From d091e66cfe4d7595fc1866c1289a5c5fa0f01719 Mon Sep 17 00:00:00 2001 From: Sachin Bansal Date: Mon, 7 Mar 2016 17:22:44 -0800 Subject: [PATCH] Use service list also as key for service chains Currently, ServiceChain class does not use service list as a key. As a result, if there are two policy rules with the same match condition, but different service lists, we will keep on deleting one service chain and creating another one. With this change, the two rules will result in two separate service chains and they should be indpendently created and deleted and should not interfere with each other. Change-Id: If4009330d32ab885fb64cfe98adf551e00662c53 Closes-Bug: 1508044 --- src/config/api-server/provision_defaults.py | 2 +- src/config/schema-transformer/config_db.py | 20 +++++++++---------- .../schema-transformer/test/test_service.py | 6 ++++++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/config/api-server/provision_defaults.py b/src/config/api-server/provision_defaults.py index 4db2f4b3bed..d7466a0465c 100644 --- a/src/config/api-server/provision_defaults.py +++ b/src/config/api-server/provision_defaults.py @@ -20,7 +20,7 @@ def __init__(self): perms = PermType('cloud-admin', PERMS_RWX, 'cloud-admin-group', PERMS_RWX, PERMS_RWX) - self.perms = IdPermsType(perms, None, True, 0, 0) + self.perms = IdPermsType(permissions=perms, enable=True) # set default perms2 of a new object # cloud-admin owner with full access, not shared with anyone diff --git a/src/config/schema-transformer/config_db.py b/src/config/schema-transformer/config_db.py index dcb7f94f1f1..1e654c56009 100644 --- a/src/config/schema-transformer/config_db.py +++ b/src/config/schema-transformer/config_db.py @@ -524,13 +524,6 @@ def add_service_chain(self, svn, dvn, proto, prule): service_chain_ris[remote_vn] = ( self.get_service_name(service_chain.name, services[0]), None) - if service_chain.service_list != services: - if service_chain.created: - service_chain.destroy() - service_chain.service_list = list(services) - service_chain.create() - else: - service_chain.service_list = list(services) if service_chain not in service_chain_list: service_chain_list.append(service_chain) @@ -762,7 +755,7 @@ def _get_routing_instance_from_route(self, next_hop): si.left_vn_str) return None sc = ServiceChain.find(si.left_vn_str, si.right_vn_str, '<>', - [PortType()], [PortType()], 'any') + [PortType()], [PortType()], 'any', [si.name]) if sc is None: self._logger.error("Service chain between %s and %s not present", si.left_vn_str, si.right_vn_str) @@ -2346,18 +2339,22 @@ def __eq__(self, other): return False if self.protocol != other.protocol: return False + if self.service_list != other.service_list: + return False return True # end __eq__ @classmethod - def find(cls, left_vn, right_vn, direction, sp_list, dp_list, protocol): + def find(cls, left_vn, right_vn, direction, sp_list, dp_list, protocol, + service_list): for sc in ServiceChain.values(): if (left_vn == sc.left_vn and right_vn == sc.right_vn and sp_list == sc.sp_list and dp_list == sc.dp_list and direction == sc.direction and - protocol == sc.protocol): + protocol == sc.protocol and + service_list == sc.service_list): return sc # end for sc return None @@ -2366,7 +2363,8 @@ def find(cls, left_vn, right_vn, direction, sp_list, dp_list, protocol): @classmethod def find_or_create(cls, left_vn, right_vn, direction, sp_list, dp_list, protocol, service_list): - sc = cls.find(left_vn, right_vn, direction, sp_list, dp_list, protocol) + sc = cls.find(left_vn, right_vn, direction, sp_list, dp_list, protocol, + service_list) if sc is not None: sc.present_stale = False return sc diff --git a/src/config/schema-transformer/test/test_service.py b/src/config/schema-transformer/test/test_service.py index 52c9e85f49a..a144a79576b 100644 --- a/src/config/schema-transformer/test/test_service.py +++ b/src/config/schema-transformer/test/test_service.py @@ -1034,7 +1034,13 @@ def test_multi_service_policy(self): np.set_network_policy_entries(np.network_policy_entries) self._vnc_lib.network_policy_update(np) + sc_old = sc for i in range(0, 5): + sc = self.wait_to_get_sc() + if sc_old == sc: + gevent.sleep(1) + continue + sc_ri_names = ['service-'+sc+'-default-domain_default-project_' + s for s in service_names] try: self.check_service_chain_pbf_rules(vn1_obj, vn2_obj, sc_ri_names[2], service_names[2], '10.0.0.250') gevent.sleep(1)