diff --git a/gbpservice/neutron/db/grouppolicy/group_policy_mapping_db.py b/gbpservice/neutron/db/grouppolicy/group_policy_mapping_db.py index c1f707d96e..a215cdb613 100644 --- a/gbpservice/neutron/db/grouppolicy/group_policy_mapping_db.py +++ b/gbpservice/neutron/db/grouppolicy/group_policy_mapping_db.py @@ -214,6 +214,11 @@ def _set_db_np_subnet(self, context, nat_pool, subnet_id): db_np.subnet_id = nat_pool['subnet_id'] context.session.merge(db_np) + def _get_ptgs_for_subnet(self, context, subnet_id): + return [x['policy_target_group_id'] for x in + context.session.query(PTGToSubnetAssociation).filter_by( + subnet_id=subnet_id)] + @log.log def create_policy_target(self, context, policy_target): pt = policy_target['policy_target'] diff --git a/gbpservice/neutron/services/grouppolicy/drivers/cisco/apic/apic_mapping.py b/gbpservice/neutron/services/grouppolicy/drivers/cisco/apic/apic_mapping.py index def5376b8e..44c88ef866 100644 --- a/gbpservice/neutron/services/grouppolicy/drivers/cisco/apic/apic_mapping.py +++ b/gbpservice/neutron/services/grouppolicy/drivers/cisco/apic/apic_mapping.py @@ -150,6 +150,7 @@ def initialize(self): self._setup_rpc() self.apic_manager = ApicMappingDriver.get_apic_manager() self.name_mapper = self.apic_manager.apic_mapper + self.enable_dhcp_opt = self.apic_manager.enable_optimized_dhcp self._gbp_plugin = None def _setup_rpc_listeners(self): @@ -211,6 +212,7 @@ def is_port_promiscuous(port): 'app_profile_name': str( self.apic_manager.app_profile_name), 'l2_policy_id': l2_policy_id, + 'l3_policy_id': l2p['l3_policy_id'], 'tenant_id': port['tenant_id'], 'host': port[portbindings.HOST_ID], 'ptg_tenant': self.apic_manager.apic.fvTenant.name( @@ -224,6 +226,7 @@ def is_port_promiscuous(port): l3_policy = context._plugin.get_l3_policy(context, l2p['l3_policy_id']) self._add_ip_mapping_details(context, port_id, l3_policy, details) + self._add_network_details(context, port, details) return details def _add_ip_mapping_details(self, context, port_id, l3_policy, details): @@ -255,6 +258,12 @@ def _add_ip_mapping_details(self, context, port_id, l3_policy, details): details['floating_ip'] = fips details['ip_mapping'] = ipms + def _add_network_details(self, context, port, details): + details['allowed_address_pairs'] = port['allowed_address_pairs'] + details['enable_dhcp_optimization'] = self.enable_dhcp_opt + details['subnets'] = self._get_subnets(context, + filters={'id': [ip['subnet_id'] for ip in port['fixed_ips']]}) + def process_port_added(self, plugin_context, port): pass @@ -806,6 +815,14 @@ def process_subnet_changed(self, context, old, new): if l2p: # Is GBP owned, reflect on APIC self._manage_l2p_subnets(context, l2p['id'], [new], [old]) + # notify ports in the subnet + ptg_ids = self.gbp_plugin._get_ptgs_for_subnet(context, old['id']) + pts = self.gbp_plugin.get_policy_targets( + context, filters={'policy_target_group_id': ptg_ids}) + # REVISIT(amit): We may notify more ports than those that are + # really affected. Consider checking the port's subnet as well. + for pt in pts: + self._notify_port_update(context, pt['port_id']) def process_subnet_added(self, context, subnet): l2p = self._network_id_to_l2p(context, subnet['network_id']) diff --git a/gbpservice/neutron/tests/unit/services/grouppolicy/test_apic_mapping.py b/gbpservice/neutron/tests/unit/services/grouppolicy/test_apic_mapping.py index 5e9510447b..e949a8c50e 100644 --- a/gbpservice/neutron/tests/unit/services/grouppolicy/test_apic_mapping.py +++ b/gbpservice/neutron/tests/unit/services/grouppolicy/test_apic_mapping.py @@ -243,6 +243,9 @@ def test_get_gbp_details(self): self.assertEqual(pt1['port_id'], mapping['port_id']) self.assertEqual(ptg['id'], mapping['endpoint_group_name']) self.assertEqual('someid', mapping['vm-name']) + self.assertTrue(mapping['enable_dhcp_optimization']) + self.assertEqual(1, len(mapping['subnets'])) + self.assertEqual(ptg['subnets'][0], mapping['subnets'][0]['id']) def test_get_gbp_details_shadow(self): l2p = self.create_l2_policy()['l2_policy'] @@ -294,6 +297,22 @@ def test_update_ptg_failed(self): expected_res_status=400) self.assertEqual('InvalidPortForPTG', res['NeutronError']['type']) + def test_port_notified_on_subnet_change(self): + ptg = self.create_policy_target_group()['policy_target_group'] + pt = self.create_policy_target( + policy_target_group_id=ptg['id'])['policy_target'] + self._bind_port_to_host(pt['port_id'], 'h1') + + subnet = self._get_object('subnets', ptg['subnets'][0], self.api) + subnet2 = copy.deepcopy(subnet) + subnet2['subnet']['gateway_ip'] = '10.0.0.254' + + self.driver.apic_manager.reset_mock() + self.driver.notifier.port_update.reset_mock() + self.driver.process_subnet_changed(context.get_admin_context(), + subnet['subnet'], subnet2['subnet']) + self.assertTrue(self.driver.notifier.port_update.called) + class TestPolicyTargetGroup(ApicMappingTestCase):