From 5f5ae464d8b57a9f29618ab1047245cbcd170e5b 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 (cherry picked from commit d091e66cfe4d7595fc1866c1289a5c5fa0f01719) --- 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 703634dcdc4..cd544aaa164 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) @@ -2342,18 +2335,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 @@ -2362,7 +2359,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 ceed22b4a4f..c636a5c182e 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)