def test_add_acl_dhcp(self): ovn_dhcp_acls = ovn_acl.add_acl_dhcp(self.fake_port, self.fake_subnet) other_dhcp_acls = ovn_acl.add_acl_dhcp(self.fake_port, self.fake_subnet, ovn_dhcp=False) expected_match_to_lport = ( 'outport == "%s" && ip4 && ip4.src == %s && udp && udp.src == 67 ' '&& udp.dst == 68') % (self.fake_port['id'], self.fake_subnet['cidr']) acl_to_lport = { 'action': 'allow', 'direction': 'to-lport', 'external_ids': { 'neutron:lport': 'fake_port_id1' }, 'log': False, 'name': [], 'severity': [], 'lport': 'fake_port_id1', 'lswitch': 'neutron-network_id1', 'match': expected_match_to_lport, 'priority': 1002 } expected_match_from_lport = ('inport == "%s" && ip4 && ' 'ip4.dst == {255.255.255.255, %s} && ' 'udp && udp.src == 68 && udp.dst == 67' ) % (self.fake_port['id'], self.fake_subnet['cidr']) acl_from_lport = { 'action': 'allow', 'direction': 'from-lport', 'external_ids': { 'neutron:lport': 'fake_port_id1' }, 'log': False, 'name': [], 'severity': [], 'lport': 'fake_port_id1', 'lswitch': 'neutron-network_id1', 'match': expected_match_from_lport, 'priority': 1002 } self.assertEqual(1, len(ovn_dhcp_acls)) self.assertEqual(acl_from_lport, ovn_dhcp_acls[0]) self.assertEqual(2, len(other_dhcp_acls)) for acl in other_dhcp_acls: if 'to-lport' in acl.values(): self.assertEqual(acl_to_lport, acl) if 'from-lport' in acl.values(): self.assertEqual(acl_from_lport, acl)
def test_add_acls_with_sec_group(self): expected_acls = [] expected_acls += ovn_acl.drop_all_ip_traffic_for_port( self.fake_port_sg) expected_acls += ovn_acl.add_acl_dhcp( self.fake_port_sg, self.fake_subnet) sg_rule_acl = ovn_acl.add_sg_rule_acl_for_port( self.fake_port_sg, self.fake_sg_rule, 'outport == "' + self.fake_port_sg['id'] + '" ' + '&& ip4 && ip4.src == 0.0.0.0/0 ' + '&& tcp && tcp.dst == 22') expected_acls.append(sg_rule_acl) # Test with caches acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), self.fake_port_sg, self.sg_cache, self.sg_ports_cache, self.subnet_cache) self.assertEqual(expected_acls, acls) # Test without caches with mock.patch('neutron.db.db_base_plugin_v2.' 'NeutronDbPluginV2.get_subnet', return_value=self.fake_subnet), \ mock.patch('neutron.db.securitygroups_db.' 'SecurityGroupDbMixin.get_security_group', return_value=self.fake_sg): acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), self.fake_port_sg, {}, {}, {}) self.assertEqual(expected_acls, acls)
def test_add_acl_dhcp(self): acls = ovn_acl.add_acl_dhcp(self.fake_port, self.fake_subnet) expected_match_to_lport = ( 'outport == "%s" && ip4 && ip4.src == %s && udp && udp.src == 67 ' '&& udp.dst == 68') % (self.fake_port['id'], self.fake_subnet['cidr']) acl_to_lport = {'action': 'allow', 'direction': 'to-lport', 'external_ids': {'neutron:lport': 'fake_port_id1'}, 'log': False, 'lport': 'fake_port_id1', 'lswitch': 'neutron-network_id1', 'match': expected_match_to_lport, 'priority': 1002} expected_match_from_lport = ( 'inport == "%s" && ip4 && ' '(ip4.dst == 255.255.255.255 || ip4.dst == %s) && ' 'udp && udp.src == 68 && udp.dst == 67' ) % (self.fake_port['id'], self.fake_subnet['cidr']) acl_from_lport = {'action': 'allow', 'direction': 'from-lport', 'external_ids': {'neutron:lport': 'fake_port_id1'}, 'log': False, 'lport': 'fake_port_id1', 'lswitch': 'neutron-network_id1', 'match': expected_match_from_lport, 'priority': 1002} for acl in acls: if 'to-lport' in acl.values(): self.assertEqual(acl_to_lport, acl) if 'from-lport' in acl.values(): self.assertEqual(acl_from_lport, acl)
def test_add_acl_dhcp(self): self.plugin._ovn.add_acl = mock.Mock() with mock.patch.object(self.plugin, 'get_subnet', return_value=self.fake_subnet): subnet = acl_utils._get_subnet_from_cache( self.plugin, self.context, {}, 'subnet_id') acls = acl_utils.add_acl_dhcp(self.fake_port, subnet) expected_match_to_lport = ( 'outport == "%s" && ip4 && ip4.src == %s && udp && udp.src == 67 ' '&& udp.dst == 68') % (self.fake_port['id'], self.fake_subnet['cidr']) acl_to_lport = {'action': 'allow', 'direction': 'to-lport', 'external_ids': {'neutron:lport': 'fake_port_id1'}, 'log': False, 'lport': 'fake_port_id1', 'lswitch': 'neutron-network_id1', 'match': expected_match_to_lport, 'priority': 1002} expected_match_from_lport = ( 'inport == "%s" && ip4 && ' '(ip4.dst == 255.255.255.255 || ip4.dst == %s) && ' 'udp && udp.src == 68 && udp.dst == 67' ) % (self.fake_port['id'], self.fake_subnet['cidr']) acl_from_lport = {'action': 'allow', 'direction': 'from-lport', 'external_ids': {'neutron:lport': 'fake_port_id1'}, 'log': False, 'lport': 'fake_port_id1', 'lswitch': 'neutron-network_id1', 'match': expected_match_from_lport, 'priority': 1002} for acl in acls: if 'to-lport' in acl.values(): self.assertEqual(acl_to_lport, acl) if 'from-lport' in acl.values(): self.assertEqual(acl_from_lport, acl)
def _add_acls(self, admin_context, port, sg_cache, sg_ports_cache, subnet_cache): acl_list = [] sec_groups = port.get('security_groups', []) if not sec_groups: return acl_list # Drop all IP traffic to and from the logical port by default. acl_list += ovn_acl.drop_all_ip_traffic_for_port(port) for ip in port['fixed_ips']: subnet = ovn_acl._get_subnet_from_cache(self._plugin, admin_context, subnet_cache, ip['subnet_id']) if subnet['ip_version'] != 4: continue acl_list += ovn_acl.add_acl_dhcp(port, subnet) # We create an ACL entry for each rule on each security group applied # to this port. for sg_id in sec_groups: sg = ovn_acl._get_sg_from_cache(self._plugin, admin_context, sg_cache, sg_id) for r in sg['security_group_rules']: acl = self._add_sg_rule_acl_for_port(admin_context, port, r, sg_ports_cache, subnet_cache) if acl and acl not in acl_list: acl_list.append(acl) return acl_list
def _test_add_acls_with_sec_group_helper(self, native_dhcp=True): fake_port_sg = fakes.FakePort.create_one_port( attrs={ 'security_groups': [self.fake_sg['id']], 'fixed_ips': [{ 'subnet_id': self.fake_subnet['id'], 'ip_address': '10.10.10.20' }] }).info() expected_acls = [] expected_acls += ovn_acl.drop_all_ip_traffic_for_port(fake_port_sg) if not native_dhcp: expected_acls += ovn_acl.add_acl_dhcp(fake_port_sg, self.fake_subnet) sg_rule_acl = ovn_acl.add_sg_rule_acl_for_port( fake_port_sg, self.fake_sg_rule, 'outport == "' + fake_port_sg['id'] + '" ' + '&& ip4 && ip4.src == 0.0.0.0/0 ' + '&& tcp && tcp.dst == 22') expected_acls.append(sg_rule_acl) # Test with caches acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, self.sg_cache, self.subnet_cache) self.assertEqual(expected_acls, acls) # Test without caches with mock.patch('neutron.db.db_base_plugin_v2.' 'NeutronDbPluginV2.get_subnet', return_value=self.fake_subnet), \ mock.patch('neutron.db.securitygroups_db.' 'SecurityGroupDbMixin.get_security_group', return_value=self.fake_sg): acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, {}, {}) self.assertEqual(expected_acls, acls) # Test with security groups disabled with mock.patch('networking_ovn.common.acl.is_sg_enabled', return_value=False): acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, self.sg_cache, self.subnet_cache) self.assertEqual([], acls) # Test with multiple fixed IPs on the same subnet. fake_port_sg['fixed_ips'].append({ 'subnet_id': self.fake_subnet['id'], 'ip_address': '10.10.10.21' }) acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, self.sg_cache, self.subnet_cache) self.assertEqual(expected_acls, acls)
def _test_add_acls_with_sec_group_helper(self, native_dhcp=True): fake_port_sg = fakes.FakePort.create_one_port( attrs={ "security_groups": [self.fake_sg["id"]], "fixed_ips": [{"subnet_id": self.fake_subnet["id"], "ip_address": "10.10.10.20"}], } ).info() expected_acls = [] expected_acls += ovn_acl.drop_all_ip_traffic_for_port(fake_port_sg) if not native_dhcp: expected_acls += ovn_acl.add_acl_dhcp(fake_port_sg, self.fake_subnet) sg_rule_acl = ovn_acl.add_sg_rule_acl_for_port( fake_port_sg, self.fake_sg_rule, 'outport == "' + fake_port_sg["id"] + '" ' + "&& ip4 && ip4.src == 0.0.0.0/0 " + "&& tcp && tcp.dst == 22", ) expected_acls.append(sg_rule_acl) # Test with caches acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, self.sg_cache, self.subnet_cache) self.assertEqual(expected_acls, acls) # Test without caches with mock.patch( "neutron.db.db_base_plugin_v2." "NeutronDbPluginV2.get_subnet", return_value=self.fake_subnet ), mock.patch( "neutron.db.securitygroups_db." "SecurityGroupDbMixin.get_security_group", return_value=self.fake_sg ): acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, {}, {}) self.assertEqual(expected_acls, acls) # Test with security groups disabled with mock.patch("networking_ovn.common.acl.is_sg_enabled", return_value=False): acls = ovn_acl.add_acls( self.mech_driver._plugin, mock.Mock(), fake_port_sg, self.sg_cache, self.subnet_cache ) self.assertEqual([], acls) # Test with multiple fixed IPs on the same subnet. fake_port_sg["fixed_ips"].append({"subnet_id": self.fake_subnet["id"], "ip_address": "10.10.10.21"}) acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, self.sg_cache, self.subnet_cache) self.assertEqual(expected_acls, acls)
def _create_resources(self): n1 = self._make_network(self.fmt, 'n1', True) res = self._create_subnet(self.fmt, n1['network']['id'], '10.0.0.0/24') n1_s1 = self.deserialize(self.fmt, res) res = self._create_subnet(self.fmt, n1['network']['id'], '2001:dba::/64', ip_version=6, enable_dhcp=False) n1_s2 = self.deserialize(self.fmt, res) res = self._create_subnet(self.fmt, n1['network']['id'], '2001:dbb::/64', ip_version=6, enable_dhcp=False) n1_s3 = self.deserialize(self.fmt, res) self.expected_dhcp_options_rows.append({ 'cidr': '10.0.0.0/24', 'external_ids': { 'subnet_id': n1_s1['subnet']['id'] }, 'options': { 'server_id': '10.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n1['network']['mtu']), 'router': n1_s1['subnet']['gateway_ip'] } }) update_port_ids = [] for p in ['p1', 'p2', 'p3', 'p4', 'p5']: port = self._make_port(self.fmt, n1['network']['id'], name='n1-' + p, device_owner='compute:None') lport_name = port['port']['id'] lswitch_name = 'neutron-' + n1['network']['id'] if p == 'p1': fake_subnet = {'cidr': '11.11.11.11/24'} dhcp_acls = acl_utils.add_acl_dhcp(port['port'], fake_subnet) for dhcp_acl in dhcp_acls: self.create_acls.append(dhcp_acl) elif p == 'p2': self.delete_lswitch_ports.append((lport_name, lswitch_name)) update_port_ids.append(port['port']['id']) self.expected_dhcp_options_rows.append({ 'cidr': '10.0.0.0/24', 'external_ids': { 'subnet_id': n1_s1['subnet']['id'], 'port_id': port['port']['id'] }, 'options': { 'server_id': '10.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n1['network']['mtu']), 'router': n1_s1['subnet']['gateway_ip'], 'tftp_server': '20.0.0.20', 'dns_server': '8.8.8.8' } }) self.dirty_dhcpv4_options.append({ 'subnet_id': n1_s1['subnet']['id'], 'port_id': lport_name }) elif p == 'p3': self.delete_acls.append((lport_name, lswitch_name)) self.reset_lport_dhcpv4_options.append(lport_name) elif p == 'p4': self.lport_dhcpv4_disabled.update({ lport_name: self.mech_driver._nb_ovn.get_subnet_dhcp_options( n1_s1['subnet']['id'])['uuid'] }) data = { 'port': { 'extra_dhcp_opts': [{ 'ip_version': 4, 'opt_name': 'dhcp_disabled', 'opt_value': 'True' }] } } port_req = self.new_update_request('ports', data, lport_name) port_req.get_response(self.api) elif p == 'p5': self.stale_lport_dhcpv4_options.append({ 'subnet_id': n1_s1['subnet']['id'], 'port_id': port['port']['id'], 'cidr': '10.0.0.0/24', 'options': { 'server_id': '10.0.0.254', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(3 * 60 * 60), 'mtu': str(n1['network']['mtu'] / 2), 'router': '10.0.0.254', 'tftp_server': '20.0.0.234', 'dns_server': '8.8.8.8' }, 'external_ids': { 'subnet_id': n1_s1['subnet']['id'], 'port_id': port['port']['id'] }, }) self.dirty_dhcpv4_options.append({'subnet_id': n1_s1['subnet']['id']}) n2 = self._make_network(self.fmt, 'n2', True) res = self._create_subnet(self.fmt, n2['network']['id'], '20.0.0.0/24') n2_s1 = self.deserialize(self.fmt, res) self.expected_dhcp_options_rows.append({ 'cidr': '20.0.0.0/24', 'external_ids': { 'subnet_id': n2_s1['subnet']['id'] }, 'options': { 'server_id': '20.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n2['network']['mtu']), 'router': n2_s1['subnet']['gateway_ip'] } }) for p in ['p1', 'p2']: port = self._make_port(self.fmt, n2['network']['id'], name='n2-' + p, device_owner='compute:None') if p == 'p1': update_port_ids.append(port['port']['id']) self.expected_dhcp_options_rows.append({ 'cidr': '20.0.0.0/24', 'external_ids': { 'subnet_id': n2_s1['subnet']['id'], 'port_id': port['port']['id'] }, 'options': { 'server_id': '20.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n1['network']['mtu']), 'router': n2_s1['subnet']['gateway_ip'], 'tftp_server': '20.0.0.20', 'dns_server': '8.8.8.8' } }) self.missed_dhcpv4_options.append( self.mech_driver._nb_ovn.get_subnet_dhcp_options( n2_s1['subnet']['id'])['uuid']) for port_id in update_port_ids: data = { 'port': { 'extra_dhcp_opts': [{ 'ip_version': 4, 'opt_name': 'tftp-server', 'opt_value': '20.0.0.20' }, { 'ip_version': 4, 'opt_name': 'dns-server', 'opt_value': '8.8.8.8' }] } } port_req = self.new_update_request('ports', data, port_id) port_req.get_response(self.api) self.create_lswitches.append('neutron-' + uuid.uuid4().hex) self.create_lswitch_ports.append( ('neutron-' + uuid.uuid4().hex, 'neutron-' + n1['network']['id'])) self.delete_lswitches.append('neutron-' + n2['network']['id']) r1 = self.l3_plugin.create_router( self.context, { 'router': { 'name': 'r1', 'admin_state_up': True, 'tenant_id': self._tenant_id } }) self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n1_s1['subnet']['id']}) r1_p2 = self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n1_s2['subnet']['id']}) self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n1_s3['subnet']['id']}) r1_p3 = self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n2_s1['subnet']['id']}) self.update_lrouter_ports.append( ('lrp-' + r1_p2['port_id'], 'neutron-' + r1['id'], n1_s2['subnet']['gateway_ip'])) self.delete_lrouter_ports.append( ('lrp-' + r1_p3['port_id'], 'neutron-' + r1['id'])) self.l3_plugin.update_router( self.context, r1['id'], { 'router': { 'routes': [{ 'destination': '10.10.0.0/24', 'nexthop': '20.0.0.10' }, { 'destination': '10.11.0.0/24', 'nexthop': '20.0.0.11' }] } }) self.create_lrouter_routes.append( ('neutron-' + r1['id'], '10.12.0.0/24', '20.0.0.12')) self.delete_lrouter_routes.append( ('neutron-' + r1['id'], '10.10.0.0/24', '20.0.0.10')) r2 = self.l3_plugin.create_router( self.context, { 'router': { 'name': 'r2', 'admin_state_up': True, 'tenant_id': self._tenant_id } }) n1_p6 = self._make_port(self.fmt, n1['network']['id'], name='n1-p6') self.l3_plugin.add_router_interface(self.context, r2['id'], {'port_id': n1_p6['port']['id']}) self.l3_plugin.update_router( self.context, r2['id'], { 'router': { 'routes': [{ 'destination': '10.20.0.0/24', 'nexthop': '10.0.0.20' }] } }) self.create_lrouters.append('neutron-' + uuid.uuid4().hex) self.create_lrouter_ports.append( ('lrp-' + uuid.uuid4().hex, 'neutron-' + r1['id'])) self.delete_lrouters.append('neutron-' + r2['id']) address_set_name = n1_p6['port']['security_groups'][0] self.create_address_sets.extend([('fake_sg', 'ip4'), ('fake_sg', 'ip6')]) self.delete_address_sets.append((address_set_name, 'ip6')) address_adds = ['10.0.0.101', '10.0.0.102'] address_dels = [] for address in n1_p6['port']['fixed_ips']: address_dels.append(address['ip_address']) self.update_address_sets.append( (address_set_name, 'ip4', address_adds, address_dels)) # Create a network and subnet with orphaned OVN resources. n3 = self._make_network(self.fmt, 'n3', True) res = self._create_subnet(self.fmt, n3['network']['id'], '30.0.0.0/24') n3_s1 = self.deserialize(self.fmt, res) self.expected_dhcp_options_rows.append({ 'cidr': '30.0.0.0/24', 'external_ids': { 'subnet_id': n3_s1['subnet']['id'] }, 'options': { 'server_id': '30.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n3['network']['mtu']), 'router': n3_s1['subnet']['gateway_ip'] } }) fake_port_id1 = uuid.uuid4().hex fake_port_id2 = uuid.uuid4().hex self.create_lswitch_ports.append( ('neutron-' + fake_port_id1, 'neutron-' + n3['network']['id'])) self.create_lswitch_ports.append( ('neutron-' + fake_port_id2, 'neutron-' + n3['network']['id'])) stale_dhcpv4_options1 = { 'subnet_id': n3_s1['subnet']['id'], 'port_id': fake_port_id1, 'cidr': '30.0.0.0/24', 'options': { 'server_id': '30.0.0.254', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(3 * 60 * 60), 'mtu': str(n3['network']['mtu'] / 2), 'router': '30.0.0.254', 'tftp_server': '30.0.0.234', 'dns_server': '8.8.8.8' }, 'external_ids': { 'subnet_id': n3_s1['subnet']['id'], 'port_id': fake_port_id1 }, } self.stale_lport_dhcpv4_options.append(stale_dhcpv4_options1) stale_dhcpv4_options2 = stale_dhcpv4_options1.copy() stale_dhcpv4_options2.update({ 'port_id': fake_port_id2, 'external_ids': { 'subnet_id': n3_s1['subnet']['id'], 'port_id': fake_port_id2 } }) self.orphaned_lport_dhcpv4_options.append(fake_port_id2) fake_port = {'id': fake_port_id1, 'network_id': n3['network']['id']} dhcp_acls = acl_utils.add_acl_dhcp(fake_port, n3_s1['subnet']) for dhcp_acl in dhcp_acls: self.create_acls.append(dhcp_acl)
def _create_resources(self): n1 = self._make_network(self.fmt, 'n1', True) res = self._create_subnet(self.fmt, n1['network']['id'], '10.0.0.0/24') n1_s1 = self.deserialize(self.fmt, res) res = self._create_subnet(self.fmt, n1['network']['id'], '2001:dba::/64', ip_version=6, enable_dhcp=True) n1_s2 = self.deserialize(self.fmt, res) res = self._create_subnet(self.fmt, n1['network']['id'], '2001:dbb::/64', ip_version=6, ipv6_address_mode='slaac', ipv6_ra_mode='slaac') n1_s3 = self.deserialize(self.fmt, res) self.expected_dhcp_options_rows.append({ 'cidr': '10.0.0.0/24', 'external_ids': {'subnet_id': n1_s1['subnet']['id']}, 'options': {'server_id': '10.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n1['network']['mtu']), 'router': n1_s1['subnet']['gateway_ip']}}) self.expected_dhcp_options_rows.append({ 'cidr': '2001:dba::/64', 'external_ids': {'subnet_id': n1_s2['subnet']['id']}, 'options': {'server_id': '01:02:03:04:05:06'}}) n1_s1_dhcp_options_uuid = ( self.mech_driver._nb_ovn.get_subnet_dhcp_options( n1_s1['subnet']['id'])['uuid']) update_port_ids_v4 = [] update_port_ids_v6 = [] for p in ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7']: port = self._make_port(self.fmt, n1['network']['id'], name='n1-' + p, device_owner='compute:None') lport_name = port['port']['id'] lswitch_name = 'neutron-' + n1['network']['id'] if p == 'p1': fake_subnet = {'cidr': '11.11.11.11/24'} dhcp_acls = acl_utils.add_acl_dhcp(port['port'], fake_subnet) for dhcp_acl in dhcp_acls: self.create_acls.append(dhcp_acl) elif p == 'p2': self.delete_lswitch_ports.append((lport_name, lswitch_name)) update_port_ids_v4.append(port['port']['id']) update_port_ids_v6.append(port['port']['id']) self.expected_dhcp_options_rows.append({ 'cidr': '10.0.0.0/24', 'external_ids': {'subnet_id': n1_s1['subnet']['id'], 'port_id': port['port']['id']}, 'options': {'server_id': '10.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n1['network']['mtu']), 'router': n1_s1['subnet']['gateway_ip'], 'tftp_server': '20.0.0.20', 'dns_server': '8.8.8.8'}}) self.expected_dhcp_options_rows.append({ 'cidr': '2001:dba::/64', 'external_ids': {'subnet_id': n1_s2['subnet']['id'], 'port_id': port['port']['id']}, 'options': {'server_id': '01:02:03:04:05:06', 'domain_search': 'foo-domain'}}) self.dirty_dhcp_options.append({ 'subnet_id': n1_s1['subnet']['id'], 'port_id': lport_name}) self.dirty_dhcp_options.append({ 'subnet_id': n1_s2['subnet']['id'], 'port_id': lport_name}) elif p == 'p3': self.delete_acls.append((lport_name, lswitch_name)) self.reset_lport_dhcpv4_options.append(lport_name) self.lport_dhcpv6_disabled.update({ lport_name: n1_s1_dhcp_options_uuid}) data = {'port': { 'extra_dhcp_opts': [{'ip_version': 6, 'opt_name': 'dhcp_disabled', 'opt_value': 'True'}]}} port_req = self.new_update_request('ports', data, lport_name) port_req.get_response(self.api) elif p == 'p4': self.lport_dhcpv4_disabled.update({ lport_name: n1_s1_dhcp_options_uuid}) data = {'port': { 'extra_dhcp_opts': [{'ip_version': 4, 'opt_name': 'dhcp_disabled', 'opt_value': 'True'}]}} port_req = self.new_update_request('ports', data, lport_name) port_req.get_response(self.api) self.reset_lport_dhcpv6_options.append(lport_name) elif p == 'p5': self.stale_lport_dhcpv4_options.append({ 'subnet_id': n1_s1['subnet']['id'], 'port_id': port['port']['id'], 'cidr': '10.0.0.0/24', 'options': {'server_id': '10.0.0.254', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(3 * 60 * 60), 'mtu': str(n1['network']['mtu'] / 2), 'router': '10.0.0.254', 'tftp_server': '20.0.0.234', 'dns_server': '8.8.8.8'}, 'external_ids': {'subnet_id': n1_s1['subnet']['id'], 'port_id': port['port']['id']}, }) elif p == 'p6': self.delete_lswitch_ports.append((lport_name, lswitch_name)) elif p == 'p7': update_port_ids_v4.append(port['port']['id']) update_port_ids_v6.append(port['port']['id']) self.expected_dhcp_options_rows.append({ 'cidr': '10.0.0.0/24', 'external_ids': {'subnet_id': n1_s1['subnet']['id'], 'port_id': port['port']['id']}, 'options': {'server_id': '10.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n1['network']['mtu']), 'router': n1_s1['subnet']['gateway_ip'], 'tftp_server': '20.0.0.20', 'dns_server': '8.8.8.8'}}) self.expected_dhcp_options_rows.append({ 'cidr': '2001:dba::/64', 'external_ids': {'subnet_id': n1_s2['subnet']['id'], 'port_id': port['port']['id']}, 'options': {'server_id': '01:02:03:04:05:06', 'domain_search': 'foo-domain'}}) self.reset_lport_dhcpv4_options.append(lport_name) self.reset_lport_dhcpv6_options.append(lport_name) self.dirty_dhcp_options.append({'subnet_id': n1_s1['subnet']['id']}) self.dirty_dhcp_options.append({'subnet_id': n1_s2['subnet']['id']}) n2 = self._make_network(self.fmt, 'n2', True) res = self._create_subnet(self.fmt, n2['network']['id'], '20.0.0.0/24') n2_s1 = self.deserialize(self.fmt, res) res = self._create_subnet(self.fmt, n2['network']['id'], '2001:dbd::/64', ip_version=6) n2_s2 = self.deserialize(self.fmt, res) self.expected_dhcp_options_rows.append({ 'cidr': '20.0.0.0/24', 'external_ids': {'subnet_id': n2_s1['subnet']['id']}, 'options': {'server_id': '20.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n2['network']['mtu']), 'router': n2_s1['subnet']['gateway_ip']}}) self.expected_dhcp_options_rows.append({ 'cidr': '2001:dbd::/64', 'external_ids': {'subnet_id': n2_s2['subnet']['id']}, 'options': {'server_id': '01:02:03:04:05:06'}}) for p in ['p1', 'p2']: port = self._make_port(self.fmt, n2['network']['id'], name='n2-' + p, device_owner='compute:None') if p == 'p1': update_port_ids_v4.append(port['port']['id']) self.expected_dhcp_options_rows.append({ 'cidr': '20.0.0.0/24', 'external_ids': {'subnet_id': n2_s1['subnet']['id'], 'port_id': port['port']['id']}, 'options': {'server_id': '20.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n1['network']['mtu']), 'router': n2_s1['subnet']['gateway_ip'], 'tftp_server': '20.0.0.20', 'dns_server': '8.8.8.8'}}) self.missed_dhcp_options.extend([ opts['uuid'] for opts in self.mech_driver._nb_ovn.get_subnets_dhcp_options( [n2_s1['subnet']['id'], n2_s2['subnet']['id']])]) for port_id in update_port_ids_v4: data = {'port': {'extra_dhcp_opts': [{'ip_version': 4, 'opt_name': 'tftp-server', 'opt_value': '20.0.0.20'}, {'ip_version': 4, 'opt_name': 'dns-server', 'opt_value': '8.8.8.8'}]}} port_req = self.new_update_request('ports', data, port_id) port_req.get_response(self.api) for port_id in update_port_ids_v6: data = {'port': {'extra_dhcp_opts': [{'ip_version': 6, 'opt_name': 'domain-search', 'opt_value': 'foo-domain'}]}} port_req = self.new_update_request('ports', data, port_id) port_req.get_response(self.api) self.create_lswitches.append('neutron-' + uuid.uuid4().hex) self.create_lswitch_ports.append(('neutron-' + uuid.uuid4().hex, 'neutron-' + n1['network']['id'])) self.create_lswitch_ports.append(('neutron-' + uuid.uuid4().hex, 'neutron-' + n1['network']['id'])) self.delete_lswitches.append('neutron-' + n2['network']['id']) r1 = self.l3_plugin.create_router( self.context, {'router': {'name': 'r1', 'admin_state_up': True, 'tenant_id': self._tenant_id}}) self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n1_s1['subnet']['id']}) r1_p2 = self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n1_s2['subnet']['id']}) self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n1_s3['subnet']['id']}) r1_p3 = self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n2_s1['subnet']['id']}) self.update_lrouter_ports.append(('lrp-' + r1_p2['port_id'], 'neutron-' + r1['id'], n1_s2['subnet']['gateway_ip'])) self.delete_lrouter_ports.append(('lrp-' + r1_p3['port_id'], 'neutron-' + r1['id'])) self.l3_plugin.update_router( self.context, r1['id'], {'router': {'routes': [{'destination': '10.10.0.0/24', 'nexthop': '20.0.0.10'}, {'destination': '10.11.0.0/24', 'nexthop': '20.0.0.11'}]}}) self.create_lrouter_routes.append(('neutron-' + r1['id'], '10.12.0.0/24', '20.0.0.12')) self.create_lrouter_routes.append(('neutron-' + r1['id'], '10.13.0.0/24', '20.0.0.13')) self.delete_lrouter_routes.append(('neutron-' + r1['id'], '10.10.0.0/24', '20.0.0.10')) r2 = self.l3_plugin.create_router( self.context, {'router': {'name': 'r2', 'admin_state_up': True, 'tenant_id': self._tenant_id}}) n1_prtr = self._make_port(self.fmt, n1['network']['id'], name='n1-p-rtr') self.l3_plugin.add_router_interface( self.context, r2['id'], {'port_id': n1_prtr['port']['id']}) self.l3_plugin.update_router( self.context, r2['id'], {'router': {'routes': [{'destination': '10.20.0.0/24', 'nexthop': '10.0.0.20'}]}}) self.create_lrouters.append('neutron-' + uuid.uuid4().hex) self.create_lrouter_ports.append(('lrp-' + uuid.uuid4().hex, 'neutron-' + r1['id'])) self.create_lrouter_ports.append(('lrp-' + uuid.uuid4().hex, 'neutron-' + r1['id'])) self.delete_lrouters.append('neutron-' + r2['id']) address_set_name = n1_prtr['port']['security_groups'][0] self.create_address_sets.extend([('fake_sg', 'ip4'), ('fake_sg', 'ip6')]) self.delete_address_sets.append((address_set_name, 'ip6')) address_adds = ['10.0.0.101', '10.0.0.102'] address_dels = [] for address in n1_prtr['port']['fixed_ips']: address_dels.append(address['ip_address']) self.update_address_sets.append((address_set_name, 'ip4', address_adds, address_dels)) # Create a network and subnet with orphaned OVN resources. n3 = self._make_network(self.fmt, 'n3', True) res = self._create_subnet(self.fmt, n3['network']['id'], '30.0.0.0/24') n3_s1 = self.deserialize(self.fmt, res) self.expected_dhcp_options_rows.append({ 'cidr': '30.0.0.0/24', 'external_ids': {'subnet_id': n3_s1['subnet']['id']}, 'options': {'server_id': '30.0.0.1', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(12 * 60 * 60), 'mtu': str(n3['network']['mtu']), 'router': n3_s1['subnet']['gateway_ip']}}) res = self._create_subnet(self.fmt, n3['network']['id'], '2001:dbc::/64', ip_version=6) n3_s2 = self.deserialize(self.fmt, res) self.expected_dhcp_options_rows.append({ 'cidr': '2001:dbc::/64', 'external_ids': {'subnet_id': n3_s2['subnet']['id']}, 'options': {'server_id': '01:02:03:04:05:06'}}) fake_port_id1 = uuid.uuid4().hex fake_port_id2 = uuid.uuid4().hex self.create_lswitch_ports.append(('neutron-' + fake_port_id1, 'neutron-' + n3['network']['id'])) self.create_lswitch_ports.append(('neutron-' + fake_port_id2, 'neutron-' + n3['network']['id'])) stale_dhcpv4_options1 = { 'subnet_id': n3_s1['subnet']['id'], 'port_id': fake_port_id1, 'cidr': '30.0.0.0/24', 'options': {'server_id': '30.0.0.254', 'server_mac': '01:02:03:04:05:06', 'lease_time': str(3 * 60 * 60), 'mtu': str(n3['network']['mtu'] / 2), 'router': '30.0.0.254', 'tftp_server': '30.0.0.234', 'dns_server': '8.8.8.8'}, 'external_ids': {'subnet_id': n3_s1['subnet']['id'], 'port_id': fake_port_id1}, } self.stale_lport_dhcpv4_options.append(stale_dhcpv4_options1) stale_dhcpv4_options2 = stale_dhcpv4_options1.copy() stale_dhcpv4_options2.update({ 'port_id': fake_port_id2, 'external_ids': {'subnet_id': n3_s1['subnet']['id'], 'port_id': fake_port_id2}}) self.stale_lport_dhcpv4_options.append(stale_dhcpv4_options2) self.orphaned_lport_dhcp_options.append(fake_port_id2) stale_dhcpv6_options1 = { 'subnet_id': n3_s2['subnet']['id'], 'port_id': fake_port_id1, 'cidr': '2001:dbc::/64', 'options': {'server_id': '01:02:03:04:05:06', 'domain-search': 'foo-domain'}, 'external_ids': {'subnet_id': n3_s2['subnet']['id'], 'port_id': fake_port_id1}, } self.stale_lport_dhcpv6_options.append(stale_dhcpv6_options1) stale_dhcpv6_options2 = stale_dhcpv6_options1.copy() stale_dhcpv6_options2.update({ 'port_id': fake_port_id2, 'external_ids': {'subnet_id': n3_s2['subnet']['id'], 'port_id': fake_port_id2}}) self.stale_lport_dhcpv6_options.append(stale_dhcpv6_options2) fake_port = {'id': fake_port_id1, 'network_id': n3['network']['id']} dhcp_acls = acl_utils.add_acl_dhcp(fake_port, n3_s1['subnet']) for dhcp_acl in dhcp_acls: self.create_acls.append(dhcp_acl)
def _test_add_acls_with_sec_group_helper(self, native_dhcp=True): fake_port_sg = fakes.FakePort.create_one_port( attrs={'security_groups': [self.fake_sg['id']], 'fixed_ips': [{'subnet_id': self.fake_subnet['id'], 'ip_address': '10.10.10.20'}]} ).info() expected_acls = [] expected_acls += ovn_acl.drop_all_ip_traffic_for_port( fake_port_sg) if not native_dhcp: expected_acls += ovn_acl.add_acl_dhcp( fake_port_sg, self.fake_subnet) sg_rule_acl = ovn_acl.add_sg_rule_acl_for_port( fake_port_sg, self.fake_sg_rule, 'outport == "' + fake_port_sg['id'] + '" ' + '&& ip4 && ip4.src == 0.0.0.0/0 ' + '&& tcp && tcp.dst == 22') expected_acls.append(sg_rule_acl) # Test with caches acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, self.sg_cache, self.subnet_cache) self.assertEqual(expected_acls, acls) # Test without caches with mock.patch('neutron.db.db_base_plugin_v2.' 'NeutronDbPluginV2.get_subnet', return_value=self.fake_subnet), \ mock.patch('neutron.db.securitygroups_db.' 'SecurityGroupDbMixin.get_security_group', return_value=self.fake_sg): acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, {}, {}) self.assertEqual(expected_acls, acls) # Test with security groups disabled with mock.patch('networking_ovn.common.acl.is_sg_enabled', return_value=False): acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, self.sg_cache, self.subnet_cache) self.assertEqual([], acls) # Test with multiple fixed IPs on the same subnet. fake_port_sg['fixed_ips'].append({'subnet_id': self.fake_subnet['id'], 'ip_address': '10.10.10.21'}) acls = ovn_acl.add_acls(self.mech_driver._plugin, mock.Mock(), fake_port_sg, self.sg_cache, self.subnet_cache) self.assertEqual(expected_acls, acls)
def _create_resources(self): n1 = self._make_network(self.fmt, 'n1', True) res = self._create_subnet(self.fmt, n1['network']['id'], '10.0.0.0/24') n1_s1 = self.deserialize(self.fmt, res) for p in ['p1', 'p2', 'p3']: port = self._make_port(self.fmt, n1['network']['id'], name='n1-' + p) lport_name = port['port']['id'] lswitch_name = 'neutron-' + n1['network']['id'] if p == 'p1': fake_subnet = {'cidr': '11.11.11.11/24'} dhcp_acls = acl_utils.add_acl_dhcp(port['port'], fake_subnet) for dhcp_acl in dhcp_acls: self.create_acls.append(dhcp_acl) elif p == 'p2': self.delete_lswitch_ports.append((lport_name, lswitch_name)) elif p == 'p3': self.delete_acls.append((lport_name, lswitch_name)) n2 = self._make_network(self.fmt, 'n2', True) res = self._create_subnet(self.fmt, n2['network']['id'], '20.0.0.0/24') n2_s1 = self.deserialize(self.fmt, res) for p in ['p1', 'p2']: port = self._make_port(self.fmt, n2['network']['id'], name='n2-' + p) self.create_lswitches.append('neutron-' + uuid.uuid4().hex) self.create_lswitch_ports.append( ('neutron-' + uuid.uuid4().hex, 'neutron-' + n1['network']['id'])) self.delete_lswitches.append('neutron-' + n2['network']['id']) r1 = self.l3_plugin.create_router( self.context, { 'router': { 'name': 'r1', 'admin_state_up': True, 'tenant_id': self._tenant_id } }) self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n1_s1['subnet']['id']}) r1_p2 = self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n2_s1['subnet']['id']}) self.delete_lrouter_ports.append( ('lrp-' + r1_p2['port_id'], 'neutron-' + r1['id'])) self.l3_plugin.update_router( self.context, r1['id'], { 'router': { 'routes': [{ 'destination': '10.10.0.0/24', 'nexthop': '20.0.0.10' }, { 'destination': '10.11.0.0/24', 'nexthop': '20.0.0.11' }] } }) self.create_lrouter_routes.append( ('neutron-' + r1['id'], '10.12.0.0/24', '20.0.0.12')) self.delete_lrouter_routes.append( ('neutron-' + r1['id'], '10.10.0.0/24', '20.0.0.10')) r2 = self.l3_plugin.create_router( self.context, { 'router': { 'name': 'r2', 'admin_state_up': True, 'tenant_id': self._tenant_id } }) n1_p4 = self._make_port(self.fmt, n1['network']['id'], name='n1-p4') self.l3_plugin.add_router_interface(self.context, r2['id'], {'port_id': n1_p4['port']['id']}) self.l3_plugin.update_router( self.context, r2['id'], { 'router': { 'routes': [{ 'destination': '10.20.0.0/24', 'nexthop': '10.0.0.20' }] } }) self.create_lrouters.append('neutron-' + uuid.uuid4().hex) self.create_lrouter_ports.append( ('lrp-' + uuid.uuid4().hex, 'neutron-' + r1['id'])) self.delete_lrouters.append('neutron-' + r2['id'])
def _create_resources(self): n1 = self._make_network(self.fmt, 'n1', True) res = self._create_subnet(self.fmt, n1['network']['id'], '10.0.0.0/24') n1_s1 = self.deserialize(self.fmt, res) for p in ['p1', 'p2', 'p3']: port = self._make_port(self.fmt, n1['network']['id'], name='n1-' + p) lport_name = port['port']['id'] lswitch_name = 'neutron-' + n1['network']['id'] if p == 'p1': fake_subnet = {'cidr': '11.11.11.11/24'} dhcp_acls = acl_utils.add_acl_dhcp(port['port'], fake_subnet) for dhcp_acl in dhcp_acls: self.create_acls.append(dhcp_acl) elif p == 'p2': self.delete_lswitch_ports.append((lport_name, lswitch_name)) elif p == 'p3': self.delete_acls.append((lport_name, lswitch_name)) n2 = self._make_network(self.fmt, 'n2', True) res = self._create_subnet(self.fmt, n2['network']['id'], '20.0.0.0/24') n2_s1 = self.deserialize(self.fmt, res) for p in ['p1', 'p2']: port = self._make_port(self.fmt, n2['network']['id'], name='n2-' + p) self.create_lswitches.append('neutron-' + uuid.uuid4().hex) self.create_lswitch_ports.append(('neutron-' + uuid.uuid4().hex, 'neutron-' + n1['network']['id'])) self.delete_lswitches.append('neutron-' + n2['network']['id']) r1 = self.l3_plugin.create_router( self.context, {'router': {'name': 'r1', 'admin_state_up': True, 'tenant_id': self._tenant_id}}) self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n1_s1['subnet']['id']}) r1_p2 = self.l3_plugin.add_router_interface( self.context, r1['id'], {'subnet_id': n2_s1['subnet']['id']}) self.delete_lrouter_ports.append(('lrp-' + r1_p2['port_id'], 'neutron-' + r1['id'])) self.l3_plugin.update_router( self.context, r1['id'], {'router': {'routes': [{'destination': '10.10.0.0/24', 'nexthop': '20.0.0.10'}, {'destination': '10.11.0.0/24', 'nexthop': '20.0.0.11'}]}}) self.create_lrouter_routes.append(('neutron-' + r1['id'], '10.12.0.0/24', '20.0.0.12')) self.delete_lrouter_routes.append(('neutron-' + r1['id'], '10.10.0.0/24', '20.0.0.10')) r2 = self.l3_plugin.create_router( self.context, {'router': {'name': 'r2', 'admin_state_up': True, 'tenant_id': self._tenant_id}}) n1_p4 = self._make_port(self.fmt, n1['network']['id'], name='n1-p4') self.l3_plugin.add_router_interface( self.context, r2['id'], {'port_id': n1_p4['port']['id']}) self.l3_plugin.update_router( self.context, r2['id'], {'router': {'routes': [{'destination': '10.20.0.0/24', 'nexthop': '10.0.0.20'}]}}) self.create_lrouters.append('neutron-' + uuid.uuid4().hex) self.create_lrouter_ports.append(('lrp-' + uuid.uuid4().hex, 'neutron-' + r1['id'])) self.delete_lrouters.append('neutron-' + r2['id'])