Porting SecurityGroup related controller into v2.1
This patch port SecurityGroup, ServerSecurityGroup and SecurityGroupAction controller into v2.1 security_groups extension. This patch just move the v2 code into v2.1 and share the unittest. The other v2.1 related fix and improvement will be addressed by subsequent patchset. Partially implements blueprint v2-on-v3-api Change-Id: I93951ce677b74ebed7db1b2fff1f788344806dba
This commit is contained in:
parent
45c2205ef1
commit
a9d446d627
@ -0,0 +1,5 @@
|
||||
{
|
||||
"addSecurityGroup": {
|
||||
"name": "test"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"security_group": {
|
||||
"name": "test",
|
||||
"description": "description"
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"removeSecurityGroup": {
|
||||
"name": "test"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"security_group": {
|
||||
"description": "default",
|
||||
"id": 1,
|
||||
"name": "default",
|
||||
"rules": [],
|
||||
"tenant_id": "openstack"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"security_group": {
|
||||
"description": "default",
|
||||
"id": 1,
|
||||
"name": "default",
|
||||
"rules": [],
|
||||
"tenant_id": "openstack"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"security_groups": [
|
||||
{
|
||||
"description": "default",
|
||||
"id": 1,
|
||||
"name": "default",
|
||||
"rules": [],
|
||||
"tenant_id": "openstack"
|
||||
}
|
||||
]
|
||||
}
|
@ -10,7 +10,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"created": "2013-09-25T03:29:13Z",
|
||||
"created": "2014-09-18T10:13:33Z",
|
||||
"flavor": {
|
||||
"id": "1",
|
||||
"links": [
|
||||
@ -20,8 +20,8 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"hostId": "0e312d6763795d572ccd716973fd078290d9ec446517b222d3395660",
|
||||
"id": "f6961f7a-0133-4f27-94cd-901dca4ba426",
|
||||
"hostId": "24451d49cba30e60300a5b928ebc93a2d0b43c084a677b0a14fd678b",
|
||||
"id": "b08eb8d8-db43-44fb-bd89-dfe3302b84ef",
|
||||
"image": {
|
||||
"id": "70a599e0-31e7-49b7-b260-868f441e862b",
|
||||
"links": [
|
||||
@ -34,11 +34,11 @@
|
||||
"key_name": null,
|
||||
"links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/v3/servers/f6961f7a-0133-4f27-94cd-901dca4ba426",
|
||||
"href": "http://openstack.example.com/v3/servers/b08eb8d8-db43-44fb-bd89-dfe3302b84ef",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://openstack.example.com/servers/f6961f7a-0133-4f27-94cd-901dca4ba426",
|
||||
"href": "http://openstack.example.com/servers/b08eb8d8-db43-44fb-bd89-dfe3302b84ef",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
@ -54,7 +54,7 @@
|
||||
],
|
||||
"status": "ACTIVE",
|
||||
"tenant_id": "openstack",
|
||||
"updated": "2013-09-25T03:29:14Z",
|
||||
"updated": "2014-09-18T10:13:34Z",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
||||
|
@ -8,4 +8,4 @@
|
||||
},
|
||||
"security_groups": [{"name": "test"}]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
{
|
||||
"server": {
|
||||
"adminPass": "ki8cbWeZdxH6",
|
||||
"id": "2dabdd93-ced7-4607-a542-2516de84e0e5",
|
||||
"adminPass": "xhS2khTdkRkT",
|
||||
"id": "60874907-c72b-4a01-805d-54c992510e47",
|
||||
"links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/v3/servers/2dabdd93-ced7-4607-a542-2516de84e0e5",
|
||||
"href": "http://openstack.example.com/v3/servers/60874907-c72b-4a01-805d-54c992510e47",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://openstack.example.com/servers/2dabdd93-ced7-4607-a542-2516de84e0e5",
|
||||
"href": "http://openstack.example.com/servers/60874907-c72b-4a01-805d-54c992510e47",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
@ -18,4 +18,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"security_groups": [
|
||||
{
|
||||
"description": "default",
|
||||
"id": 1,
|
||||
"name": "default",
|
||||
"rules": [],
|
||||
"tenant_id": "openstack"
|
||||
}
|
||||
]
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"created": "2013-09-25T03:29:11Z",
|
||||
"created": "2014-09-18T10:13:33Z",
|
||||
"flavor": {
|
||||
"id": "1",
|
||||
"links": [
|
||||
@ -21,8 +21,8 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"hostId": "afeeb125d4d37d0a2123e3144a20a6672fda5d4b6cb85ec193430d82",
|
||||
"id": "1b94e3fc-1b1c-431a-a077-6b280fb720ce",
|
||||
"hostId": "2ab794bccd321fe64f9f8b679266aa2c96825f467434bbdd71b09b1d",
|
||||
"id": "d182742c-6f20-479c-8e32-f79f9c9df6e3",
|
||||
"image": {
|
||||
"id": "70a599e0-31e7-49b7-b260-868f441e862b",
|
||||
"links": [
|
||||
@ -35,11 +35,11 @@
|
||||
"key_name": null,
|
||||
"links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/v3/servers/1b94e3fc-1b1c-431a-a077-6b280fb720ce",
|
||||
"href": "http://openstack.example.com/v3/servers/d182742c-6f20-479c-8e32-f79f9c9df6e3",
|
||||
"rel": "self"
|
||||
},
|
||||
{
|
||||
"href": "http://openstack.example.com/servers/1b94e3fc-1b1c-431a-a077-6b280fb720ce",
|
||||
"href": "http://openstack.example.com/servers/d182742c-6f20-479c-8e32-f79f9c9df6e3",
|
||||
"rel": "bookmark"
|
||||
}
|
||||
],
|
||||
@ -55,7 +55,7 @@
|
||||
],
|
||||
"status": "ACTIVE",
|
||||
"tenant_id": "openstack",
|
||||
"updated": "2013-09-25T03:29:12Z",
|
||||
"updated": "2014-09-18T10:13:34Z",
|
||||
"user_id": "fake"
|
||||
}
|
||||
]
|
||||
|
@ -15,9 +15,12 @@
|
||||
# under the License.
|
||||
|
||||
"""The security groups extension."""
|
||||
import contextlib
|
||||
|
||||
from oslo.serialization import jsonutils
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
from nova.api.openstack.compute.schemas.v3 import security_groups as \
|
||||
schema_security_groups
|
||||
from nova.api.openstack import extensions
|
||||
@ -25,10 +28,13 @@ from nova.api.openstack import wsgi
|
||||
from nova import compute
|
||||
from nova.compute import api as compute_api
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova.network.security_group import neutron_driver
|
||||
from nova.network.security_group import openstack_driver
|
||||
from nova.openstack.common import log as logging
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
ALIAS = 'os-security-groups'
|
||||
ATTRIBUTE_NAME = 'security_groups'
|
||||
authorize = extensions.extension_authorizer('compute', 'v3:' + ALIAS)
|
||||
@ -41,6 +47,263 @@ def _authorize_context(req):
|
||||
return context
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def translate_exceptions():
|
||||
"""Translate nova exceptions to http exceptions."""
|
||||
try:
|
||||
yield
|
||||
except exception.Invalid as exp:
|
||||
msg = exp.format_message()
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
except exception.SecurityGroupNotFound as exp:
|
||||
msg = exp.format_message()
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
except exception.InstanceNotFound as exp:
|
||||
msg = exp.format_message()
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
except exception.SecurityGroupLimitExceeded as exp:
|
||||
msg = exp.format_message()
|
||||
raise exc.HTTPForbidden(explanation=msg)
|
||||
except exception.NoUniqueMatch as exp:
|
||||
msg = exp.format_message()
|
||||
raise exc.HTTPConflict(explanation=msg)
|
||||
|
||||
|
||||
class SecurityGroupControllerBase(wsgi.Controller):
|
||||
"""Base class for Security Group controllers."""
|
||||
|
||||
def __init__(self):
|
||||
self.security_group_api = (
|
||||
openstack_driver.get_openstack_security_group_driver())
|
||||
self.compute_api = compute.API(
|
||||
security_group_api=self.security_group_api)
|
||||
|
||||
def _format_security_group_rule(self, context, rule, group_rule_data=None):
|
||||
"""Return a secuity group rule in desired API response format.
|
||||
|
||||
If group_rule_data is passed in that is used rather than querying
|
||||
for it.
|
||||
"""
|
||||
sg_rule = {}
|
||||
sg_rule['id'] = rule['id']
|
||||
sg_rule['parent_group_id'] = rule['parent_group_id']
|
||||
sg_rule['ip_protocol'] = rule['protocol']
|
||||
sg_rule['from_port'] = rule['from_port']
|
||||
sg_rule['to_port'] = rule['to_port']
|
||||
sg_rule['group'] = {}
|
||||
sg_rule['ip_range'] = {}
|
||||
if rule['group_id']:
|
||||
with translate_exceptions():
|
||||
try:
|
||||
source_group = self.security_group_api.get(
|
||||
context, id=rule['group_id'])
|
||||
except exception.SecurityGroupNotFound:
|
||||
# NOTE(arosen): There is a possible race condition that can
|
||||
# occur here if two api calls occur concurrently: one that
|
||||
# lists the security groups and another one that deletes a
|
||||
# security group rule that has a group_id before the
|
||||
# group_id is fetched. To handle this if
|
||||
# SecurityGroupNotFound is raised we return None instead
|
||||
# of the rule and the caller should ignore the rule.
|
||||
LOG.debug("Security Group ID %s does not exist",
|
||||
rule['group_id'])
|
||||
return
|
||||
sg_rule['group'] = {'name': source_group.get('name'),
|
||||
'tenant_id': source_group.get('project_id')}
|
||||
elif group_rule_data:
|
||||
sg_rule['group'] = group_rule_data
|
||||
else:
|
||||
sg_rule['ip_range'] = {'cidr': rule['cidr']}
|
||||
return sg_rule
|
||||
|
||||
def _format_security_group(self, context, group):
|
||||
security_group = {}
|
||||
security_group['id'] = group['id']
|
||||
security_group['description'] = group['description']
|
||||
security_group['name'] = group['name']
|
||||
security_group['tenant_id'] = group['project_id']
|
||||
security_group['rules'] = []
|
||||
for rule in group['rules']:
|
||||
formatted_rule = self._format_security_group_rule(context, rule)
|
||||
if formatted_rule:
|
||||
security_group['rules'] += [formatted_rule]
|
||||
return security_group
|
||||
|
||||
def _from_body(self, body, key):
|
||||
if not body:
|
||||
raise exc.HTTPBadRequest(
|
||||
explanation=_("The request body can't be empty"))
|
||||
value = body.get(key, None)
|
||||
if value is None:
|
||||
raise exc.HTTPBadRequest(
|
||||
explanation=_("Missing parameter %s") % key)
|
||||
return value
|
||||
|
||||
|
||||
class SecurityGroupController(SecurityGroupControllerBase):
|
||||
"""The Security group API controller for the OpenStack API."""
|
||||
|
||||
def show(self, req, id):
|
||||
"""Return data about the given security group."""
|
||||
context = _authorize_context(req)
|
||||
|
||||
with translate_exceptions():
|
||||
id = self.security_group_api.validate_id(id)
|
||||
security_group = self.security_group_api.get(context, None, id,
|
||||
map_exception=True)
|
||||
|
||||
return {'security_group': self._format_security_group(context,
|
||||
security_group)}
|
||||
|
||||
@wsgi.response(202)
|
||||
def delete(self, req, id):
|
||||
"""Delete a security group."""
|
||||
context = _authorize_context(req)
|
||||
|
||||
with translate_exceptions():
|
||||
id = self.security_group_api.validate_id(id)
|
||||
security_group = self.security_group_api.get(context, None, id,
|
||||
map_exception=True)
|
||||
self.security_group_api.destroy(context, security_group)
|
||||
|
||||
def index(self, req):
|
||||
"""Returns a list of security groups."""
|
||||
context = _authorize_context(req)
|
||||
|
||||
search_opts = {}
|
||||
search_opts.update(req.GET)
|
||||
|
||||
with translate_exceptions():
|
||||
project_id = context.project_id
|
||||
raw_groups = self.security_group_api.list(context,
|
||||
project=project_id,
|
||||
search_opts=search_opts)
|
||||
|
||||
limited_list = common.limited(raw_groups, req)
|
||||
result = [self._format_security_group(context, group)
|
||||
for group in limited_list]
|
||||
|
||||
return {'security_groups':
|
||||
list(sorted(result,
|
||||
key=lambda k: (k['tenant_id'], k['name'])))}
|
||||
|
||||
def create(self, req, body):
|
||||
"""Creates a new security group."""
|
||||
context = _authorize_context(req)
|
||||
|
||||
security_group = self._from_body(body, 'security_group')
|
||||
|
||||
group_name = security_group.get('name', None)
|
||||
group_description = security_group.get('description', None)
|
||||
|
||||
with translate_exceptions():
|
||||
self.security_group_api.validate_property(group_name, 'name', None)
|
||||
self.security_group_api.validate_property(group_description,
|
||||
'description', None)
|
||||
group_ref = self.security_group_api.create_security_group(
|
||||
context, group_name, group_description)
|
||||
|
||||
return {'security_group': self._format_security_group(context,
|
||||
group_ref)}
|
||||
|
||||
def update(self, req, id, body):
|
||||
"""Update a security group."""
|
||||
context = _authorize_context(req)
|
||||
|
||||
with translate_exceptions():
|
||||
id = self.security_group_api.validate_id(id)
|
||||
security_group = self.security_group_api.get(context, None, id,
|
||||
map_exception=True)
|
||||
|
||||
security_group_data = self._from_body(body, 'security_group')
|
||||
group_name = security_group_data.get('name', None)
|
||||
group_description = security_group_data.get('description', None)
|
||||
|
||||
with translate_exceptions():
|
||||
self.security_group_api.validate_property(group_name, 'name', None)
|
||||
self.security_group_api.validate_property(group_description,
|
||||
'description', None)
|
||||
group_ref = self.security_group_api.update_security_group(
|
||||
context, security_group, group_name, group_description)
|
||||
|
||||
return {'security_group': self._format_security_group(context,
|
||||
group_ref)}
|
||||
|
||||
|
||||
class ServerSecurityGroupController(SecurityGroupControllerBase):
|
||||
|
||||
def index(self, req, server_id):
|
||||
"""Returns a list of security groups for the given instance."""
|
||||
context = _authorize_context(req)
|
||||
|
||||
self.security_group_api.ensure_default(context)
|
||||
|
||||
with translate_exceptions():
|
||||
instance = self.compute_api.get(context, server_id)
|
||||
groups = self.security_group_api.get_instance_security_groups(
|
||||
context, instance['uuid'], True)
|
||||
|
||||
result = [self._format_security_group(context, group)
|
||||
for group in groups]
|
||||
|
||||
return {'security_groups':
|
||||
list(sorted(result,
|
||||
key=lambda k: (k['tenant_id'], k['name'])))}
|
||||
|
||||
|
||||
class SecurityGroupActionController(wsgi.Controller):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SecurityGroupActionController, self).__init__(*args, **kwargs)
|
||||
self.security_group_api = (
|
||||
openstack_driver.get_openstack_security_group_driver())
|
||||
self.compute_api = compute.API(
|
||||
security_group_api=self.security_group_api)
|
||||
|
||||
def _parse(self, body, action):
|
||||
try:
|
||||
body = body[action]
|
||||
group_name = body['name']
|
||||
except TypeError:
|
||||
msg = _("Missing parameter dict")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
except KeyError:
|
||||
msg = _("Security group not specified")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
if not group_name or group_name.strip() == '':
|
||||
msg = _("Security group name cannot be empty")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
return group_name
|
||||
|
||||
def _invoke(self, method, context, id, group_name):
|
||||
with translate_exceptions():
|
||||
instance = self.compute_api.get(context, id)
|
||||
method(context, instance, group_name)
|
||||
|
||||
@wsgi.response(202)
|
||||
@wsgi.action('addSecurityGroup')
|
||||
def _addSecurityGroup(self, req, id, body):
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
|
||||
group_name = self._parse(body, 'addSecurityGroup')
|
||||
|
||||
return self._invoke(self.security_group_api.add_to_instance,
|
||||
context, id, group_name)
|
||||
|
||||
@wsgi.response(202)
|
||||
@wsgi.action('removeSecurityGroup')
|
||||
def _removeSecurityGroup(self, req, id, body):
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
|
||||
group_name = self._parse(body, 'removeSecurityGroup')
|
||||
|
||||
return self._invoke(self.security_group_api.remove_from_instance,
|
||||
context, id, group_name)
|
||||
|
||||
|
||||
class SecurityGroupsOutputController(wsgi.Controller):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SecurityGroupsOutputController, self).__init__(*args, **kwargs)
|
||||
@ -115,12 +378,20 @@ class SecurityGroups(extensions.V3APIExtensionBase):
|
||||
version = 1
|
||||
|
||||
def get_controller_extensions(self):
|
||||
controller = SecurityGroupsOutputController()
|
||||
output = extensions.ControllerExtension(self, 'servers', controller)
|
||||
return [output]
|
||||
secgrp_output_ext = extensions.ControllerExtension(
|
||||
self, 'servers', SecurityGroupsOutputController())
|
||||
secgrp_act_ext = extensions.ControllerExtension(
|
||||
self, 'servers', SecurityGroupActionController())
|
||||
return [secgrp_output_ext, secgrp_act_ext]
|
||||
|
||||
def get_resources(self):
|
||||
return []
|
||||
secgrp_ext = extensions.ResourceExtension('os-security-groups',
|
||||
SecurityGroupController())
|
||||
server_secgrp_ext = extensions.ResourceExtension(
|
||||
'os-security-groups',
|
||||
controller=ServerSecurityGroupController(),
|
||||
parent=dict(member_name='server', collection_name='servers'))
|
||||
return [secgrp_ext, server_secgrp_ext]
|
||||
|
||||
# NOTE(gmann): This function is not supposed to use 'body_deprecated_param'
|
||||
# parameter as this is placed to handle scheduler_hint extension for V2.1.
|
||||
|
@ -51,8 +51,8 @@ class TestNeutronSecurityGroupsTestCase(test.TestCase):
|
||||
super(TestNeutronSecurityGroupsTestCase, self).tearDown()
|
||||
|
||||
|
||||
class TestNeutronSecurityGroups(
|
||||
test_security_groups.TestSecurityGroups,
|
||||
class TestNeutronSecurityGroupsV21(
|
||||
test_security_groups.TestSecurityGroupsV21,
|
||||
TestNeutronSecurityGroupsTestCase):
|
||||
|
||||
def _create_sg_template(self, **kwargs):
|
||||
@ -400,6 +400,12 @@ class TestNeutronSecurityGroups(
|
||||
device_id=test_security_groups.FAKE_UUID1)
|
||||
|
||||
|
||||
class TestNeutronSecurityGroupsV2(TestNeutronSecurityGroupsV21):
|
||||
controller_cls = security_groups.SecurityGroupController
|
||||
server_secgrp_ctl_cls = security_groups.ServerSecurityGroupController
|
||||
secgrp_act_ctl_cls = security_groups.SecurityGroupActionController
|
||||
|
||||
|
||||
class TestNeutronSecurityGroupRulesTestCase(TestNeutronSecurityGroupsTestCase):
|
||||
def setUp(self):
|
||||
super(TestNeutronSecurityGroupRulesTestCase, self).setUp()
|
||||
|
@ -21,6 +21,8 @@ from oslo.serialization import jsonutils
|
||||
import webob
|
||||
|
||||
from nova.api.openstack.compute.contrib import security_groups as secgroups_v2
|
||||
from nova.api.openstack.compute.plugins.v3 import security_groups as \
|
||||
secgroups_v21
|
||||
from nova.api.openstack import wsgi
|
||||
from nova.api.openstack import xmlutil
|
||||
from nova import compute
|
||||
@ -121,17 +123,17 @@ def return_server_nonexistent(context, server_id, columns_to_join=None):
|
||||
raise exception.InstanceNotFound(instance_id=server_id)
|
||||
|
||||
|
||||
# NOTE(oomichi): v2.1 API does not support security group management (create/
|
||||
# update/delete a security group). We don't need to test this class against
|
||||
# v2.1 API.
|
||||
class TestSecurityGroups(test.TestCase):
|
||||
def setUp(self):
|
||||
super(TestSecurityGroups, self).setUp()
|
||||
class TestSecurityGroupsV21(test.TestCase):
|
||||
secgrp_ctl_cls = secgroups_v21.SecurityGroupController
|
||||
server_secgrp_ctl_cls = secgroups_v21.ServerSecurityGroupController
|
||||
secgrp_act_ctl_cls = secgroups_v21.SecurityGroupActionController
|
||||
|
||||
self.controller = secgroups_v2.SecurityGroupController()
|
||||
self.server_controller = (
|
||||
secgroups_v2.ServerSecurityGroupController())
|
||||
self.manager = secgroups_v2.SecurityGroupActionController()
|
||||
def setUp(self):
|
||||
super(TestSecurityGroupsV21, self).setUp()
|
||||
|
||||
self.controller = self.secgrp_ctl_cls()
|
||||
self.server_controller = self.server_secgrp_ctl_cls()
|
||||
self.manager = self.secgrp_act_ctl_cls()
|
||||
|
||||
# This needs to be done here to set fake_id because the derived
|
||||
# class needs to be called first if it wants to set
|
||||
@ -807,6 +809,12 @@ class TestSecurityGroups(test.TestCase):
|
||||
self.manager._removeSecurityGroup(req, '1', body)
|
||||
|
||||
|
||||
class TestSecurityGroupsV2(TestSecurityGroupsV21):
|
||||
controller_cls = secgroups_v2.SecurityGroupController
|
||||
server_secgrp_ctl_cls = secgroups_v2.ServerSecurityGroupController
|
||||
secgrp_act_ctl_cls = secgroups_v2.SecurityGroupActionController
|
||||
|
||||
|
||||
# NOTE(oomichi): v2.1 API does not support security group management (create/
|
||||
# update/delete a security group). We don't need to test this class against
|
||||
# v2.1 API.
|
||||
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"addSecurityGroup": {
|
||||
"name": "%(group_name)s"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"security_group": {
|
||||
"name": "%(group_name)s",
|
||||
"description": "description"
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"removeSecurityGroup": {
|
||||
"name": "%(group_name)s"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"security_group": {
|
||||
"description": "%(description)s",
|
||||
"id": 1,
|
||||
"name": "%(group_name)s",
|
||||
"rules": [],
|
||||
"tenant_id": "openstack"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"security_group": {
|
||||
"description": "default",
|
||||
"id": 1,
|
||||
"name": "default",
|
||||
"rules": [],
|
||||
"tenant_id": "openstack"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"security_groups": [
|
||||
{
|
||||
"description": "default",
|
||||
"id": 1,
|
||||
"name": "default",
|
||||
"rules": [],
|
||||
"tenant_id": "openstack"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"security_groups": [
|
||||
{
|
||||
"description": "default",
|
||||
"id": 1,
|
||||
"name": "default",
|
||||
"rules": [],
|
||||
"tenant_id": "openstack"
|
||||
}
|
||||
]
|
||||
}
|
@ -19,21 +19,44 @@ from nova.tests.integrated.v3 import test_servers
|
||||
|
||||
def fake_get(*args, **kwargs):
|
||||
nova_group = {}
|
||||
nova_group['id'] = 'fake'
|
||||
nova_group['description'] = ''
|
||||
nova_group['name'] = 'test'
|
||||
nova_group['project_id'] = 'fake'
|
||||
nova_group['id'] = 1
|
||||
nova_group['description'] = 'default'
|
||||
nova_group['name'] = 'default'
|
||||
nova_group['project_id'] = 'openstack'
|
||||
nova_group['rules'] = []
|
||||
return nova_group
|
||||
|
||||
|
||||
def fake_get_instances_security_groups_bindings(self, context, servers):
|
||||
def fake_get_instances_security_groups_bindings(self, context, servers,
|
||||
detailed=False):
|
||||
result = {}
|
||||
for s in servers:
|
||||
result[s.get('id')] = [{'name': 'test'}]
|
||||
return result
|
||||
|
||||
|
||||
def fake_add_to_instance(self, context, instance, security_group_name):
|
||||
pass
|
||||
|
||||
|
||||
def fake_remove_from_instance(self, context, instance, security_group_name):
|
||||
pass
|
||||
|
||||
|
||||
def fake_list(self, context, names=None, ids=None, project=None,
|
||||
search_opts=None):
|
||||
return [fake_get()]
|
||||
|
||||
|
||||
def fake_get_instance_security_groups(self, context, instance_uuid,
|
||||
detailed=False):
|
||||
return [fake_get()]
|
||||
|
||||
|
||||
def fake_create_security_group(self, context, name, description):
|
||||
return fake_get()
|
||||
|
||||
|
||||
class SecurityGroupsJsonTest(test_servers.ServersSampleBase):
|
||||
extension_name = 'os-security-groups'
|
||||
|
||||
@ -44,6 +67,21 @@ class SecurityGroupsJsonTest(test_servers.ServersSampleBase):
|
||||
self.stubs.Set(neutron_driver.SecurityGroupAPI,
|
||||
'get_instances_security_groups_bindings',
|
||||
fake_get_instances_security_groups_bindings)
|
||||
self.stubs.Set(neutron_driver.SecurityGroupAPI,
|
||||
'add_to_instance',
|
||||
fake_add_to_instance)
|
||||
self.stubs.Set(neutron_driver.SecurityGroupAPI,
|
||||
'remove_from_instance',
|
||||
fake_remove_from_instance)
|
||||
self.stubs.Set(neutron_driver.SecurityGroupAPI,
|
||||
'list',
|
||||
fake_list)
|
||||
self.stubs.Set(neutron_driver.SecurityGroupAPI,
|
||||
'get_instance_security_groups',
|
||||
fake_get_instance_security_groups)
|
||||
self.stubs.Set(neutron_driver.SecurityGroupAPI,
|
||||
'create_security_group',
|
||||
fake_create_security_group)
|
||||
|
||||
def test_server_create(self):
|
||||
self._post_server()
|
||||
@ -61,3 +99,68 @@ class SecurityGroupsJsonTest(test_servers.ServersSampleBase):
|
||||
subs = self._get_regexes()
|
||||
subs['hostid'] = '[a-f0-9]+'
|
||||
self._verify_response('servers-detail-resp', subs, response, 200)
|
||||
|
||||
def _get_create_subs(self):
|
||||
return {
|
||||
'group_name': 'default',
|
||||
"description": "default",
|
||||
}
|
||||
|
||||
def _create_security_group(self):
|
||||
subs = self._get_create_subs()
|
||||
return self._do_post('os-security-groups',
|
||||
'security-group-post-req', subs)
|
||||
|
||||
def _add_group(self, uuid):
|
||||
subs = {
|
||||
'group_name': 'test'
|
||||
}
|
||||
return self._do_post('servers/%s/action' % uuid,
|
||||
'security-group-add-post-req', subs)
|
||||
|
||||
def test_security_group_create(self):
|
||||
response = self._create_security_group()
|
||||
subs = self._get_create_subs()
|
||||
self._verify_response('security-groups-create-resp', subs,
|
||||
response, 200)
|
||||
|
||||
def test_security_groups_list(self):
|
||||
# Get api sample of security groups get list request.
|
||||
response = self._do_get('os-security-groups')
|
||||
subs = self._get_regexes()
|
||||
self._verify_response('security-groups-list-get-resp',
|
||||
subs, response, 200)
|
||||
|
||||
def test_security_groups_get(self):
|
||||
# Get api sample of security groups get request.
|
||||
security_group_id = '11111111-1111-1111-1111-111111111111'
|
||||
response = self._do_get('os-security-groups/%s' % security_group_id)
|
||||
subs = self._get_regexes()
|
||||
self._verify_response('security-groups-get-resp', subs, response, 200)
|
||||
|
||||
def test_security_groups_list_server(self):
|
||||
# Get api sample of security groups for a specific server.
|
||||
uuid = self._post_server()
|
||||
response = self._do_get('servers/%s/os-security-groups' % uuid)
|
||||
subs = self._get_regexes()
|
||||
self._verify_response('server-security-groups-list-resp',
|
||||
subs, response, 200)
|
||||
|
||||
def test_security_groups_add(self):
|
||||
self._create_security_group()
|
||||
uuid = self._post_server()
|
||||
response = self._add_group(uuid)
|
||||
self.assertEqual(response.status_code, 202)
|
||||
self.assertEqual(response.content, '')
|
||||
|
||||
def test_security_groups_remove(self):
|
||||
self._create_security_group()
|
||||
uuid = self._post_server()
|
||||
self._add_group(uuid)
|
||||
subs = {
|
||||
'group_name': 'test'
|
||||
}
|
||||
response = self._do_post('servers/%s/action' % uuid,
|
||||
'security-group-remove-post-req', subs)
|
||||
self.assertEqual(response.status_code, 202)
|
||||
self.assertEqual(response.content, '')
|
||||
|
Loading…
x
Reference in New Issue
Block a user