summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorMorgan Fainberg <m@metacloud.com>2013-02-06 15:39:54 -0800
committerGerrit Code Review <review@openstack.org>2013-02-19 01:50:51 +0000
commit59aaf1dff97aa25a71d317300b8255f4c59391a9 (patch)
tree6c5614d8cdd8b3963e5abacbf0939f1772deaad9 /nova/api
parent30c2a8f66edb9f9601a519fb525a46cc4486ab2a (diff)
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
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/compute/contrib/security_group_default_rules.py210
1 files changed, 210 insertions, 0 deletions
diff --git a/nova/api/openstack/compute/contrib/security_group_default_rules.py b/nova/api/openstack/compute/contrib/security_group_default_rules.py
new file mode 100644
index 000000000..fed1468a8
--- /dev/null
+++ b/nova/api/openstack/compute/contrib/security_group_default_rules.py
@@ -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