Default SG rules for the Security Group "Default"
Added in the API os-security-group-default-rules This allows create, delete, list, and get (of individual rules) for rules that will be pre-populated into the Security Group "default" that is populated in all projects on creation. These rules will not be applied retroactively, as it is designed to allow the creation of a "reasonable" base-line set of sg rules. The new rules live in a separate table that mirrors the relevant structures of the security_group_rules table. Added unit tests/API samples for the new API calls Related to bp default-rules-for-default-security-group DocImpact Change-Id: I7ab51e68aff562bb869538197a0eca158fc3220c
This commit is contained in:
parent
30c2a8f66e
commit
59aaf1dff9
@ -384,6 +384,14 @@
|
||||
"namespace": "http://docs.openstack.org/compute/ext/rescue/api/v1.1",
|
||||
"updated": "2011-08-18T00:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"alias": "os-security-group-default-rules",
|
||||
"description": "Default rules for security group support.",
|
||||
"links": [],
|
||||
"name": "SecurityGroupDefaultRules",
|
||||
"namespace": "http://docs.openstack.org/compute/ext/securitygroupdefaultrules/api/v1.1",
|
||||
"updated": "2013-02-05T00:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"alias": "os-security-groups",
|
||||
"description": "Security group support.",
|
||||
|
@ -162,6 +162,9 @@
|
||||
<extension alias="os-rescue" updated="2011-08-18T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/rescue/api/v1.1" name="Rescue">
|
||||
<description>Instance rescue mode.</description>
|
||||
</extension>
|
||||
<extension alias="os-security-group-default-rules" updated="2013-02-05T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/securitygroupdefaultrules/api/v1.1" name="SecurityGroupDefaultRules">
|
||||
<description>Default rules for security group support.</description>
|
||||
</extension>
|
||||
<extension alias="os-security-groups" updated="2011-07-21T00:00:00+00:00" namespace="http://docs.openstack.org/compute/ext/securitygroups/api/v1.1" name="SecurityGroups">
|
||||
<description>Security group support.</description>
|
||||
</extension>
|
||||
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"security_group_default_rule": {
|
||||
"ip_protocol": "TCP",
|
||||
"from_port": "80",
|
||||
"to_port": "80",
|
||||
"cidr": "10.10.12.0/24"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<security_group_default_rule>
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<from_port>80</from_port>
|
||||
<to_port>80</to_port>
|
||||
<cidr>10.10.12.0/24</cidr>
|
||||
</security_group_default_rule>
|
@ -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,9 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<security_group_default_rule xmlns="http://docs.openstack.org/compute/api/v1.1" id="1">
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<from_port>80</from_port>
|
||||
<to_port>80</to_port>
|
||||
<ip_range>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</ip_range>
|
||||
</security_group_default_rule>
|
@ -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 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<security_group_default_rules xmlns="http://docs.openstack.org/compute/api/v1.1">
|
||||
<security_group_default_rule id="1">
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<from_port>80</from_port>
|
||||
<to_port>80</to_port>
|
||||
<ip_range>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</ip_range>
|
||||
</security_group_default_rule>
|
||||
</security_group_default_rules>
|
@ -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,9 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<security_group_default_rule xmlns="http://docs.openstack.org/compute/api/v1.1" id="1">
|
||||
<from_port>80</from_port>
|
||||
<to_port>80</to_port>
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<ip_range>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</ip_range>
|
||||
</security_group_default_rule>
|
@ -78,6 +78,7 @@
|
||||
"compute_extension:quotas:update": "rule:admin_api",
|
||||
"compute_extension:quota_classes": "",
|
||||
"compute_extension:rescue": "",
|
||||
"compute_extension:security_group_default_rules": "rule:admin_api",
|
||||
"compute_extension:security_groups": "",
|
||||
"compute_extension:server_diagnostics": "rule:admin_api",
|
||||
"compute_extension:server_password": "",
|
||||
|
@ -0,0 +1,210 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# 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 xml.dom import minidom
|
||||
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack.compute.contrib import security_groups as sg
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from nova.api.openstack import xmlutil
|
||||
from nova import exception
|
||||
from nova.openstack.common import log as logging
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
authorize = extensions.extension_authorizer('compute',
|
||||
'security_group_default_rules')
|
||||
|
||||
sg_nsmap = {None: wsgi.XMLNS_V11}
|
||||
|
||||
|
||||
def make_default_rule(elem):
|
||||
elem.set('id')
|
||||
|
||||
proto = xmlutil.SubTemplateElement(elem, 'ip_protocol')
|
||||
proto.text = 'ip_protocol'
|
||||
|
||||
from_port = xmlutil.SubTemplateElement(elem, 'from_port')
|
||||
from_port.text = 'from_port'
|
||||
|
||||
to_port = xmlutil.SubTemplateElement(elem, 'to_port')
|
||||
to_port.text = 'to_port'
|
||||
|
||||
ip_range = xmlutil.SubTemplateElement(elem, 'ip_range',
|
||||
selector='ip_range')
|
||||
cidr = xmlutil.SubTemplateElement(ip_range, 'cidr')
|
||||
cidr.text = 'cidr'
|
||||
|
||||
|
||||
class SecurityGroupDefaultRulesTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('security_group_default_rules')
|
||||
elem = xmlutil.SubTemplateElement(root, 'security_group_default_rule',
|
||||
selector='security_group_default_rules')
|
||||
|
||||
make_default_rule(elem)
|
||||
return xmlutil.MasterTemplate(root, 1, nsmap=sg_nsmap)
|
||||
|
||||
|
||||
class SecurityGroupDefaultRuleTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('security_group_default_rule',
|
||||
selector='security_group_default_rule')
|
||||
make_default_rule(root)
|
||||
return xmlutil.MasterTemplate(root, 1, nsmap=sg_nsmap)
|
||||
|
||||
|
||||
class SecurityGroupDefaultRulesXMLDeserializer(wsgi.MetadataXMLDeserializer):
|
||||
def default(self, string):
|
||||
dom = minidom.parseString(string)
|
||||
security_group_rule = self._extract_security_group_default_rule(dom)
|
||||
return {'body': {'security_group_default_rule': security_group_rule}}
|
||||
|
||||
def _extract_security_group_default_rule(self, node):
|
||||
sg_rule = {}
|
||||
sg_rule_node = self.find_first_child_named(node,
|
||||
'security_group_default_rule')
|
||||
if sg_rule_node is not None:
|
||||
ip_protocol_node = self.find_first_child_named(sg_rule_node,
|
||||
"ip_protocol")
|
||||
if ip_protocol_node is not None:
|
||||
sg_rule['ip_protocol'] = self.extract_text(ip_protocol_node)
|
||||
|
||||
from_port_node = self.find_first_child_named(sg_rule_node,
|
||||
"from_port")
|
||||
if from_port_node is not None:
|
||||
sg_rule['from_port'] = self.extract_text(from_port_node)
|
||||
|
||||
to_port_node = self.find_first_child_named(sg_rule_node, "to_port")
|
||||
if to_port_node is not None:
|
||||
sg_rule['to_port'] = self.extract_text(to_port_node)
|
||||
|
||||
cidr_node = self.find_first_child_named(sg_rule_node, "cidr")
|
||||
if cidr_node is not None:
|
||||
sg_rule['cidr'] = self.extract_text(cidr_node)
|
||||
|
||||
return sg_rule
|
||||
|
||||
|
||||
class SecurityGroupDefaultRulesController(sg.SecurityGroupControllerBase):
|
||||
|
||||
@wsgi.serializers(xml=SecurityGroupDefaultRuleTemplate)
|
||||
@wsgi.deserializers(xml=SecurityGroupDefaultRulesXMLDeserializer)
|
||||
def create(self, req, body):
|
||||
context = self._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 as exp:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(exp))
|
||||
|
||||
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)
|
||||
|
||||
@wsgi.serializers(xml=SecurityGroupDefaultRuleTemplate)
|
||||
def show(self, req, id):
|
||||
context = self._authorize_context(req)
|
||||
authorize(context)
|
||||
|
||||
id = self._validate_id(id)
|
||||
LOG.debug(_("Showing security_group_default_rule with id %s") % id)
|
||||
try:
|
||||
rule = self.security_group_api.get_default_rule(context, id)
|
||||
except exception.SecurityGroupDefaultRuleNotFound:
|
||||
raise exc.HTTPNotFound(_("security group default rule not found"))
|
||||
|
||||
fmt_rule = self._format_security_group_default_rule(rule)
|
||||
return {"security_group_default_rule": fmt_rule}
|
||||
|
||||
def delete(self, req, id):
|
||||
context = self._authorize_context(req)
|
||||
authorize(context)
|
||||
|
||||
id = self._validate_id(id)
|
||||
|
||||
rule = self.security_group_api.get_default_rule(context, id)
|
||||
|
||||
self.security_group_api.remove_default_rules(context, [rule['id']])
|
||||
|
||||
return webob.Response(status_int=204)
|
||||
|
||||
@wsgi.serializers(xml=SecurityGroupDefaultRulesTemplate)
|
||||
def index(self, req):
|
||||
|
||||
context = self._authorize_context(req)
|
||||
authorize(context)
|
||||
|
||||
ret = {'security_group_default_rules': []}
|
||||
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)
|
||||
|
||||
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 Security_group_default_rules(extensions.ExtensionDescriptor):
|
||||
"""Default rules for security group support."""
|
||||
name = "SecurityGroupDefaultRules"
|
||||
alias = "os-security-group-default-rules"
|
||||
namespace = ("http://docs.openstack.org/compute/ext/"
|
||||
"securitygroupdefaultrules/api/v1.1")
|
||||
updated = "2013-02-05T00:00:00+00:00"
|
||||
|
||||
def get_resources(self):
|
||||
resources = [
|
||||
extensions.ResourceExtension('os-security-group-default-rules',
|
||||
SecurityGroupDefaultRulesController(),
|
||||
collection_actions={'create': 'POST',
|
||||
'delete': 'DELETE',
|
||||
'index': 'GET'},
|
||||
member_actions={'show': 'GET'})]
|
||||
|
||||
return resources
|
@ -3128,6 +3128,46 @@ class SecurityGroupAPI(base.Base):
|
||||
self.trigger_rules_refresh(context, id=security_group['id'])
|
||||
self.trigger_handler('security_group_rule_destroy', context, rule_ids)
|
||||
|
||||
def remove_default_rules(self, context, rule_ids):
|
||||
for rule_id in rule_ids:
|
||||
self.db.security_group_default_rule_destroy(context, rule_id)
|
||||
|
||||
def add_default_rules(self, context, vals):
|
||||
rules = [self.db.security_group_default_rule_create(context, v)
|
||||
for v in vals]
|
||||
return rules
|
||||
|
||||
def default_rule_exists(self, context, values):
|
||||
"""Indicates whether the specified rule values are already
|
||||
defined in the default security group rules.
|
||||
"""
|
||||
for rule in self.db.security_group_default_rule_list(context):
|
||||
is_duplicate = True
|
||||
keys = ('cidr', 'from_port', 'to_port', 'protocol')
|
||||
for key in keys:
|
||||
if rule.get(key) != values.get(key):
|
||||
is_duplicate = False
|
||||
break
|
||||
if is_duplicate:
|
||||
return rule.get('id') or True
|
||||
return False
|
||||
|
||||
def get_all_default_rules(self, context):
|
||||
try:
|
||||
rules = self.db.security_group_default_rule_list(context)
|
||||
except Exception:
|
||||
msg = 'cannot get default security group rules'
|
||||
raise exception.SecurityGroupDefaultRuleNotFound(msg)
|
||||
|
||||
return rules
|
||||
|
||||
def get_default_rule(self, context, id):
|
||||
try:
|
||||
return self.db.security_group_default_rule_get(context, id)
|
||||
except exception.NotFound:
|
||||
msg = _("Rule (%s) not found") % id
|
||||
self.raise_not_found(msg)
|
||||
|
||||
@staticmethod
|
||||
def raise_invalid_property(msg):
|
||||
raise NotImplementedError()
|
||||
|
@ -1206,6 +1206,28 @@ def security_group_rule_count_by_group(context, security_group_id):
|
||||
###################
|
||||
|
||||
|
||||
def security_group_default_rule_get(context, security_group_rule_default_id):
|
||||
return IMPL.security_group_default_rule_get(context,
|
||||
security_group_rule_default_id)
|
||||
|
||||
|
||||
def security_group_default_rule_destroy(context,
|
||||
security_group_rule_default_id):
|
||||
return IMPL.security_group_default_rule_destroy(
|
||||
context, security_group_rule_default_id)
|
||||
|
||||
|
||||
def security_group_default_rule_create(context, values):
|
||||
return IMPL.security_group_default_rule_create(context, values)
|
||||
|
||||
|
||||
def security_group_default_rule_list(context):
|
||||
return IMPL.security_group_default_rule_list(context)
|
||||
|
||||
|
||||
###################
|
||||
|
||||
|
||||
def provider_fw_rule_create(context, rule):
|
||||
"""Add a firewall rule at the provider level (all hosts & instances)."""
|
||||
return IMPL.provider_fw_rule_create(context, rule)
|
||||
|
@ -3180,6 +3180,16 @@ def security_group_ensure_default(context, session=None):
|
||||
'project_id': context.project_id}
|
||||
default_group = security_group_create(context, values,
|
||||
session=session)
|
||||
for default_rule in security_group_default_rule_list(context):
|
||||
# This is suboptimal, it should be programmatic to know
|
||||
# the values of the default_rule
|
||||
rule_values = {'protocol': default_rule.protocol,
|
||||
'from_port': default_rule.from_port,
|
||||
'to_port': default_rule.to_port,
|
||||
'cidr': default_rule.cidr,
|
||||
'parent_group_id': default_group.id,
|
||||
}
|
||||
security_group_rule_create(context, rule_values)
|
||||
return (False, default_group)
|
||||
|
||||
|
||||
@ -3280,6 +3290,56 @@ def security_group_rule_count_by_group(context, security_group_id):
|
||||
###################
|
||||
|
||||
|
||||
def _security_group_rule_get_default_query(context, session=None):
|
||||
return model_query(context, models.SecurityGroupIngressDefaultRule,
|
||||
session=session)
|
||||
|
||||
|
||||
@require_context
|
||||
def security_group_default_rule_get(context, security_group_rule_default_id,
|
||||
session=None):
|
||||
result = _security_group_rule_get_default_query(context, session=session).\
|
||||
filter_by(id=security_group_rule_default_id).\
|
||||
first()
|
||||
|
||||
if not result:
|
||||
raise exception.SecurityGroupDefaultRuleNotFound(
|
||||
rule_id=security_group_rule_default_id)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@require_admin_context
|
||||
def security_group_default_rule_destroy(context,
|
||||
security_group_rule_default_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
count = _security_group_rule_get_default_query(context,
|
||||
session=session).\
|
||||
filter_by(id=security_group_rule_default_id).\
|
||||
soft_delete()
|
||||
if count == 0:
|
||||
raise exception.SecurityGroupDefaultRuleNotFound(
|
||||
rule_id=security_group_rule_default_id)
|
||||
|
||||
|
||||
@require_admin_context
|
||||
def security_group_default_rule_create(context, values):
|
||||
security_group_default_rule_ref = models.SecurityGroupIngressDefaultRule()
|
||||
security_group_default_rule_ref.update(values)
|
||||
security_group_default_rule_ref.save()
|
||||
return security_group_default_rule_ref
|
||||
|
||||
|
||||
@require_context
|
||||
def security_group_default_rule_list(context, session=None):
|
||||
return _security_group_rule_get_default_query(context, session=session).\
|
||||
all()
|
||||
|
||||
|
||||
###################
|
||||
|
||||
|
||||
@require_admin_context
|
||||
def provider_fw_rule_create(context, rule):
|
||||
fw_rule_ref = models.ProviderFirewallRule()
|
||||
|
@ -0,0 +1,61 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
#
|
||||
# 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 sqlalchemy import Column, DateTime, Integer, MetaData, String, Table
|
||||
from nova.db.sqlalchemy import types
|
||||
|
||||
from nova.openstack.common import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
security_group_default_rules = Table('security_group_default_rules', meta,
|
||||
Column('created_at', DateTime),
|
||||
Column('updated_at', DateTime),
|
||||
Column('deleted_at', DateTime),
|
||||
Column('deleted', Integer, default=0),
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('protocol', String(length=5)),
|
||||
Column('from_port', Integer),
|
||||
Column('to_port', Integer),
|
||||
Column('cidr', types.CIDR()),
|
||||
mysql_engine='InnoDB',
|
||||
mysql_charset='utf8',
|
||||
)
|
||||
|
||||
try:
|
||||
security_group_default_rules.create()
|
||||
except Exception:
|
||||
msg = "Exception while creating table 'security_group_default_rules"
|
||||
LOG.exception(msg)
|
||||
raise
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
security_group_default_rules = Table('security_group_default_rules',
|
||||
meta,
|
||||
autoload=True)
|
||||
try:
|
||||
security_group_default_rules.drop()
|
||||
except Exception:
|
||||
msg = "Exception while droppping table 'security_group_default_rules'"
|
||||
LOG.exception(msg)
|
||||
raise
|
@ -541,6 +541,15 @@ class SecurityGroupIngressRule(BASE, NovaBase):
|
||||
'SecurityGroupIngressRule.deleted == 0)')
|
||||
|
||||
|
||||
class SecurityGroupIngressDefaultRule(BASE, NovaBase):
|
||||
__tablename__ = 'security_group_default_rules'
|
||||
id = Column(Integer, primary_key=True)
|
||||
protocol = Column(String(5)) # "tcp", "udp" or "icmp"
|
||||
from_port = Column(Integer)
|
||||
to_port = Column(Integer)
|
||||
cidr = Column(types.CIDR())
|
||||
|
||||
|
||||
class ProviderFirewallRule(BASE, NovaBase):
|
||||
"""Represents a rule in a security group."""
|
||||
__tablename__ = 'provider_fw_rules'
|
||||
|
@ -732,6 +732,10 @@ class SecurityGroupNotExistsForInstance(Invalid):
|
||||
" the instance %(instance_id)s")
|
||||
|
||||
|
||||
class SecurityGroupDefaultRuleNotFound(Invalid):
|
||||
message = _("Security group default rule (%rule_id)s not found.")
|
||||
|
||||
|
||||
class MigrationNotFound(NotFound):
|
||||
message = _("Migration %(migration_id)s could not be found.")
|
||||
|
||||
|
@ -0,0 +1,467 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# 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 lxml import etree
|
||||
import webob
|
||||
|
||||
from nova.api.openstack.compute.contrib import security_group_default_rules
|
||||
from nova.api.openstack import wsgi
|
||||
from nova import context
|
||||
import nova.db
|
||||
from nova.openstack.common import cfg
|
||||
from nova import test
|
||||
from nova.tests.api.openstack import fakes
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class AttrDict(dict):
|
||||
def __getattr__(self, k):
|
||||
return self[k]
|
||||
|
||||
|
||||
def security_group_default_rule_template(**kwargs):
|
||||
rule = kwargs.copy()
|
||||
rule.setdefault('ip_protocol', 'TCP')
|
||||
rule.setdefault('from_port', 22)
|
||||
rule.setdefault('to_port', 22)
|
||||
rule.setdefault('cidr', '10.10.10.0/24')
|
||||
return rule
|
||||
|
||||
|
||||
def security_group_default_rule_db(security_group_default_rule, id=None):
|
||||
attrs = security_group_default_rule.copy()
|
||||
if id is not None:
|
||||
attrs['id'] = id
|
||||
return AttrDict(attrs)
|
||||
|
||||
|
||||
class TestSecurityGroupDefaultRules(test.TestCase):
|
||||
def setUp(self):
|
||||
super(TestSecurityGroupDefaultRules, self).setUp()
|
||||
self.controller = \
|
||||
security_group_default_rules.SecurityGroupDefaultRulesController()
|
||||
|
||||
def test_create_security_group_default_rule(self):
|
||||
sgr = security_group_default_rule_template()
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
sgr_dict = dict(security_group_default_rule=sgr)
|
||||
res_dict = self.controller.create(req, sgr_dict)
|
||||
security_group_default_rule = res_dict['security_group_default_rule']
|
||||
self.assertEqual(security_group_default_rule['ip_protocol'],
|
||||
sgr['ip_protocol'])
|
||||
self.assertEqual(security_group_default_rule['from_port'],
|
||||
sgr['from_port'])
|
||||
self.assertEqual(security_group_default_rule['to_port'],
|
||||
sgr['to_port'])
|
||||
self.assertEqual(security_group_default_rule['ip_range']['cidr'],
|
||||
sgr['cidr'])
|
||||
|
||||
def test_create_security_group_default_rule_with_no_to_port(self):
|
||||
sgr = security_group_default_rule_template()
|
||||
del sgr['to_port']
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_with_no_from_port(self):
|
||||
sgr = security_group_default_rule_template()
|
||||
del sgr['from_port']
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_with_no_ip_protocol(self):
|
||||
sgr = security_group_default_rule_template()
|
||||
del sgr['ip_protocol']
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_with_no_cidr(self):
|
||||
sgr = security_group_default_rule_template()
|
||||
del sgr['cidr']
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
res_dict = self.controller.create(req,
|
||||
{'security_group_default_rule': sgr})
|
||||
security_group_default_rule = res_dict['security_group_default_rule']
|
||||
self.assertNotEquals(security_group_default_rule['id'], 0)
|
||||
self.assertEquals(security_group_default_rule['ip_range']['cidr'],
|
||||
'0.0.0.0/0')
|
||||
|
||||
def test_create_security_group_default_rule_with_blank_to_port(self):
|
||||
sgr = security_group_default_rule_template(to_port='')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_with_blank_from_port(self):
|
||||
sgr = security_group_default_rule_template(from_port='')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_with_blank_ip_protocol(self):
|
||||
sgr = security_group_default_rule_template(ip_protocol='')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_with_blank_cidr(self):
|
||||
sgr = security_group_default_rule_template(cidr='')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
res_dict = self.controller.create(req,
|
||||
{'security_group_default_rule': sgr})
|
||||
security_group_default_rule = res_dict['security_group_default_rule']
|
||||
self.assertNotEquals(security_group_default_rule['id'], 0)
|
||||
self.assertEquals(security_group_default_rule['ip_range']['cidr'],
|
||||
'0.0.0.0/0')
|
||||
|
||||
def test_create_security_group_default_rule_non_numerical_to_port(self):
|
||||
sgr = security_group_default_rule_template(to_port='invalid')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_non_numerical_from_port(self):
|
||||
sgr = security_group_default_rule_template(from_port='invalid')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_invalid_ip_protocol(self):
|
||||
sgr = security_group_default_rule_template(ip_protocol='invalid')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_invalid_cidr(self):
|
||||
sgr = security_group_default_rule_template(cidr='10.10.2222.0/24')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_invalid_to_port(self):
|
||||
sgr = security_group_default_rule_template(to_port='666666')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_invalid_from_port(self):
|
||||
sgr = security_group_default_rule_template(from_port='666666')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_create_security_group_default_rule_with_no_body(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPUnprocessableEntity,
|
||||
self.controller.create, req, None)
|
||||
|
||||
def test_create_duplicate_security_group_default_rule(self):
|
||||
sgr = security_group_default_rule_template()
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.controller.create(req, {'security_group_default_rule': sgr})
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, {'security_group_default_rule': sgr})
|
||||
|
||||
def test_security_group_default_rules_list(self):
|
||||
self.test_create_security_group_default_rule()
|
||||
rules = [dict(id=1,
|
||||
ip_protocol='TCP',
|
||||
from_port=22,
|
||||
to_port=22,
|
||||
ip_range=dict(cidr='10.10.10.0/24'))]
|
||||
expected = {'security_group_default_rules': rules}
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(res_dict, expected)
|
||||
|
||||
def test_default_security_group_default_rule_show(self):
|
||||
sgr = security_group_default_rule_template(id=1)
|
||||
|
||||
self.test_create_security_group_default_rule()
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
res_dict = self.controller.show(req, '1')
|
||||
|
||||
security_group_default_rule = res_dict['security_group_default_rule']
|
||||
|
||||
self.assertEqual(security_group_default_rule['ip_protocol'],
|
||||
sgr['ip_protocol'])
|
||||
self.assertEqual(security_group_default_rule['to_port'],
|
||||
sgr['to_port'])
|
||||
self.assertEqual(security_group_default_rule['from_port'],
|
||||
sgr['from_port'])
|
||||
self.assertEqual(security_group_default_rule['ip_range']['cidr'],
|
||||
sgr['cidr'])
|
||||
|
||||
def test_delete_security_group_default_rule(self):
|
||||
sgr = security_group_default_rule_template(id=1)
|
||||
|
||||
self.test_create_security_group_default_rule()
|
||||
|
||||
self.called = False
|
||||
|
||||
def security_group_default_rule_destroy(context, id):
|
||||
self.called = True
|
||||
|
||||
def return_security_group_default_rule(context, id):
|
||||
self.assertEquals(sgr['id'], id)
|
||||
return security_group_default_rule_db(sgr)
|
||||
|
||||
self.stubs.Set(nova.db, 'security_group_default_rule_destroy',
|
||||
security_group_default_rule_destroy)
|
||||
self.stubs.Set(nova.db, 'security_group_default_rule_get',
|
||||
return_security_group_default_rule)
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v2/fake/os-security-group-default-rules', use_admin_context=True)
|
||||
self.controller.delete(req, '1')
|
||||
|
||||
self.assertTrue(self.called)
|
||||
|
||||
def test_security_group_ensure_default(self):
|
||||
sgr = security_group_default_rule_template(id=1)
|
||||
self.test_create_security_group_default_rule()
|
||||
|
||||
ctxt = context.get_admin_context()
|
||||
|
||||
setattr(ctxt, 'project_id', 'new_project_id')
|
||||
|
||||
_, sg = nova.db.security_group_ensure_default(ctxt)
|
||||
rules = nova.db.security_group_rule_get_by_security_group(ctxt, sg.id)
|
||||
security_group_rule = rules[0]
|
||||
self.assertEqual(sgr['id'], security_group_rule.id)
|
||||
self.assertEqual(sgr['ip_protocol'], security_group_rule.protocol)
|
||||
self.assertEqual(sgr['from_port'], security_group_rule.from_port)
|
||||
self.assertEqual(sgr['to_port'], security_group_rule.to_port)
|
||||
self.assertEqual(sgr['cidr'], security_group_rule.cidr)
|
||||
|
||||
|
||||
class TestSecurityGroupDefaultRulesXMLDeserializer(test.TestCase):
|
||||
def setUp(self):
|
||||
super(TestSecurityGroupDefaultRulesXMLDeserializer, self).setUp()
|
||||
deserializer = security_group_default_rules.\
|
||||
SecurityGroupDefaultRulesXMLDeserializer()
|
||||
self.deserializer = deserializer
|
||||
|
||||
def test_create_request(self):
|
||||
serial_request = """
|
||||
<security_group_default_rule>
|
||||
<from_port>22</from_port>
|
||||
<to_port>22</to_port>
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</security_group_default_rule>"""
|
||||
request = self.deserializer.deserialize(serial_request)
|
||||
expected = {
|
||||
"security_group_default_rule": {
|
||||
"from_port": "22",
|
||||
"to_port": "22",
|
||||
"ip_protocol": "TCP",
|
||||
"cidr": "10.10.10.0/24"
|
||||
},
|
||||
}
|
||||
self.assertEqual(request['body'], expected)
|
||||
|
||||
def test_create_no_to_port_request(self):
|
||||
serial_request = """
|
||||
<security_group_default_rule>
|
||||
<from_port>22</from_port>
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</security_group_default_rule>"""
|
||||
request = self.deserializer.deserialize(serial_request)
|
||||
expected = {
|
||||
"security_group_default_rule": {
|
||||
"from_port": "22",
|
||||
"ip_protocol": "TCP",
|
||||
"cidr": "10.10.10.0/24"
|
||||
},
|
||||
}
|
||||
self.assertEqual(request['body'], expected)
|
||||
|
||||
def test_create_no_from_port_request(self):
|
||||
serial_request = """
|
||||
<security_group_default_rule>
|
||||
<to_port>22</to_port>
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</security_group_default_rule>"""
|
||||
request = self.deserializer.deserialize(serial_request)
|
||||
expected = {
|
||||
"security_group_default_rule": {
|
||||
"to_port": "22",
|
||||
"ip_protocol": "TCP",
|
||||
"cidr": "10.10.10.0/24"
|
||||
},
|
||||
}
|
||||
self.assertEqual(request['body'], expected)
|
||||
|
||||
def test_create_no_ip_protocol_request(self):
|
||||
serial_request = """
|
||||
<security_group_default_rule>
|
||||
<from_port>22</from_port>
|
||||
<to_port>22</to_port>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</security_group_default_rule>"""
|
||||
request = self.deserializer.deserialize(serial_request)
|
||||
expected = {
|
||||
"security_group_default_rule": {
|
||||
"from_port": "22",
|
||||
"to_port": "22",
|
||||
"cidr": "10.10.10.0/24"
|
||||
},
|
||||
}
|
||||
self.assertEqual(request['body'], expected)
|
||||
|
||||
def test_create_no_cidr_request(self):
|
||||
serial_request = """
|
||||
<security_group_default_rule>
|
||||
<from_port>22</from_port>
|
||||
<to_port>22</to_port>
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
</security_group_default_rule>"""
|
||||
request = self.deserializer.deserialize(serial_request)
|
||||
expected = {
|
||||
"security_group_default_rule": {
|
||||
"from_port": "22",
|
||||
"to_port": "22",
|
||||
"ip_protocol": "TCP",
|
||||
},
|
||||
}
|
||||
self.assertEqual(request['body'], expected)
|
||||
|
||||
|
||||
class TestSecurityGroupDefaultRuleXMLSerializer(test.TestCase):
|
||||
def setUp(self):
|
||||
super(TestSecurityGroupDefaultRuleXMLSerializer, self).setUp()
|
||||
self.namespace = wsgi.XMLNS_V11
|
||||
self.rule_serializer =\
|
||||
security_group_default_rules.SecurityGroupDefaultRuleTemplate()
|
||||
self.index_serializer =\
|
||||
security_group_default_rules.SecurityGroupDefaultRulesTemplate()
|
||||
|
||||
def _tag(self, elem):
|
||||
tagname = elem.tag
|
||||
self.assertEqual(tagname[0], '{')
|
||||
tmp = tagname.partition('}')
|
||||
namespace = tmp[0][1:]
|
||||
self.assertEqual(namespace, self.namespace)
|
||||
return tmp[2]
|
||||
|
||||
def _verify_security_group_default_rule(self, raw_rule, tree):
|
||||
self.assertEqual(raw_rule['id'], tree.get('id'))
|
||||
|
||||
seen = set()
|
||||
expected = set(['ip_protocol', 'from_port', 'to_port', 'ip_range',
|
||||
'ip_range/cidr'])
|
||||
|
||||
for child in tree:
|
||||
child_tag = self._tag(child)
|
||||
seen.add(child_tag)
|
||||
if child_tag == 'ip_range':
|
||||
for gr_child in child:
|
||||
gr_child_tag = self._tag(gr_child)
|
||||
self.assertTrue(gr_child_tag in raw_rule[child_tag])
|
||||
seen.add('%s/%s' % (child_tag, gr_child_tag))
|
||||
self.assertEqual(gr_child.text,
|
||||
raw_rule[child_tag][gr_child_tag])
|
||||
else:
|
||||
self.assertEqual(child.text, raw_rule[child_tag])
|
||||
self.assertEqual(seen, expected)
|
||||
|
||||
def test_rule_serializer(self):
|
||||
raw_rule = dict(id='123',
|
||||
ip_protocol='TCP',
|
||||
from_port='22',
|
||||
to_port='22',
|
||||
ip_range=dict(cidr='10.10.10.0/24'))
|
||||
rule = dict(security_group_default_rule=raw_rule)
|
||||
text = self.rule_serializer.serialize(rule)
|
||||
|
||||
tree = etree.fromstring(text)
|
||||
|
||||
self.assertEqual('security_group_default_rule', self._tag(tree))
|
||||
self._verify_security_group_default_rule(raw_rule, tree)
|
||||
|
||||
def test_index_serializer(self):
|
||||
rules = [dict(id='123',
|
||||
ip_protocol='TCP',
|
||||
from_port='22',
|
||||
to_port='22',
|
||||
ip_range=dict(cidr='10.10.10.0/24')),
|
||||
dict(id='234',
|
||||
ip_protocol='UDP',
|
||||
from_port='23456',
|
||||
to_port='234567',
|
||||
ip_range=dict(cidr='10.12.0.0/18')),
|
||||
dict(id='345',
|
||||
ip_protocol='tcp',
|
||||
from_port='3456',
|
||||
to_port='4567',
|
||||
ip_range=dict(cidr='192.168.1.0/32'))]
|
||||
|
||||
rules_dict = dict(security_group_default_rules=rules)
|
||||
|
||||
text = self.index_serializer.serialize(rules_dict)
|
||||
|
||||
tree = etree.fromstring(text)
|
||||
self.assertEqual('security_group_default_rules', self._tag(tree))
|
||||
self.assertEqual(len(rules), len(tree))
|
||||
for idx, child in enumerate(tree):
|
||||
self._verify_security_group_default_rule(rules[idx], child)
|
@ -193,6 +193,7 @@ class ExtensionControllerTest(ExtensionTestCase):
|
||||
"Quotas",
|
||||
"Rescue",
|
||||
"SchedulerHints",
|
||||
"SecurityGroupDefaultRules",
|
||||
"SecurityGroups",
|
||||
"ServerDiagnostics",
|
||||
"ServerPassword",
|
||||
|
@ -156,6 +156,7 @@ policy_data = """
|
||||
"compute_extension:quotas:update": "",
|
||||
"compute_extension:quota_classes": "",
|
||||
"compute_extension:rescue": "",
|
||||
"compute_extension:security_group_default_rules": "",
|
||||
"compute_extension:security_groups": "",
|
||||
"compute_extension:server_diagnostics": "",
|
||||
"compute_extension:server_password": "",
|
||||
|
@ -392,6 +392,14 @@
|
||||
"namespace": "http://docs.openstack.org/compute/ext/rescue/api/v1.1",
|
||||
"updated": "%(timestamp)s"
|
||||
},
|
||||
{
|
||||
"alias": "os-security-group-default-rules",
|
||||
"description": "%(text)s",
|
||||
"links": [],
|
||||
"name": "SecurityGroupDefaultRules",
|
||||
"namespace": "http://docs.openstack.org/compute/ext/securitygroupdefaultrules/api/v1.1",
|
||||
"updated": "%(timestamp)s"
|
||||
},
|
||||
{
|
||||
"alias": "os-security-groups",
|
||||
"description": "%(text)s",
|
||||
|
@ -147,6 +147,9 @@
|
||||
<extension alias="os-rescue" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/rescue/api/v1.1" name="Rescue">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
<extension alias="os-security-group-default-rules" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/securitygroupdefaultrules/api/v1.1" name="SecurityGroupDefaultRules">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
<extension alias="os-security-groups" updated="%(timestamp)s" namespace="http://docs.openstack.org/compute/ext/securitygroups/api/v1.1" name="SecurityGroups">
|
||||
<description>%(text)s</description>
|
||||
</extension>
|
||||
|
@ -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,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<security_group_default_rule>
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<from_port>80</from_port>
|
||||
<to_port>80</to_port>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</security_group_default_rule>
|
@ -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,9 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<security_group_default_rule xmlns="http://docs.openstack.org/compute/api/v1.1" id="1">
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<from_port>80</from_port>
|
||||
<to_port>80</to_port>
|
||||
<ip_range>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</ip_range>
|
||||
</security_group_default_rule>
|
@ -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 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<security_group_default_rules xmlns="http://docs.openstack.org/compute/api/v1.1">
|
||||
<security_group_default_rule id="1">
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<from_port>80</from_port>
|
||||
<to_port>80</to_port>
|
||||
<ip_range>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</ip_range>
|
||||
</security_group_default_rule>
|
||||
</security_group_default_rules>
|
@ -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,9 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<security_group_default_rule xmlns="http://docs.openstack.org/compute/api/v1.1" id="1">
|
||||
<from_port>80</from_port>
|
||||
<to_port>80</to_port>
|
||||
<ip_protocol>TCP</ip_protocol>
|
||||
<ip_range>
|
||||
<cidr>10.10.10.0/24</cidr>
|
||||
</ip_range>
|
||||
</security_group_default_rule>
|
@ -1127,7 +1127,39 @@ class SecurityGroupsSampleJsonTest(ServersSampleBase):
|
||||
subs, response)
|
||||
|
||||
|
||||
class SecurityGroupsSampleXmlTest(SecurityGroupsSampleJsonTest):
|
||||
class SecurityGroupsSampleXmlTest(ApiSampleTestBase):
|
||||
ctype = 'xml'
|
||||
|
||||
|
||||
class SecurityGroupDefaultRulesSampleJsonTest(ServersSampleBase):
|
||||
extension_name = ('nova.api.openstack.compute.contrib'
|
||||
'.security_group_default_rules'
|
||||
'.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.assertEqual(response.status, 200)
|
||||
return self._verify_response(
|
||||
'security-group-default-rules-create-resp', {}, response)
|
||||
|
||||
def test_security_group_default_rules_list(self):
|
||||
self.test_security_group_default_rules_create()
|
||||
response = self._do_get('os-security-group-default-rules')
|
||||
return self._verify_response('security-group-default-rules-list-resp',
|
||||
{}, response)
|
||||
|
||||
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)
|
||||
return self._verify_response('security-group-default-rules-show-resp',
|
||||
{}, response)
|
||||
|
||||
|
||||
class SecurityGroupDefaultRulesSampleXmlTest(
|
||||
SecurityGroupDefaultRulesSampleJsonTest):
|
||||
ctype = 'xml'
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user