diff --git a/src/config/svc-monitor/svc_monitor/config_db.py b/src/config/svc-monitor/svc_monitor/config_db.py index f7797546507..b53d9478208 100644 --- a/src/config/svc-monitor/svc_monitor/config_db.py +++ b/src/config/svc-monitor/svc_monitor/config_db.py @@ -401,8 +401,8 @@ def __init__(self, uuid, obj_dict=None): self.logical_interface = None self.instance_ips = set() self.floating_ips = set() - self.interface_route_table = None - self.service_health_check = None + self.interface_route_tables = set() + self.service_health_checks = set() self.security_groups = set() self.service_instance = None self.instance_id = None @@ -432,8 +432,8 @@ def update(self, obj=None): self.update_single_ref('virtual_network', obj) self.update_single_ref('virtual_machine', obj) self.update_single_ref('logical_interface', obj) - self.update_single_ref('interface_route_table', obj) - self.update_single_ref('service_health_check', obj) + self.update_multiple_refs('interface_route_table', obj) + self.update_multiple_refs('service_health_check', obj) self.update_single_ref('physical_interface',obj) self.update_multiple_refs('security_group', obj) self.update_single_ref('port_tuple', obj) @@ -457,8 +457,8 @@ def delete(cls, uuid): obj.update_single_ref('virtual_network', {}) obj.update_single_ref('virtual_machine', {}) obj.update_single_ref('logical_interface', {}) - obj.update_single_ref('interface_route_table', {}) - obj.update_single_ref('service_health_check', {}) + obj.update_multiple_refs('interface_route_table', {}) + obj.update_multiple_refs('service_health_check', {}) obj.update_multiple_refs('security_group', {}) obj.update_single_ref('port_tuple', {}) obj.remove_from_parent() @@ -540,10 +540,6 @@ def update(self, obj=None): return obj # end update - def evaluate(self): - self.state = 'launch' - self._manager.create_service_instance(self) - def check_vn_changes(self, obj): self.vn_changed = False if not self.params or not obj.get('service_instance_properties'): @@ -581,6 +577,14 @@ def delete(cls, uuid): obj.remove_from_parent() del cls._dict[uuid] # end delete + + def evaluate(self): + self.state = 'launch' + self._manager.create_service_instance(self) + + for pt_id in self.port_tuples: + self._manager.port_tuple_agent.update_port_tuple(pt_id=pt_id) + # end class ServiceInstanceSM @@ -963,6 +967,8 @@ def __init__(self, uuid, obj_dict=None): self.virtual_machine_interfaces = set() self.service_instance = None self.service_interface_tag = None + self.si_uuid = None + self.if_type = None self.update(obj_dict) # end __init__ @@ -976,6 +982,10 @@ def update(self, obj=None): ref_attr = self.get_single_ref_attr('service_instance', obj) if ref_attr: self.service_interface_tag = ref_attr['interface_type'] + name_split = self.name.split(' ') + if len(name_split) == 2: + self.si_uuid = name_split[0] + self.if_type = name_split[1] # end update @classmethod @@ -989,8 +999,9 @@ def delete(cls, uuid): # end delete def evaluate(self): - if not len(self.virtual_machine_interfaces): + if self.si_uuid and not len(self.virtual_machine_interfaces): self._manager.delete_interface_route_table(self.uuid) + # end InterfaceRouteTableSM @@ -1158,6 +1169,9 @@ def delete(cls, uuid): obj.remove_from_parent() del cls._dict[uuid] # end delete + + def evaluate(self): + self._manager.port_tuple_agent.update_port_tuple(pt_id=self.uuid) # end PortTupleSM class ServiceHealthCheckSM(DBBaseSM): @@ -1166,6 +1180,7 @@ class ServiceHealthCheckSM(DBBaseSM): def __init__(self, uuid, obj_dict=None): self.uuid = uuid + self.virtual_machine_interfaces = set() self.service_instance = None self.service_interface_tag = None self.update(obj_dict) @@ -1176,6 +1191,7 @@ def update(self, obj=None): obj = self.read_obj(self.uuid) self.parent_uuid = obj['parent_uuid'] self.name = obj['fq_name'][-1] + self.update_multiple_refs('virtual_machine_interface', obj) self.update_single_ref('service_instance', obj) ref_attr = self.get_single_ref_attr('service_instance', obj) if ref_attr: @@ -1188,6 +1204,7 @@ def delete(cls, uuid): return obj = cls._dict[uuid] obj.update_single_ref('service_instance', {}) + obj.update_multiple_refs('virtual_machine_interface', {}) del cls._dict[uuid] # end delete # end ServiceHealthCheckSM diff --git a/src/config/svc-monitor/svc_monitor/port_tuple.py b/src/config/svc-monitor/svc_monitor/port_tuple.py index e185111de7e..46e108f342f 100644 --- a/src/config/svc-monitor/svc_monitor/port_tuple.py +++ b/src/config/svc-monitor/svc_monitor/port_tuple.py @@ -80,15 +80,35 @@ def _allocate_shared_iip(self, si, port, vmi, vmi_obj): return def set_port_service_health_check(self, port, vmi): - if port['service-health-check'] and not vmi.service_health_check: + # handle add + for health_id in port['service-health-checks']: + if health_id in vmi.service_health_checks: + continue + self._vnc_lib.ref_update('virtual-machine-interface', vmi.uuid, + 'service-health-check', health_id, None, 'ADD') + vmi.update() + # handle deletes + for health_id in vmi.service_health_checks: + if health_id in port['service-health-checks']: + continue self._vnc_lib.ref_update('virtual-machine-interface', vmi.uuid, - 'service-health-check', port['service-health-check'], None, 'ADD') + 'service-health-check', health_id, None, 'DELETE') vmi.update() def set_port_static_routes(self, port, vmi): - if port['interface-route-table'] and not vmi.interface_route_table: + # handle add + for irt_id in port['interface-route-tables']: + if irt_id in vmi.interface_route_tables: + continue + self._vnc_lib.ref_update('virtual-machine-interface', vmi.uuid, + 'interface-route-table', irt_id, None, 'ADD') + vmi.update() + # handle deletes + for irt_id in vmi.interface_route_tables: + if irt_id in port['interface-route-tables']: + continue self._vnc_lib.ref_update('virtual-machine-interface', vmi.uuid, - 'interface-route-table', port['interface-route-table'], None, 'ADD') + 'interface-route-table', irt_id, None, 'DELETE') vmi.update() def set_secondary_ip_tracking_ip(self, vmi): @@ -96,19 +116,30 @@ def set_secondary_ip_tracking_ip(self, vmi): iip = InstanceIpSM.get(iip_id) if not iip or not iip.instance_ip_secondary: continue - if iip.secondary_tracking_ip == vmi.aaps[0]['ip']: - continue - iip_obj = self._vnc_lib.instance_ip_read(id=iip.uuid) - iip_obj.set_secondary_ip_tracking_ip(vmi.aaps[0]['ip']) - self._vnc_lib.instance_ip_update(iip_obj) - iip.update(iip_obj.serialize_to_json()) + if vmi.aaps and len(vmi.aaps): + if iip.secondary_tracking_ip != vmi.aaps[0]['ip']: + iip_obj = self._vnc_lib.instance_ip_read(id=iip.uuid) + iip_obj.set_secondary_ip_tracking_ip(vmi.aaps[0]['ip']) + self._vnc_lib.instance_ip_update(iip_obj) + iip.update(iip_obj.serialize_to_json()) + else: + if iip.secondary_tracking_ip: + iip_obj = self._vnc_lib.instance_ip_read(id=iip.uuid) + iip_obj.set_secondary_ip_tracking_ip(None) + self._vnc_lib.instance_ip_update(iip_obj) + iip.update(iip_obj.serialize_to_json()) def set_port_allowed_address_pairs(self, port, vmi, vmi_obj): - if not port['allowed-address-pairs']: + if not port['allowed-address-pairs'] or \ + not port['allowed-address-pairs'].get('allowed_address_pair', None): + if vmi.aaps and len(vmi.aaps): + vmi_obj.set_virtual_machine_interface_allowed_address_pairs(AllowedAddressPairs()) + self._vnc_lib.virtual_machine_interface_update(vmi_obj) + vmi.update() + self.set_secondary_ip_tracking_ip(vmi) return + aaps = port['allowed-address-pairs'].get('allowed_address_pair', None) - if not aaps: - return update_aap = False if len(aaps) != len(vmi.aaps or []): update_aap = True @@ -148,17 +179,19 @@ def delete_old_vmi_links(self, vmi): 'virtual-machine-interface', vmi.uuid, None, 'DELETE') vmi.instance_ips.remove(iip_id) - irt = InterfaceRouteTableSM.get(vmi.interface_route_table) - if irt and irt.service_instance: - self._vnc_lib.ref_update('virtual-machine-interface', vmi.uuid, - 'interface-route-table', irt.uuid, None, 'DELETE') - vmi.interface_route_table = None + for irt_id in vmi.interface_route_tables: + irt = InterfaceRouteTableSM.get(irt_id) + if irt and irt.service_instance: + self._vnc_lib.ref_update('virtual-machine-interface', vmi.uuid, + 'interface-route-table', irt.uuid, None, 'DELETE') + vmi.interface_route_tables.remove(irt_id) - health = ServiceHealthCheckSM.get(vmi.service_health_check) - if health and health.service_instance: - self._vnc_lib.ref_update('virtual-machine-interface', vmi.uuid, - 'service-health-check', health.uuid, None, 'DELETE') - vmi.service_health_check = None + for health_id in vmi.service_health_checks: + health = ServiceHealthCheckSM.get(health_id) + if health and health.service_instance: + self._vnc_lib.ref_update('virtual-machine-interface', vmi.uuid, + 'service-health-check', health.uuid, None, 'DELETE') + vmi.service_health_checks.remove(health_id) def set_port_service_chain_ip(self, si, port, vmi, vmi_obj): self._allocate_shared_iip(si, port, vmi, vmi_obj) @@ -180,18 +213,16 @@ def get_port_config(self, st, si): port['shared-ip'] = st_if.get('shared_ip') port['static-route-enable'] = st_if.get('static_route_enable') port['allowed-address-pairs'] = si_if.get('allowed_address_pairs') - port['interface-route-table'] = None + port['interface-route-tables'] = [] for irt_id in si.interface_route_tables: irt = InterfaceRouteTableSM.get(irt_id) if irt and irt.service_interface_tag == port['type']: - port['interface-route-table'] = irt.uuid - break - port['service-health-check'] = None + port['interface-route-tables'].append(irt.uuid) + port['service-health-checks'] = [] for health_id in si.service_health_checks: health = ServiceHealthCheckSM.get(health_id) if health and health.service_interface_tag == port['type']: - port['service-health-check'] = health.uuid - break + port['service-health-checks'].append(health.uuid) port_config[st_if.get('service_interface_type')] = port return port_config @@ -214,7 +245,7 @@ def update_port_tuple(self, vmi=None, pt_id=None): if not port_config: return - for vmi_id in pt.virtual_machine_interfaces: + for vmi_id in list(pt.virtual_machine_interfaces): vmi = VirtualMachineInterfaceSM.get(vmi_id) if not vmi: continue diff --git a/src/config/svc-monitor/svc_monitor/reaction_map.py b/src/config/svc-monitor/svc_monitor/reaction_map.py index 1cdbb722410..39ad5d55685 100644 --- a/src/config/svc-monitor/svc_monitor/reaction_map.py +++ b/src/config/svc-monitor/svc_monitor/reaction_map.py @@ -41,7 +41,9 @@ 'loadbalancer_pool': [], 'virtual_machine': [], 'port_tuple': [], - 'virtual_machine_interface' : [] + 'virtual_machine_interface' : [], + 'service_health_check': [], + 'interface_route_table': [], }, "instance_ip": { 'self': [], @@ -81,20 +83,29 @@ 'self': ['virtual_machine_interface'], 'service_instance': [], 'virtual_machine_interface': [], + 'service_health_check': [], + 'interface_route_table': [], }, "virtual_machine_interface": { 'self': ['interface_route_table', 'virtual_machine', 'port_tuple', 'security_group', - 'instance_ip'], + 'instance_ip', 'service_health_check'], 'interface_route_table': [], + 'service_health_check': [], 'security_group': [], 'virtual_machine': [], 'port_tuple': ['physical_interface', 'instance_ip'], 'physical_interface': ['service_instance'] }, "interface_route_table": { - 'self': [], + 'self': ['service_instance'], 'virtual_machine_interface': [], + 'service_instance': [], + }, + "service_health_check": { + 'self': ['service_instance'], + 'virtual_machine_interface': [], + 'service_instance': [], }, "project": { 'self': [], diff --git a/src/config/svc-monitor/svc_monitor/tests/test_config_db.py b/src/config/svc-monitor/svc_monitor/tests/test_config_db.py index a8f73f4edcb..fa4c1040ae7 100644 --- a/src/config/svc-monitor/svc_monitor/tests/test_config_db.py +++ b/src/config/svc-monitor/svc_monitor/tests/test_config_db.py @@ -430,7 +430,7 @@ def test_add_delete_interface_route_table(self): self.assertIsNotNone(vmi) self.assertIsNotNone(irt) self.assertEqual(len(irt.virtual_machine_interfaces), 1) - self.assertEqual(vmi.interface_route_table, 'irt') + self.assertEqual(vmi.interface_route_tables, set(['irt'])) config_db.InterfaceRouteTableSM.delete('irt') config_db.VirtualMachineInterfaceSM.delete('vmi') diff --git a/src/config/svc-monitor/svc_monitor/tests/test_svc_monitor.py b/src/config/svc-monitor/svc_monitor/tests/test_svc_monitor.py index 53ae6215275..b37d4110d07 100644 --- a/src/config/svc-monitor/svc_monitor/tests/test_svc_monitor.py +++ b/src/config/svc-monitor/svc_monitor/tests/test_svc_monitor.py @@ -1034,7 +1034,7 @@ def test_svc_monitor_vmi_del(self): project = self.add_project('fake-project', 'fake-project') net_obj = self.add_vn('left-vn', 'left-vn', project) vmi_obj = self.add_vmi('left-vmi', 'left-vmi', project, net_obj) - irt_obj = self.add_irt('fake-irt', 'fake-irt') + irt_obj = self.add_irt('fake-si-uuid left', 'fake-irt') vmi = config_db.VirtualMachineInterfaceSM.get('left-vmi') vmi.interface_route_table = 'fake-irt'