diff --git a/neutron/db/securitygroups_db.py b/neutron/db/securitygroups_db.py index 3336d892f20..a610d6d4899 100644 --- a/neutron/db/securitygroups_db.py +++ b/neutron/db/securitygroups_db.py @@ -46,9 +46,9 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): __native_bulk_support = True - def create_security_group_bulk(self, context, security_group_rule): + def create_security_group_bulk(self, context, security_groups): return self._create_bulk('security_group', context, - security_group_rule) + security_groups) def _registry_notify(self, res, event, id=None, exc_cls=None, **kwargs): # NOTE(armax): a callback exception here will prevent the request diff --git a/neutron/tests/tempest/api/test_security_groups.py b/neutron/tests/tempest/api/test_security_groups.py index a6009e4feea..4520ecc2a5f 100644 --- a/neutron/tests/tempest/api/test_security_groups.py +++ b/neutron/tests/tempest/api/test_security_groups.py @@ -53,3 +53,17 @@ class SecGroupTest(base.BaseSecGroupTest): self.assertEqual(show_body['security_group']['name'], new_name) self.assertEqual(show_body['security_group']['description'], new_description) + + @test.idempotent_id('7c0ecb10-b2db-11e6-9b14-000c29248b0d') + def test_create_bulk_sec_groups(self): + # Creates 2 sec-groups in one request + sec_nm = [data_utils.rand_name('secgroup'), + data_utils.rand_name('secgroup')] + body = self.client.create_bulk_security_groups(sec_nm) + created_sec_grps = body['security_groups'] + self.assertEqual(2, len(created_sec_grps)) + for secgrp in created_sec_grps: + self.addCleanup(self.client.delete_security_group, + secgrp['id']) + self.assertIn(secgrp['name'], sec_nm) + self.assertIsNotNone(secgrp['id']) diff --git a/neutron/tests/tempest/services/network/json/network_client.py b/neutron/tests/tempest/services/network/json/network_client.py index 6b71f0258a6..610b04998aa 100644 --- a/neutron/tests/tempest/services/network/json/network_client.py +++ b/neutron/tests/tempest/services/network/json/network_client.py @@ -251,6 +251,18 @@ class NetworkClientJSON(service_client.RestClient): self.expected_success(201, resp.status) return service_client.ResponseBody(resp, body) + def create_bulk_security_groups(self, security_group_list): + group_list = [{'security_group': {'name': name}} + for name in security_group_list] + post_data = {'security_groups': group_list} + body = self.serialize_list(post_data, 'security_groups', + 'security_group') + uri = self.get_uri("security-groups") + resp, body = self.post(uri, body) + body = {'security_groups': self.deserialize_list(body)} + self.expected_success(201, resp.status) + return service_client.ResponseBody(resp, body) + def wait_for_resource_deletion(self, resource_type, id): """Waits for a resource to be deleted.""" start_time = int(time.time()) diff --git a/neutron/tests/unit/extensions/test_securitygroup.py b/neutron/tests/unit/extensions/test_securitygroup.py index 187c7d3bf06..ed1c255239e 100644 --- a/neutron/tests/unit/extensions/test_securitygroup.py +++ b/neutron/tests/unit/extensions/test_securitygroup.py @@ -69,14 +69,16 @@ class SecurityGroupTestExtensionManager(object): class SecurityGroupsTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase): - def _create_security_group(self, fmt, name, description, **kwargs): - + def _build_security_group(self, name, description, **kwargs): data = { 'security_group': { 'name': name, - 'tenant_id': kwargs.get('tenant_id', - test_db_base_plugin_v2.TEST_TENANT_ID), + 'tenant_id': kwargs.get( + 'tenant_id', test_db_base_plugin_v2.TEST_TENANT_ID), 'description': description}} + return data + + def _create_security_group_response(self, fmt, data, **kwargs): security_group_req = self.new_create_request('security-groups', data, fmt) if (kwargs.get('set_context') and 'tenant_id' in kwargs): @@ -85,6 +87,10 @@ class SecurityGroupsTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase): context.Context('', kwargs['tenant_id'])) return security_group_req.get_response(self.ext_api) + def _create_security_group(self, fmt, name, description, **kwargs): + data = self._build_security_group(name, description, **kwargs) + return self._create_security_group_response(fmt, data, **kwargs) + def _build_security_group_rule( self, security_group_id, direction, proto, port_range_min=None, port_range_max=None, @@ -284,6 +290,16 @@ class TestSecurityGroups(SecurityGroupDBTestCase): 'port_range_min': None} self._assert_sg_rule_has_kvs(v6_rule, expected) + def test_create_security_group_bulk(self): + rule1 = self._build_security_group("sg_1", "sec_grp_1") + rule2 = self._build_security_group("sg_2", "sec_grp_2") + rules = {'security_groups': [rule1['security_group'], + rule2['security_group']]} + res = self._create_security_group_response(self.fmt, rules) + ret = self.deserialize(self.fmt, res) + self.assertEqual(webob.exc.HTTPCreated.code, res.status_int) + self.assertEqual(2, len(ret['security_groups'])) + def test_skip_duplicate_default_sg_error(self): num_called = [0] original_func = self.plugin.create_security_group