<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; color: rgb(0, 0, 0); font-size: 14px; font-family: Calibri, sans-serif;">
<div>Ryan,</div>
<div><br>
</div>
<div>Looks good apart from:</div>
<div><br>
</div>
<div><span style="font-family: monospace;">networking_ovn/common/extensions.py</span></div>
<div><span style="font-family: monospace;"><br>
</span></div>
<div>There should be no changes to that file, I removed them as they are from an older prototype. </div>
<div><br>
</div>
<div>Regards</div>
<div><br>
</div>
<div>John</div>
<div><br>
</div>
<span id="OLK_SRC_BODY_SECTION">
<div style="font-family:Calibri; font-size:11pt; text-align:left; color:black; BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0in; PADDING-LEFT: 0in; PADDING-RIGHT: 0in; BORDER-TOP: #b5c4df 1pt solid; BORDER-RIGHT: medium none; PADDING-TOP: 3pt">
<span style="font-weight:bold">From: </span>Ryan Moats <<a href="mailto:rmoats@us.ibm.com">rmoats@us.ibm.com</a>><br>
<span style="font-weight:bold">Date: </span>Wednesday, May 11, 2016 at 9:59 AM<br>
<span style="font-weight:bold">To: </span>John McDowall <<a href="mailto:jmcdowall@paloaltonetworks.com">jmcdowall@paloaltonetworks.com</a>><br>
<span style="font-weight:bold">Cc: </span>"<a href="mailto:discuss@openvswitch.org">discuss@openvswitch.org</a>" <<a href="mailto:discuss@openvswitch.org">discuss@openvswitch.org</a>>, OpenStack Development Mailing List <<a href="mailto:openstack-dev@lists.openstack.org">openstack-dev@lists.openstack.org</a>><br>
<span style="font-weight:bold">Subject: </span>Re: [OVN] [networking-ovn] [networking-sfc] SFC and OVN<br>
</div>
<div><br>
</div>
<div>
<div>
<p><tt>John McDowall <<a href="mailto:jmcdowall@paloaltonetworks.com">jmcdowall@paloaltonetworks.com</a>> wrote on 05/11/2016 11:30:07 AM:<br>
<br>
> From: John McDowall <<a href="mailto:jmcdowall@paloaltonetworks.com">jmcdowall@paloaltonetworks.com</a>></tt><br>
<tt>> To: Ryan Moats/Omaha/IBM@IBMUS</tt><br>
<tt>> Cc: "<a href="mailto:discuss@openvswitch.org">discuss@openvswitch.org</a>" <<a href="mailto:discuss@openvswitch.org">discuss@openvswitch.org</a>>, "OpenStack
<br>
> Development Mailing List" <<a href="mailto:openstack-dev@lists.openstack.org">openstack-dev@lists.openstack.org</a>></tt><br>
<tt>> Date: 05/11/2016 11:30 AM</tt><br>
<tt>> Subject: Re: [OVN] [networking-ovn] [networking-sfc] SFC and OVN</tt><br>
<tt>> <br>
> Ryan,</tt><br>
<tt>> <br>
> Apologies for missing the _init_.py files – removed them and <br>
> remerged. When I do a compare from my repo to main I see three files<br>
> changed (which I think is correct):</tt><br>
<tt>> <br>
> networking_ovn/ovsdb/commands.py</tt><br>
<tt>> networking_ovn/ovsdb/impl_idl_ovn.py</tt><br>
<tt>> networking_ovn/ovsdb/ovn_api.py</tt><br>
<tt>> <br>
> I could be doing something wrong as not an expert at merging repos. <br>
> If I am doing something wrong let me know and I will fix it.</tt><br>
<tt>> <br>
> Regards</tt><br>
<tt>> <br>
> John</tt><br>
<br>
<tt>So the change I made to common/extensions.py was to avoid a merge</tt><br>
<tt>conflict, and I double checked and yes, the changes I had to</tt><br>
<tt>plugin.py are spurious, so here is an updated/corrected patch for</tt><br>
<tt>you to check against:</tt><br>
<br>
<tt>From eb93dc3984145f1b82be15d204c2f0790c1429bd Mon Sep 17 00:00:00 2001<br>
From: RYAN D. MOATS <<a href="mailto:rmoats@us.ibm.com">rmoats@us.ibm.com</a>><br>
Date: Wed, 11 May 2016 09:10:18 -0500<br>
Subject: [PATCH] test</tt><br>
<br>
<tt>Signed-off-by: RYAN D. MOATS <<a href="mailto:rmoats@us.ibm.com">rmoats@us.ibm.com</a>><br>
---<br>
networking_ovn/common/extensions.py | 1 +<br>
networking_ovn/ovsdb/commands.py | 78 ++++++++++++++++++++++++++++++++++<br>
networking_ovn/ovsdb/impl_idl_ovn.py | 18 ++++++++<br>
networking_ovn/ovsdb/ovn_api.py | 49 +++++++++++++++++++++<br>
4 files changed, 146 insertions(+), 0 deletions(-)</tt><br>
<br>
<tt>diff --git a/networking_ovn/common/extensions.py b/networking_ovn/common/extensions.py<br>
index c171e11..55fc147 100644<br>
--- a/networking_ovn/common/extensions.py<br>
+++ b/networking_ovn/common/extensions.py<br>
@@ -37,4 +37,5 @@ SUPPORTED_API_EXTENSIONS = [<br>
'subnet_allocation',<br>
'port-security',<br>
'allowed-address-pairs',<br>
+ 'sfi',<br>
]<br>
diff --git a/networking_ovn/ovsdb/commands.py b/networking_ovn/ovsdb/commands.py<br>
index 7ea7a6f..68a747f 100644<br>
--- a/networking_ovn/ovsdb/commands.py<br>
+++ b/networking_ovn/ovsdb/commands.py<br>
@@ -164,6 +164,84 @@ class DelLogicalPortCommand(BaseCommand):<br>
setattr(lswitch, 'ports', ports)<br>
self.api._tables['Logical_Port'].rows[lport.uuid].delete()<br>
<br>
+class AddLogicalServiceCommand(BaseCommand):<br>
+ def __init__(self, api, lservice, lswitch, may_exist, **columns):<br>
+ super(AddLogicalServiceCommand, self).__init__(api)<br>
+ self.lservice = lservice<br>
+ self.lswitch = lswitch<br>
+ self.may_exist = may_exist<br>
+ self.columns = columns<br>
+<br>
+ def run_idl(self, txn):</tt><br>
<tt>+ try:<br>
+ lswitch = idlutils.row_by_value(self.api.idl, 'Logical_Switch',<br>
+ 'name', self.lswitch)<br>
+ services= getattr(lswitch, 'services', [])<br>
+ except idlutils.RowNotFound:<br>
+ msg = _("Logical Switch %s does not exist") % self.lswitch<br>
+ raise RuntimeError(msg)<br>
+ if self.may_exist:<br>
+ service = idlutils.row_by_value(self.api.idl,<br>
+ 'Logical_Service', 'name',<br>
+ self.lservice, None)<br>
+ if service:<br>
+ return<br>
+<br>
+ lswitch.verify('services')<br>
+<br>
+ service = txn.insert(self.api._tables['Logical_Service'])<br>
+ service.name = self.lservice<br>
+ for col, val in self.columns.items():<br>
+ setattr(service, col, val)<br>
+ # add the newly created service to existing lswitch<br>
+ services.append(service.uuid)<br>
+ setattr(lswitch, 'services', services)<br>
+<br>
+class SetLogicalServiceCommand(BaseCommand):</tt><br>
<tt>+ def __init__(self, api, lservice, if_exists, **columns):<br>
+ super(SetLogicalServiceCommand, self).__init__(api)<br>
+ self.lservice = lservice<br>
+ self.columns = columns<br>
+ self.if_exists = if_exists<br>
+<br>
+ def run_idl(self, txn):<br>
+ try:<br>
+ service = idlutils.row_by_value(self.api.idl, 'Logical_Service',<br>
+ 'name', self.lservice)<br>
+ except idlutils.RowNotFound:<br>
+ if self.if_exists:<br>
+ return<br>
+ msg = _("Logical Service %s does not exist") % self.lservice<br>
+ raise RuntimeError(msg)<br>
+<br>
+ for col, val in self.columns.items():<br>
+ setattr(service, col, val)<br>
+<br>
+class DelLogicalServiceCommand(BaseCommand):<br>
+ def __init__(self, api, lservice, lswitch, if_exists):<br>
+ super(DelLogicalServiceCommand, self).__init__(api)<br>
+ self.lservice = lservice<br>
+ self.lswitch = lswitch<br>
+ self.if_exists = if_exists<br>
+<br>
+ def run_idl(self, txn):<br>
+ try:</tt><br>
<tt>+ lservice = idlutils.row_by_value(self.api.idl, 'Logical_Service',<br>
+ 'name', self.lservice)<br>
+ lswitch = idlutils.row_by_value(self.api.idl, 'Logical_Switch',<br>
+ 'name', self.lswitch)<br>
+ services = getattr(lswitch, 'services', [])<br>
+ except idlutils.RowNotFound:<br>
+ if self.if_exists:<br>
+ return<br>
+ msg = _("Service %s does not exist") % self.lservice<br>
+ raise RuntimeError(msg)<br>
+<br>
+ lswitch.verify('services')<br>
+<br>
+ services.remove(lservice)<br>
+ setattr(lswitch, 'services', services)<br>
+ self.api._tables['Logical_Service'].rows[lservice.uuid].delete()<br>
<br>
class AddLRouterCommand(BaseCommand):<br>
def __init__(self, api, name, may_exist, **columns):<br>
diff --git a/networking_ovn/ovsdb/impl_idl_ovn.py b/networking_ovn/ovsdb/impl_idl_ovn.py<br>
index c3411f0..38623ac 100644<br>
--- a/networking_ovn/ovsdb/impl_idl_ovn.py<br>
+++ b/networking_ovn/ovsdb/impl_idl_ovn.py</tt><br>
<tt>@@ -77,6 +77,24 @@ class OvsdbOvnIdl(ovn_api.API):<br>
ext_id[0], ext_id[1],<br>
if_exists)<br>
<br>
+ def create_lservice(self, lservice_name, lswitch_name, may_exist=True,<br>
+ **columns):<br>
+ return cmd.AddLogicalServiceCommand(self, lservice_name, lswitch_name,<br>
+ may_exist, **columns)<br>
+<br>
+ def set_lservice(self, lservice_name, if_exists=True, **columns):<br>
+ return cmd.SetLogicalServiceCommand(self, lservice_name,<br>
+ if_exists, **columns)<br>
+<br>
+ def delete_lservice(self, lservice_name=None, lswitch=None,<br>
+ ext_id=None, if_exists=True):<br>
+ if lservice_name is not None:<br>
+ return cmd.DelLogicalServiceCommand(self, lservice_name,<br>
+ lswitch, if_exists)<br>
+ else:<br>
+ raise RuntimeError(_("Currently only supports "<br>
+ "delete by lservice-name"))</tt><br>
<tt>+<br>
def create_lport(self, lport_name, lswitch_name, may_exist=True,<br>
**columns):<br>
return cmd.AddLogicalPortCommand(self, lport_name, lswitch_name,<br>
diff --git a/networking_ovn/ovsdb/ovn_api.py b/networking_ovn/ovsdb/ovn_api.py<br>
index feca916..067488c 100644<br>
--- a/networking_ovn/ovsdb/ovn_api.py<br>
+++ b/networking_ovn/ovsdb/ovn_api.py<br>
@@ -69,6 +69,55 @@ class API(object):<br>
:returns: :class:`Command` with no result<br>
"""<br>
<br>
+<br>
+<br>
+<br>
+ @abc.abstractmethod<br>
+ def create_lservice(self, name, lswitch_name, may_exist=True, **columns):<br>
+ """Create a command to add an OVN lservice<br>
+<br>
+ :param name: The name of the lservice<br>
+ :type name: string<br>
+ :param lswitch_name: The name of the lswitch the lservice is created on<br>
+ :type lswitch_name: string<br>
+ :param may_exist: Do not fail if lservice already exists<br>
+ :type may_exist: bool<br>
+ :param columns: Dictionary of service columns<br>
+ Supported columns: app_port, in_port, out_port</tt><br>
<tt>+ :type columns: dictionary<br>
+ :returns: :class:`Command` with no result<br>
+ """<br>
+<br>
+ @abc.abstractmethod<br>
+ def set_lservice(self, lservice_name, if_exists=True, **columns):<br>
+ """Create a command to set OVN lservice fields<br>
+<br>
+ :param lservice_name: The name of the lservice<br>
+ :type lservice_name: string<br>
+ :param columns: Dictionary of service columns<br>
+ Supported columns: app_port, in_port, out_port<br>
+ :param if_exists: Do not fail if lservice does not exist<br>
+ :type if_exists: bool<br>
+ :type columns: dictionary<br>
+ :returns: :class:`Command` with no result<br>
+ """<br>
+<br>
+ @abc.abstractmethod<br>
+ def delete_lservice(self, name=None, lswitch=None, ext_id=None,<br>
+ if_exists=True):<br>
+ """Create a command to delete an OVN lservice<br>
+<br>
+ :param name: The name of the lservice<br>
+ :type name: string<br>
+ :param lswitch: The name of the lswitch</tt><br>
<tt>+ :type lswitch: string<br>
+ :param ext_id: The external id of the lservice<br>
+ :type ext_id: pair of <ext_id_key ,ext_id_value><br>
+ :param if_exists: Do not fail if the lservice does not exists<br>
+ :type if_exists: bool<br>
+ :returns: :class:`Command` with no result<br>
+ """<br>
+<br>
@abc.abstractmethod<br>
def create_lport(self, name, lswitch_name, may_exist=True, **columns):<br>
"""Create a command to add an OVN lport<br>
-- <br>
1.7.1</tt><br>
<br>
<br>
<br>
</p>
</div>
</div>
</span>
</body>
</html>