Merge "Adding support for address group feature in upstream"

This commit is contained in:
Zuul 2022-07-01 14:52:08 +00:00 committed by Gerrit Code Review
commit ebffb0af89
2 changed files with 113 additions and 1 deletions

View File

@ -32,6 +32,7 @@ from aim import utils as aim_utils
import netaddr
from neutron.agent import securitygroups_rpc
from neutron.common import utils as n_utils
from neutron.db.models import address_group as ag_db
from neutron.db.models import address_scope as as_db
from neutron.db.models import allowed_address_pair as n_addr_pair_db
from neutron.db.models import l3 as l3_db
@ -2666,6 +2667,10 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
context, port, removed_sgs, is_delete=True)
self._really_update_sg_rule_with_remote_group_set(
context, port, added_sgs, is_delete=False)
self._really_update_sg_rule_with_remote_address_group_set(
context, port, removed_sgs, is_delete=True)
self._really_update_sg_rule_with_remote_address_group_set(
context, port, added_sgs, is_delete=False)
def _really_update_sg_rule_with_remote_group_set(
self, context, port, security_groups, is_delete):
@ -2715,6 +2720,51 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
self.aim.update(aim_ctx, sg_rule_aim,
remote_ips=aim_sg_rule.remote_ips)
def _really_update_sg_rule_with_remote_address_group_set(
self, context, port, security_groups, is_delete):
if not security_groups:
return
session = context._plugin_context.session
aim_ctx = aim_context.AimContext(session)
query = BAKERY(lambda s: s.query(
sg_models.SecurityGroupRule,
ag_db.AddressGroup))
query += lambda q: q.filter(
sg_models.SecurityGroupRule.remote_address_group_id ==
ag_db.AddressGroup.id)
res = query(session).params(
security_groups=list(security_groups)).all()
sg_to_tenant = {}
for sg in res:
sg_rule = sg[0]
address_group = sg[1]
sg_id = sg_rule['security_group_id']
if sg_id in sg_to_tenant:
tenant_id = sg_to_tenant[sg_id]
else:
tenant_id = self._get_sg_rule_tenant_id(session, sg_rule)
sg_to_tenant[sg_id] = tenant_id
tenant_aname = self.name_mapper.project(session, tenant_id)
sg_rule_aim = aim_resource.SecurityGroupRule(
tenant_name=tenant_aname,
security_group_name=sg_rule['security_group_id'],
security_group_subject_name='default',
name=sg_rule['id'])
aim_sg_rule = self.aim.get(aim_ctx, sg_rule_aim)
if not aim_sg_rule:
continue
for ag_address in address_group['addresses']:
address = str(ag_address.address)
if is_delete:
if address in aim_sg_rule.remote_ips:
aim_sg_rule.remote_ips.remove(address)
else:
if address not in aim_sg_rule.remote_ips:
aim_sg_rule.remote_ips.append(address)
self.aim.update(aim_ctx, sg_rule_aim,
remote_ips=aim_sg_rule.remote_ips)
def _check_active_active_aap(self, context, port):
aap_current = port.get('allowed_address_pairs', [])
aap_original = []
@ -2962,6 +3012,8 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
self._check_valid_erspan_config(port)
self._really_update_sg_rule_with_remote_group_set(
context, port, port['security_groups'], is_delete=False)
self._really_update_sg_rule_with_remote_address_group_set(
context, port, port['security_groups'], is_delete=False)
self._insert_provisioning_block(context)
# Handle router gateway port creation.
@ -3252,6 +3304,8 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
self._delete_erspan_aim_config(context, port)
self._really_update_sg_rule_with_remote_group_set(
context, port, port['security_groups'], is_delete=True)
self._really_update_sg_rule_with_remote_address_group_set(
context, port, port['security_groups'], is_delete=True)
# Set status of floating ip DOWN.
self._update_floatingip_status(

View File

@ -40,6 +40,7 @@ from neutron.plugins.ml2 import driver_context
from neutron.plugins.ml2 import models as ml2_models
from neutron.tests.unit.api import test_extensions
from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin
from neutron.tests.unit.extensions import test_address_group
from neutron.tests.unit.extensions import test_address_scope
from neutron.tests.unit.extensions import test_l3
from neutron.tests.unit.extensions import test_securitygroup
@ -296,7 +297,8 @@ class ApicAimTestMixin(object):
class ApicAimTestCase(test_address_scope.AddressScopeTestCase,
test_l3.L3NatTestCaseMixin, ApicAimTestMixin,
test_securitygroup.SecurityGroupsTestCase):
test_securitygroup.SecurityGroupsTestCase,
test_address_group.AddressGroupTestCase):
def setUp(self, mechanism_drivers=None, tenant_network_types=None,
plugin=None, ext_mgr=None):
@ -11013,6 +11015,62 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork):
sg_rule1['id'], 'default', default_sg_id, tenant_aname)
self.assertEqual(aim_sg_rule.remote_ips, [])
def test_update_sg_rule_with_remote_address_group_set(self):
# Create network.
net_resp = self._make_network(self.fmt, 'net1', True)
net = net_resp['network']
# Create subnet
subnet = self._make_subnet(self.fmt, net_resp, '10.0.1.1',
'10.0.1.0/24')['subnet']
subnet_id = subnet['id']
fixed_ips = [{'subnet_id': subnet_id, 'ip_address': '10.0.1.100'}]
# create port with security group having rule
# with remote_address_group_id set
sg = self._make_security_group(self.fmt, 'test',
'test remote address group')
sg_id = sg['security_group']['id']
ag = self._test_create_address_group(name='foo',
addresses=['10.0.1.0/24',
'192.168.0.1/32'])
ag_id = ag['address_group']['id']
rule = self._build_security_group_rule(
sg_id, 'ingress', n_constants.PROTO_NAME_ICMP, '33', '2',
remote_address_group_id=ag_id, ethertype=n_constants.IPv4)
rules = {'security_group_rules': [rule['security_group_rule']]}
sg_rule = self._make_security_group_rule(
self.fmt, rules)['security_group_rules'][0]
port = self._make_port(self.fmt, net['id'], fixed_ips=fixed_ips,
security_groups=[sg_id])['port']
tenant_aname = self.name_mapper.project(None,
sg['security_group']['tenant_id'])
aim_sg_rule = self._get_sg_rule(
sg_rule['id'], 'default', sg_id, tenant_aname)
self.assertEqual(aim_sg_rule.remote_ips,
['10.0.1.0/24', '192.168.0.1/32'])
# delete SG group
data = {'port': {'security_groups': []}}
port = self._update('ports', port['id'], data)['port']
aim_sg_rule = self._get_sg_rule(
sg_rule['id'], 'default', sg_id, tenant_aname)
self.assertEqual(aim_sg_rule.remote_ips, [])
# add security group
data = {'port': {'security_groups': [sg_id]}}
port = self._update('ports', port['id'], data)['port']
aim_sg_rule = self._get_sg_rule(
sg_rule['id'], 'default', sg_id, tenant_aname)
self.assertEqual(aim_sg_rule.remote_ips,
['10.0.1.0/24', '192.168.0.1/32'])
# Delete port
self._delete('ports', port['id'])
aim_sg_rule = self._get_sg_rule(
sg_rule['id'], 'default', sg_id, tenant_aname)
self.assertEqual(aim_sg_rule.remote_ips, [])
def test_create_sg_rule_with_remote_group_set_different_tenant(self):
# Create network.
net_resp = self._make_network(