Filter port-list based on security_groups.
This patch allows users to filter ports depending on security groups. In addition to that I added a unit test to verify this change. TODO: move security_groups_port_filtering_lib.py into neutron-lib. Closes-Bug: 1405057 Change-Id: I528719d895fc1d89f74e2ee85b9ddc470323c601
This commit is contained in:
parent
1813f7c497
commit
43d3e88a07
23
neutron/extensions/security_groups_port_filtering.py
Normal file
23
neutron/extensions/security_groups_port_filtering.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Copyright (c) 2018 Nokia. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from neutron_lib.api import extensions
|
||||||
|
|
||||||
|
from neutron.extensions import security_groups_port_filtering_lib as apidef
|
||||||
|
|
||||||
|
|
||||||
|
class Security_groups_port_filtering(extensions.APIExtensionDescriptor):
|
||||||
|
"""Extension class supporting filtering port depend on security group."""
|
||||||
|
|
||||||
|
api_definition = apidef
|
59
neutron/extensions/security_groups_port_filtering_lib.py
Normal file
59
neutron/extensions/security_groups_port_filtering_lib.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
# The alias of the extension.
|
||||||
|
ALIAS = 'port-security-groups-filtering'
|
||||||
|
|
||||||
|
# Whether or not this extension is simply signaling behavior to the user
|
||||||
|
# or it actively modifies the attribute map.
|
||||||
|
IS_SHIM_EXTENSION = True
|
||||||
|
|
||||||
|
# Whether the extension is marking the adoption of standardattr model for
|
||||||
|
# legacy resources, or introducing new standardattr attributes. False or
|
||||||
|
# None if the standardattr model is adopted since the introduction of
|
||||||
|
# resource extension.
|
||||||
|
# If this is True, the alias for the extension should be prefixed with
|
||||||
|
# 'standard-attr-'.
|
||||||
|
IS_STANDARD_ATTR_EXTENSION = False
|
||||||
|
|
||||||
|
# The name of the extension.
|
||||||
|
NAME = 'Port filtering on security groups'
|
||||||
|
|
||||||
|
# The description of the extension.
|
||||||
|
DESCRIPTION = "Provides security groups filtering when listing ports"
|
||||||
|
|
||||||
|
# A timestamp of when the extension was introduced.
|
||||||
|
UPDATED_TIMESTAMP = "2018-01-09T09:00:00-00:00"
|
||||||
|
|
||||||
|
# The resource attribute map for the extension.
|
||||||
|
RESOURCE_ATTRIBUTE_MAP = {
|
||||||
|
}
|
||||||
|
|
||||||
|
# The subresource attribute map for the extension.
|
||||||
|
SUB_RESOURCE_ATTRIBUTE_MAP = {
|
||||||
|
}
|
||||||
|
|
||||||
|
# The action map.
|
||||||
|
ACTION_MAP = {
|
||||||
|
}
|
||||||
|
|
||||||
|
# The action status.
|
||||||
|
ACTION_STATUS = {
|
||||||
|
}
|
||||||
|
|
||||||
|
# The list of required extensions.
|
||||||
|
REQUIRED_EXTENSIONS = [
|
||||||
|
]
|
||||||
|
|
||||||
|
# The list of optional extensions.
|
||||||
|
OPTIONAL_EXTENSIONS = [
|
||||||
|
]
|
@ -155,7 +155,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
"network_availability_zone",
|
"network_availability_zone",
|
||||||
"default-subnetpools",
|
"default-subnetpools",
|
||||||
"subnet-service-types",
|
"subnet-service-types",
|
||||||
"ip-substring-filtering"]
|
"ip-substring-filtering",
|
||||||
|
"port-security-groups-filtering"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_extension_aliases(self):
|
def supported_extension_aliases(self):
|
||||||
@ -1853,6 +1854,17 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
|
|
||||||
def _get_ports_query(self, context, filters=None, *args, **kwargs):
|
def _get_ports_query(self, context, filters=None, *args, **kwargs):
|
||||||
filters = filters or {}
|
filters = filters or {}
|
||||||
|
security_groups = filters.pop("security_groups", None)
|
||||||
|
if security_groups:
|
||||||
|
port_bindings = self._get_port_security_group_bindings(
|
||||||
|
context, filters={'security_group_id':
|
||||||
|
security_groups})
|
||||||
|
if 'id' in filters:
|
||||||
|
filters['id'] = [entry['port_id'] for
|
||||||
|
entry in port_bindings
|
||||||
|
if entry['port_id'] in filters['id']]
|
||||||
|
else:
|
||||||
|
filters['id'] = [entry['port_id'] for entry in port_bindings]
|
||||||
fixed_ips = filters.get('fixed_ips', {})
|
fixed_ips = filters.get('fixed_ips', {})
|
||||||
ip_addresses_s = fixed_ips.get('ip_address_substr')
|
ip_addresses_s = fixed_ips.get('ip_address_substr')
|
||||||
query = super(Ml2Plugin, self)._get_ports_query(context, filters,
|
query = super(Ml2Plugin, self)._get_ports_query(context, filters,
|
||||||
|
@ -37,6 +37,7 @@ NETWORK_API_EXTENSIONS+=",rbac-policies"
|
|||||||
NETWORK_API_EXTENSIONS+=",router"
|
NETWORK_API_EXTENSIONS+=",router"
|
||||||
NETWORK_API_EXTENSIONS+=",router_availability_zone"
|
NETWORK_API_EXTENSIONS+=",router_availability_zone"
|
||||||
NETWORK_API_EXTENSIONS+=",security-group"
|
NETWORK_API_EXTENSIONS+=",security-group"
|
||||||
|
NETWORK_API_EXTENSIONS+=",port-security-groups-filtering"
|
||||||
NETWORK_API_EXTENSIONS+=",segment"
|
NETWORK_API_EXTENSIONS+=",segment"
|
||||||
NETWORK_API_EXTENSIONS+=",service-type"
|
NETWORK_API_EXTENSIONS+=",service-type"
|
||||||
NETWORK_API_EXTENSIONS+=",sorting"
|
NETWORK_API_EXTENSIONS+=",sorting"
|
||||||
|
@ -44,6 +44,7 @@ from neutron.db import agents_db
|
|||||||
from neutron.db import api as db_api
|
from neutron.db import api as db_api
|
||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
from neutron.db import provisioning_blocks
|
from neutron.db import provisioning_blocks
|
||||||
|
from neutron.db import securitygroups_db as sg_db
|
||||||
from neutron.db import segments_db
|
from neutron.db import segments_db
|
||||||
from neutron.extensions import multiprovidernet as mpnet
|
from neutron.extensions import multiprovidernet as mpnet
|
||||||
from neutron.objects import base as base_obj
|
from neutron.objects import base as base_obj
|
||||||
@ -1278,6 +1279,45 @@ fixed_ips=ip_address_substr%%3D%s&fixed_ips=ip_address%%3D%s
|
|||||||
self._delete('ports', port1['port']['id'])
|
self._delete('ports', port1['port']['id'])
|
||||||
self._delete('ports', port2['port']['id'])
|
self._delete('ports', port2['port']['id'])
|
||||||
|
|
||||||
|
def test_list_ports_filtered_by_security_groups(self):
|
||||||
|
# for this test we need to enable overlapping ips
|
||||||
|
cfg.CONF.set_default('allow_overlapping_ips', True)
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
with self.port() as port1, self.port() as port2:
|
||||||
|
query_params = "security_groups=%s" % (
|
||||||
|
port1['port']['security_groups'][0])
|
||||||
|
ports_data = self._list('ports', query_params=query_params)
|
||||||
|
self.assertEqual(set([port1['port']['id'], port2['port']['id']]),
|
||||||
|
set([port['id'] for port in ports_data['ports']]))
|
||||||
|
self.assertEqual(2, len(ports_data['ports']))
|
||||||
|
query_params = "security_groups=%s&id=%s" % (
|
||||||
|
port1['port']['security_groups'][0],
|
||||||
|
port1['port']['id'])
|
||||||
|
ports_data = self._list('ports', query_params=query_params)
|
||||||
|
self.assertEqual(port1['port']['id'], ports_data['ports'][0]['id'])
|
||||||
|
self.assertEqual(1, len(ports_data['ports']))
|
||||||
|
temp_sg = {'security_group': {'tenant_id': 'some_tenant',
|
||||||
|
'name': '', 'description': 's'}}
|
||||||
|
sg_dbMixin = sg_db.SecurityGroupDbMixin()
|
||||||
|
sg = sg_dbMixin.create_security_group(ctx, temp_sg)
|
||||||
|
sg_dbMixin._delete_port_security_group_bindings(
|
||||||
|
ctx, port2['port']['id'])
|
||||||
|
sg_dbMixin._create_port_security_group_binding(
|
||||||
|
ctx, port2['port']['id'], sg['id'])
|
||||||
|
port2['port']['security_groups'][0] = sg['id']
|
||||||
|
query_params = "security_groups=%s&id=%s" % (
|
||||||
|
port1['port']['security_groups'][0],
|
||||||
|
port1['port']['id'])
|
||||||
|
ports_data = self._list('ports', query_params=query_params)
|
||||||
|
self.assertEqual(port1['port']['id'], ports_data['ports'][0]['id'])
|
||||||
|
self.assertEqual(1, len(ports_data['ports']))
|
||||||
|
query_params = "security_groups=%s&id=%s" % (
|
||||||
|
(port2['port']['security_groups'][0],
|
||||||
|
port2['port']['id']))
|
||||||
|
ports_data = self._list('ports', query_params=query_params)
|
||||||
|
self.assertEqual(port2['port']['id'], ports_data['ports'][0]['id'])
|
||||||
|
self.assertEqual(1, len(ports_data['ports']))
|
||||||
|
|
||||||
|
|
||||||
class TestMl2PortsV2WithRevisionPlugin(Ml2PluginV2TestCase):
|
class TestMl2PortsV2WithRevisionPlugin(Ml2PluginV2TestCase):
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Support port filtering on security group IDs.
|
||||||
|
The feature can be used if 'port-security-group-filtering' extension is available.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user