Port security-group-default-rules extension into v2.1
This patch port security-group-default-rules into v2.1. 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: I4d65993d6413160d2c7c2eb2ce0c3f66768e1a36
This commit is contained in:
parent
94b006e210
commit
c7d9924a08
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"security_group_default_rule": {
|
||||
"ip_protocol": "TCP",
|
||||
"from_port": "80",
|
||||
"to_port": "80",
|
||||
"cidr": "10.10.10.0/24"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"security_group_default_rule": {
|
||||
"from_port": 80,
|
||||
"id": 1,
|
||||
"ip_protocol": "TCP",
|
||||
"ip_range": {
|
||||
"cidr": "10.10.10.0/24"
|
||||
},
|
||||
"to_port": 80
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"security_group_default_rules": [
|
||||
{
|
||||
"from_port": 80,
|
||||
"id": 1,
|
||||
"ip_protocol": "TCP",
|
||||
"ip_range": {
|
||||
"cidr": "10.10.10.0/24"
|
||||
},
|
||||
"to_port": 80
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"security_group_default_rule": {
|
||||
"from_port": 80,
|
||||
"id": 1,
|
||||
"ip_protocol": "TCP",
|
||||
"ip_range": {
|
||||
"cidr": "10.10.10.0/24"
|
||||
},
|
||||
"to_port": 80
|
||||
}
|
||||
}
|
|
@ -242,6 +242,8 @@
|
|||
"compute_extension:v3:os-rescue:discoverable": "",
|
||||
"compute_extension:v3:os-scheduler-hints:discoverable": "",
|
||||
"compute_extension:security_group_default_rules": "rule:admin_api",
|
||||
"compute_extension:v3:os-security-group-default-rules:discoverable": "",
|
||||
"compute_extension:v3:os-security-group-default-rules": "rule:admin_api",
|
||||
"compute_extension:security_groups": "",
|
||||
"compute_extension:v3:os-security-groups": "",
|
||||
"compute_extension:v3:os-security-groups:discoverable": "",
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
# Copyright 2013 Metacloud Inc.
|
||||
#
|
||||
# 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 webob import exc
|
||||
|
||||
from nova.api.openstack.compute.plugins.v3 import security_groups as sg
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova.network.security_group import openstack_driver
|
||||
|
||||
|
||||
ALIAS = "os-security-group-default-rules"
|
||||
authorize = extensions.extension_authorizer('compute', 'v3:' + ALIAS)
|
||||
|
||||
|
||||
def _authorize_context(req):
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
return context
|
||||
|
||||
|
||||
class SecurityGroupDefaultRulesController(sg.SecurityGroupControllerBase):
|
||||
|
||||
def __init__(self):
|
||||
self.security_group_api = (
|
||||
openstack_driver.get_openstack_security_group_driver())
|
||||
|
||||
@extensions.expected_errors((400, 501))
|
||||
def create(self, req, body):
|
||||
context = sg._authorize_context(req)
|
||||
authorize(context)
|
||||
|
||||
sg_rule = self._from_body(body, 'security_group_default_rule')
|
||||
|
||||
try:
|
||||
values = self._rule_args_to_dict(to_port=sg_rule.get('to_port'),
|
||||
from_port=sg_rule.get('from_port'),
|
||||
ip_protocol=sg_rule.get('ip_protocol'),
|
||||
cidr=sg_rule.get('cidr'))
|
||||
except (exception.InvalidCidr,
|
||||
exception.InvalidInput,
|
||||
exception.InvalidIpProtocol,
|
||||
exception.InvalidPortRange) as ex:
|
||||
raise exc.HTTPBadRequest(explanation=ex.format_message())
|
||||
|
||||
if values is None:
|
||||
msg = _('Not enough parameters to build a valid rule.')
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
if self.security_group_api.default_rule_exists(context, values):
|
||||
msg = _('This default rule already exists.')
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
security_group_rule = self.security_group_api.add_default_rules(
|
||||
context, [values])[0]
|
||||
fmt_rule = self._format_security_group_default_rule(
|
||||
security_group_rule)
|
||||
return {'security_group_default_rule': fmt_rule}
|
||||
|
||||
def _rule_args_to_dict(self, to_port=None, from_port=None,
|
||||
ip_protocol=None, cidr=None):
|
||||
cidr = self.security_group_api.parse_cidr(cidr)
|
||||
return self.security_group_api.new_cidr_ingress_rule(
|
||||
cidr, ip_protocol, from_port, to_port)
|
||||
|
||||
@extensions.expected_errors((400, 404, 501))
|
||||
def show(self, req, id):
|
||||
context = sg._authorize_context(req)
|
||||
authorize(context)
|
||||
|
||||
try:
|
||||
id = self.security_group_api.validate_id(id)
|
||||
except exception.Invalid as ex:
|
||||
raise exc.HTTPBadRequest(explanation=ex.format_message())
|
||||
|
||||
try:
|
||||
rule = self.security_group_api.get_default_rule(context, id)
|
||||
except exception.SecurityGroupNotFound as ex:
|
||||
raise exc.HTTPNotFound(explanation=ex.format_message())
|
||||
|
||||
fmt_rule = self._format_security_group_default_rule(rule)
|
||||
return {"security_group_default_rule": fmt_rule}
|
||||
|
||||
@extensions.expected_errors((400, 404, 501))
|
||||
@wsgi.response(204)
|
||||
def delete(self, req, id):
|
||||
context = sg._authorize_context(req)
|
||||
authorize(context)
|
||||
|
||||
try:
|
||||
id = self.security_group_api.validate_id(id)
|
||||
except exception.Invalid as ex:
|
||||
raise exc.HTTPBadRequest(explanation=ex.format_message())
|
||||
|
||||
try:
|
||||
rule = self.security_group_api.get_default_rule(context, id)
|
||||
except exception.SecurityGroupNotFound as ex:
|
||||
raise exc.HTTPNotFound(explanation=ex.format_message())
|
||||
|
||||
try:
|
||||
self.security_group_api.remove_default_rules(context, [rule['id']])
|
||||
except exception.SecurityGroupDefaultRuleNotFound as ex:
|
||||
raise exc.HTTPNotFound(explanation=ex.format_message())
|
||||
|
||||
@extensions.expected_errors((404, 501))
|
||||
def index(self, req):
|
||||
|
||||
context = sg._authorize_context(req)
|
||||
authorize(context)
|
||||
|
||||
ret = {'security_group_default_rules': []}
|
||||
try:
|
||||
for rule in self.security_group_api.get_all_default_rules(context):
|
||||
rule_fmt = self._format_security_group_default_rule(rule)
|
||||
ret['security_group_default_rules'].append(rule_fmt)
|
||||
except exception.SecurityGroupDefaultRuleNotFound as ex:
|
||||
raise exc.HTTPNotFound(explanation=ex.format_message())
|
||||
|
||||
return ret
|
||||
|
||||
def _format_security_group_default_rule(self, rule):
|
||||
sg_rule = {}
|
||||
sg_rule['id'] = rule['id']
|
||||
sg_rule['ip_protocol'] = rule['protocol']
|
||||
sg_rule['from_port'] = rule['from_port']
|
||||
sg_rule['to_port'] = rule['to_port']
|
||||
sg_rule['ip_range'] = {}
|
||||
sg_rule['ip_range'] = {'cidr': rule['cidr']}
|
||||
return sg_rule
|
||||
|
||||
|
||||
class SecurityGroupDefaultRules(extensions.V3APIExtensionBase):
|
||||
"""Default rules for security group support."""
|
||||
name = "SecurityGroupDefaultRules"
|
||||
alias = ALIAS
|
||||
version = 1
|
||||
|
||||
def get_resources(self):
|
||||
resources = [
|
||||
extensions.ResourceExtension(ALIAS,
|
||||
SecurityGroupDefaultRulesController())]
|
||||
|
||||
return resources
|
||||
|
||||
def get_controller_extensions(self):
|
||||
return []
|
|
@ -16,7 +16,10 @@ from lxml import etree
|
|||
from oslo.config import cfg
|
||||
import webob
|
||||
|
||||
from nova.api.openstack.compute.contrib import security_group_default_rules
|
||||
from nova.api.openstack.compute.contrib import \
|
||||
security_group_default_rules as security_group_default_rules_v2
|
||||
from nova.api.openstack.compute.plugins.v3 import \
|
||||
security_group_default_rules as security_group_default_rules_v21
|
||||
from nova.api.openstack import wsgi
|
||||
from nova import context
|
||||
import nova.db
|
||||
|
@ -48,12 +51,14 @@ def security_group_default_rule_db(security_group_default_rule, id=None):
|
|||
return AttrDict(attrs)
|
||||
|
||||
|
||||
class TestSecurityGroupDefaultRulesNeutron(test.TestCase):
|
||||
class TestSecurityGroupDefaultRulesNeutronV21(test.TestCase):
|
||||
controller_cls = (security_group_default_rules_v21.
|
||||
SecurityGroupDefaultRulesController)
|
||||
|
||||
def setUp(self):
|
||||
self.flags(security_group_api='neutron')
|
||||
super(TestSecurityGroupDefaultRulesNeutron, self).setUp()
|
||||
self.controller = \
|
||||
security_group_default_rules.SecurityGroupDefaultRulesController()
|
||||
super(TestSecurityGroupDefaultRulesNeutronV21, self).setUp()
|
||||
self.controller = self.controller_cls()
|
||||
|
||||
def test_create_security_group_default_rule_not_implemented_neutron(self):
|
||||
sgr = security_group_default_rule_template()
|
||||
|
@ -81,11 +86,18 @@ class TestSecurityGroupDefaultRulesNeutron(test.TestCase):
|
|||
req, '602ed77c-a076-4f9b-a617-f93b847b62c5')
|
||||
|
||||
|
||||
class TestSecurityGroupDefaultRules(test.TestCase):
|
||||
class TestSecurityGroupDefaultRulesNeutronV2(test.TestCase):
|
||||
controller_cls = (security_group_default_rules_v2.
|
||||
SecurityGroupDefaultRulesController)
|
||||
|
||||
|
||||
class TestSecurityGroupDefaultRulesV21(test.TestCase):
|
||||
controller_cls = (security_group_default_rules_v21.
|
||||
SecurityGroupDefaultRulesController)
|
||||
|
||||
def setUp(self):
|
||||
super(TestSecurityGroupDefaultRules, self).setUp()
|
||||
self.controller = \
|
||||
security_group_default_rules.SecurityGroupDefaultRulesController()
|
||||
super(TestSecurityGroupDefaultRulesV21, self).setUp()
|
||||
self.controller = self.controller_cls()
|
||||
|
||||
def test_create_security_group_default_rule(self):
|
||||
sgr = security_group_default_rule_template()
|
||||
|
@ -323,10 +335,15 @@ class TestSecurityGroupDefaultRules(test.TestCase):
|
|||
self.assertEqual(sgr['cidr'], security_group_rule.cidr)
|
||||
|
||||
|
||||
class TestSecurityGroupDefaultRulesV2(test.TestCase):
|
||||
controller_cls = (security_group_default_rules_v2.
|
||||
SecurityGroupDefaultRulesController)
|
||||
|
||||
|
||||
class TestSecurityGroupDefaultRulesXMLDeserializer(test.TestCase):
|
||||
def setUp(self):
|
||||
super(TestSecurityGroupDefaultRulesXMLDeserializer, self).setUp()
|
||||
deserializer = security_group_default_rules.\
|
||||
deserializer = security_group_default_rules_v2.\
|
||||
SecurityGroupDefaultRulesXMLDeserializer()
|
||||
self.deserializer = deserializer
|
||||
|
||||
|
@ -423,9 +440,9 @@ class TestSecurityGroupDefaultRuleXMLSerializer(test.TestCase):
|
|||
super(TestSecurityGroupDefaultRuleXMLSerializer, self).setUp()
|
||||
self.namespace = wsgi.XMLNS_V11
|
||||
self.rule_serializer =\
|
||||
security_group_default_rules.SecurityGroupDefaultRuleTemplate()
|
||||
security_group_default_rules_v2.SecurityGroupDefaultRuleTemplate()
|
||||
self.index_serializer =\
|
||||
security_group_default_rules.SecurityGroupDefaultRulesTemplate()
|
||||
security_group_default_rules_v2.SecurityGroupDefaultRulesTemplate()
|
||||
|
||||
def _tag(self, elem):
|
||||
tagname = elem.tag
|
||||
|
|
|
@ -279,6 +279,7 @@ policy_data = """
|
|||
"compute_extension:rescue": "",
|
||||
"compute_extension:v3:os-rescue": "",
|
||||
"compute_extension:security_group_default_rules": "",
|
||||
"compute_extension:v3:os-security-group-default-rules": "",
|
||||
"compute_extension:security_groups": "",
|
||||
"compute_extension:v3:os-security-groups": "",
|
||||
"compute_extension:server_diagnostics": "",
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"security_group_default_rule": {
|
||||
"ip_protocol": "TCP",
|
||||
"from_port": "80",
|
||||
"to_port": "80",
|
||||
"cidr": "10.10.10.0/24"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"security_group_default_rule": {
|
||||
"from_port": 80,
|
||||
"id": 1,
|
||||
"ip_protocol": "TCP",
|
||||
"ip_range":{
|
||||
"cidr": "10.10.10.0/24"
|
||||
},
|
||||
"to_port": 80
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"security_group_default_rules": [
|
||||
{
|
||||
"from_port": 80,
|
||||
"id": 1,
|
||||
"ip_protocol": "TCP",
|
||||
"ip_range": {
|
||||
"cidr": "10.10.10.0/24"
|
||||
},
|
||||
"to_port": 80
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"security_group_default_rule": {
|
||||
"id": 1,
|
||||
"from_port": 80,
|
||||
"to_port": 80,
|
||||
"ip_protocol": "TCP",
|
||||
"ip_range": {
|
||||
"cidr": "10.10.10.0/24"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright 2014 IBM Corp.
|
||||
#
|
||||
# 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 nova.tests.integrated.v3 import api_sample_base
|
||||
|
||||
|
||||
class SecurityGroupDefaultRulesSampleJsonTest(
|
||||
api_sample_base.ApiSampleTestBaseV3):
|
||||
extension_name = 'os-security-group-default-rules'
|
||||
|
||||
def test_security_group_default_rules_create(self):
|
||||
response = self._do_post('os-security-group-default-rules',
|
||||
'security-group-default-rules-create-req',
|
||||
{})
|
||||
self._verify_response('security-group-default-rules-create-resp',
|
||||
{}, response, 200)
|
||||
|
||||
def test_security_group_default_rules_list(self):
|
||||
self.test_security_group_default_rules_create()
|
||||
response = self._do_get('os-security-group-default-rules')
|
||||
self._verify_response('security-group-default-rules-list-resp',
|
||||
{}, response, 200)
|
||||
|
||||
def test_security_group_default_rules_show(self):
|
||||
self.test_security_group_default_rules_create()
|
||||
rule_id = '1'
|
||||
response = self._do_get('os-security-group-default-rules/%s' % rule_id)
|
||||
self._verify_response('security-group-default-rules-show-resp',
|
||||
{}, response, 200)
|
|
@ -114,6 +114,7 @@ nova.api.v3.extensions =
|
|||
remote_consoles = nova.api.openstack.compute.plugins.v3.remote_consoles:RemoteConsoles
|
||||
rescue = nova.api.openstack.compute.plugins.v3.rescue:Rescue
|
||||
scheduler_hints = nova.api.openstack.compute.plugins.v3.scheduler_hints:SchedulerHints
|
||||
security_group_default_rules = nova.api.openstack.compute.plugins.v3.security_group_default_rules:SecurityGroupDefaultRules
|
||||
security_groups = nova.api.openstack.compute.plugins.v3.security_groups:SecurityGroups
|
||||
server_diagnostics = nova.api.openstack.compute.plugins.v3.server_diagnostics:ServerDiagnostics
|
||||
server_external_events = nova.api.openstack.compute.plugins.v3.server_external_events:ServerExternalEvents
|
||||
|
|
Loading…
Reference in New Issue