Merge "Allow add security group by uuid"

This commit is contained in:
Jenkins
2017-08-07 06:41:58 +00:00
committed by Gerrit Code Review
5 changed files with 85 additions and 19 deletions

View File

@@ -15,6 +15,7 @@
from oslo_log import log as logging from oslo_log import log as logging
from oslo_utils import strutils from oslo_utils import strutils
from oslo_utils import uuidutils
import pecan import pecan
import six import six
@@ -295,6 +296,34 @@ class ContainersController(base.Controller):
pecan.response.status = 202 pecan.response.status = 202
return view.format_container(pecan.request.host_url, new_container) return view.format_container(pecan.request.host_url, new_container)
def _check_security_group(self, context, security_group, container):
if security_group.get("uuid"):
security_group_id = security_group.get("uuid")
if not uuidutils.is_uuid_like(security_group_id):
raise exception.InvalidUUID(uuid=security_group_id)
if security_group_id in container.security_groups:
msg = _("security_group %s already present in container") % \
security_group_id
raise exception.InvalidValue(msg)
else:
security_group_ids = utils.get_security_group_ids(
context, [security_group['name']])
if len(security_group_ids) > len(security_group):
msg = _("Multiple security group matches "
"found for name %(name)s, use an ID "
"to be more specific. ") % security_group
raise exception.Conflict(msg)
else:
security_group_id = security_group_ids[0]
container_ports_detail = utils.list_ports(context, container)
for container_port_detail in container_ports_detail:
if security_group_id in container_port_detail['security_groups']:
msg = _("security_group %s already present in container") % \
list(security_group.values())[0]
raise exception.InvalidValue(msg)
return security_group_id
@pecan.expose('json') @pecan.expose('json')
@exception.wrap_pecan_controller_exception @exception.wrap_pecan_controller_exception
@validation.validated(schema.add_security_group) @validation.validated(schema.add_security_group)
@@ -312,21 +341,10 @@ class ContainersController(base.Controller):
# check if security group already presnt in container # check if security group already presnt in container
context = pecan.request.context context = pecan.request.context
compute_api = pecan.request.compute_api compute_api = pecan.request.compute_api
if security_group['name'] in container.security_groups: security_group_id = self._check_security_group(
msg = _("security_group %s already present in container") % \ context, security_group, container)
security_group['name']
raise exception.InvalidValue(msg)
security_group_id = utils.\
get_security_group_ids(context, [security_group['name']])[0]
container_ports_detail = utils.list_ports(context, container)
for container_port_detail in container_ports_detail:
if security_group_id in container_port_detail['security_groups']:
msg = _("security_group %s already present in container") % \
security_group['name']
raise exception.InvalidValue(msg)
compute_api.add_security_group(context, container, compute_api.add_security_group(context, container,
security_group['name']) security_group_id)
pecan.response.status = 202 pecan.response.status = 202
@pecan.expose('json') @pecan.expose('json')

View File

@@ -158,8 +158,13 @@ add_security_group = {
'type': 'string', 'type': 'string',
'minLength': 1, 'minLength': 1,
'maxLength': 255 'maxLength': 255
},
'uuid': {
'type': 'string',
'minLength': 2,
'maxLength': 255,
'pattern': '[a-zA-Z0-9][a-zA-Z0-9_.-]'
} }
}, },
'required': ['name'],
'additionalProperties': False 'additionalProperties': False
} }

View File

@@ -307,7 +307,7 @@ def get_security_group_ids(context, security_groups, **kwargs):
**search_opts).get('security_groups', []) **search_opts).get('security_groups', [])
security_group_ids = [item['id'] for item in security_groups_list security_group_ids = [item['id'] for item in security_groups_list
if item['name'] in security_groups] if item['name'] in security_groups]
if len(security_group_ids) == len(security_groups): if len(security_group_ids) >= len(security_groups):
return security_group_ids return security_group_ids
else: else:
raise exception.ZunException(_( raise exception.ZunException(_(

View File

@@ -756,14 +756,12 @@ class DockerDriver(driver.ContainerDriver):
return cpu_used return cpu_used
def add_security_group(self, context, container, security_group): def add_security_group(self, context, container, security_group):
security_group_ids = utils.get_security_group_ids(
context, [security_group])
with docker_utils.docker_client() as docker: with docker_utils.docker_client() as docker:
network_api = zun_network.api(context=context, network_api = zun_network.api(context=context,
docker_api=docker) docker_api=docker)
network_api.add_security_groups_to_ports(container, network_api.add_security_groups_to_ports(container,
security_group_ids) [security_group])
def get_available_nodes(self): def get_available_nodes(self):
return [self._host.get_hostname()] return [self._host.get_hostname()]

View File

@@ -1398,6 +1398,51 @@ class TestContainerController(api_base.FunctionalTest):
"security_group %s already present in container" % "security_group %s already present in container" %
default_security_group, response.json['errors'][0]['detail']) default_security_group, response.json['errors'][0]['detail'])
@mock.patch('zun.compute.api.API.add_security_group')
@mock.patch('zun.common.utils.list_ports')
@mock.patch('zun.api.utils.get_resource')
def test_add_security_group_by_uuid(self, mock_get_resource,
mock_list_ports,
mock_add_security_group):
test_container = utils.get_test_container()
test_container_obj = objects.Container(self.context, **test_container)
mock_get_resource.return_value = test_container_obj
mock_list_ports.return_value = \
[{'security_groups': ['fake_default_security_group_id']}]
container_name = test_container.get('name')
security_group_id_to_add = '5f7cf831-9a9c-4e2b-87b2-6081667f852b'
url = '/v1/containers/%s/%s?uuid=%s' % (container_name,
'add_security_group',
security_group_id_to_add)
response = self.app.post(url)
self.assertEqual(202, response.status_int)
self.assertEqual('application/json', response.content_type)
mock_add_security_group.assert_called_once_with(
mock.ANY, test_container_obj, security_group_id_to_add)
@mock.patch('zun.common.utils.get_security_group_ids')
@mock.patch('zun.common.utils.list_ports')
@mock.patch('zun.api.utils.get_resource')
def test_add_security_group_with_invalid_uuid(self, mock_get_resource,
mock_list_ports,
mock_get_security_group_ids):
test_container = utils.get_test_container()
test_container_obj = objects.Container(self.context, **test_container)
mock_get_resource.return_value = test_container_obj
mock_list_ports.return_value = \
[{'security_groups': test_container_obj.security_groups}]
container_name = test_container.get('name')
invalid_uuid = 'invalid_uuid'
url = '/v1/containers/%s/%s?uuid=%s' % (container_name,
'add_security_group',
invalid_uuid)
response = self.app.post(url, expect_errors=True)
self.assertEqual(400, response.status_int)
self.assertEqual('application/json', response.content_type)
self.assertEqual(
"Expected a uuid but received %(uuid)s." %
{'uuid': invalid_uuid}, response.json['errors'][0]['detail'])
class TestContainerEnforcement(api_base.FunctionalTest): class TestContainerEnforcement(api_base.FunctionalTest):