**** CubicPower OpenStack Study ****
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2012 OpenStack Foundation.
# All rights reserved.
#
# 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 abc import ABCMeta
from abc import abstractmethod
from oslo.config import cfg
import six
from neutron.api import extensions
from neutron.api.v2 import attributes as attr
from neutron.api.v2 import base
from neutron.common import constants as const
from neutron.common import exceptions as qexception
from neutron import manager
from neutron.openstack.common import uuidutils
from neutron import quota
# Security group Exceptions
**** CubicPower OpenStack Study ****
class SecurityGroupInvalidPortRange(qexception.InvalidInput):
message = _("For TCP/UDP protocols, port_range_min must be "
"<= port_range_max")
**** CubicPower OpenStack Study ****
class SecurityGroupInvalidPortValue(qexception.InvalidInput):
message = _("Invalid value for port %(port)s")
**** CubicPower OpenStack Study ****
class SecurityGroupInvalidIcmpValue(qexception.InvalidInput):
message = _("Invalid value for ICMP %(field)s (%(attr)s) "
"%(value)s. It must be 0 to 255.")
**** CubicPower OpenStack Study ****
class SecurityGroupInUse(qexception.InUse):
message = _("Security Group %(id)s in use.")
**** CubicPower OpenStack Study ****
class SecurityGroupCannotRemoveDefault(qexception.InUse):
message = _("Removing
**** CubicPower OpenStack Study ****
class SecurityGroupCannotUpdateDefault(qexception.InUse):
message = _("Updating
**** CubicPower OpenStack Study ****
class SecurityGroupDefaultAlreadyExists(qexception.InUse):
message = _("Default security group already exists.")
**** CubicPower OpenStack Study ****
class SecurityGroupRuleInvalidProtocol(qexception.InvalidInput):
message = _("Security group rule protocol %(protocol)s not supported. "
"Only protocol values %(values)s and their integer "
"representation (0 to 255) are supported.")
**** CubicPower OpenStack Study ****
class SecurityGroupRulesNotSingleTenant(qexception.InvalidInput):
message = _("Multiple tenant_ids in bulk security group rule create"
" not allowed")
**** CubicPower OpenStack Study ****
class SecurityGroupRemoteGroupAndRemoteIpPrefix(qexception.InvalidInput):
message = _("Only remote_ip_prefix or remote_group_id may "
"be provided.")
**** CubicPower OpenStack Study ****
class SecurityGroupProtocolRequiredWithPorts(qexception.InvalidInput):
message = _("Must also specifiy protocol if port range is given.")
**** CubicPower OpenStack Study ****
class SecurityGroupNotSingleGroupRules(qexception.InvalidInput):
message = _("Only allowed to update rules for "
"one security profile at a time")
**** CubicPower OpenStack Study ****
class SecurityGroupNotFound(qexception.NotFound):
message = _("Security group %(id)s does not exist")
**** CubicPower OpenStack Study ****
class SecurityGroupRuleNotFound(qexception.NotFound):
message = _("Security group rule %(id)s does not exist")
**** CubicPower OpenStack Study ****
class DuplicateSecurityGroupRuleInPost(qexception.InUse):
message = _("Duplicate Security Group Rule in POST.")
**** CubicPower OpenStack Study ****
class SecurityGroupRuleExists(qexception.InUse):
message = _("Security group rule already exists. Group id is %(id)s.")
**** CubicPower OpenStack Study ****
def convert_protocol(value):
if value is None:
return
try:
val = int(value)
if val >= 0 and val <= 255:
return val
raise SecurityGroupRuleInvalidProtocol(
protocol=value, values=sg_supported_protocols)
except (ValueError, TypeError):
if value.lower() in sg_supported_protocols:
return value.lower()
raise SecurityGroupRuleInvalidProtocol(
protocol=value, values=sg_supported_protocols)
except AttributeError:
raise SecurityGroupRuleInvalidProtocol(
protocol=value, values=sg_supported_protocols)
**** CubicPower OpenStack Study ****
def convert_ethertype_to_case_insensitive(value):
if isinstance(value, basestring):
for ethertype in sg_supported_ethertypes:
if ethertype.lower() == value.lower():
return ethertype
**** CubicPower OpenStack Study ****
def convert_validate_port_value(port):
if port is None:
return port
try:
val = int(port)
except (ValueError, TypeError):
raise SecurityGroupInvalidPortValue(port=port)
if val >= 0 and val <= 65535:
return val
else:
raise SecurityGroupInvalidPortValue(port=port)
**** CubicPower OpenStack Study ****
def convert_to_uuid_list_or_none(value_list):
if value_list is None:
return
for sg_id in value_list:
if not uuidutils.is_uuid_like(sg_id):
msg = _("'%s' is not an integer or uuid") % sg_id
raise qexception.InvalidInput(error_message=msg)
return value_list
**** CubicPower OpenStack Study ****
def _validate_name_not_default(data, valid_values=None):
if data == "default":
raise SecurityGroupDefaultAlreadyExists()
attr.validators['type:name_not_default'] = _validate_name_not_default
sg_supported_protocols = [None, const.PROTO_NAME_TCP,
const.PROTO_NAME_UDP, const.PROTO_NAME_ICMP]
sg_supported_ethertypes = ['IPv4', 'IPv6']
# Attribute Map
RESOURCE_ATTRIBUTE_MAP = {
'security_groups': {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True,
'primary_key': True},
'name': {'allow_post': True, 'allow_put': True,
'is_visible': True, 'default': '',
'validate': {'type:name_not_default': None}},
'description': {'allow_post': True, 'allow_put': True,
'is_visible': True, 'default': ''},
'tenant_id': {'allow_post': True, 'allow_put': False,
'required_by_policy': True,
'is_visible': True},
'security_group_rules': {'allow_post': False, 'allow_put': False,
'is_visible': True},
},
'security_group_rules': {
'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None},
'is_visible': True,
'primary_key': True},
'security_group_id': {'allow_post': True, 'allow_put': False,
'is_visible': True, 'required_by_policy': True},
'remote_group_id': {'allow_post': True, 'allow_put': False,
'default': None, 'is_visible': True},
'direction': {'allow_post': True, 'allow_put': True,
'is_visible': True,
'validate': {'type:values': ['ingress', 'egress']}},
'protocol': {'allow_post': True, 'allow_put': False,
'is_visible': True, 'default': None,
'convert_to': convert_protocol},
'port_range_min': {'allow_post': True, 'allow_put': False,
'convert_to': convert_validate_port_value,
'default': None, 'is_visible': True},
'port_range_max': {'allow_post': True, 'allow_put': False,
'convert_to': convert_validate_port_value,
'default': None, 'is_visible': True},
'ethertype': {'allow_post': True, 'allow_put': False,
'is_visible': True, 'default': 'IPv4',
'convert_to': convert_ethertype_to_case_insensitive,
'validate': {'type:values': sg_supported_ethertypes}},
'remote_ip_prefix': {'allow_post': True, 'allow_put': False,
'default': None, 'is_visible': True},
'tenant_id': {'allow_post': True, 'allow_put': False,
'required_by_policy': True,
'is_visible': True},
}
}
SECURITYGROUPS = 'security_groups'
EXTENDED_ATTRIBUTES_2_0 = {
'ports': {SECURITYGROUPS: {'allow_post': True,
'allow_put': True,
'is_visible': True,
'convert_to': convert_to_uuid_list_or_none,
'default': attr.ATTR_NOT_SPECIFIED}}}
security_group_quota_opts = [
cfg.IntOpt('quota_security_group',
default=10,
help=_('Number of security groups allowed per tenant. '
'A negative value means unlimited.')),
cfg.IntOpt('quota_security_group_rule',
default=100,
help=_('Number of security rules allowed per tenant. '
'A negative value means unlimited.')),
]
cfg.CONF.register_opts(security_group_quota_opts, 'QUOTAS')
**** CubicPower OpenStack Study ****
class Securitygroup(extensions.ExtensionDescriptor):
"""Security group extension."""
@classmethod
**** CubicPower OpenStack Study ****
def get_name(cls):
return "security-group"
@classmethod
**** CubicPower OpenStack Study ****
def get_alias(cls):
return "security-group"
@classmethod
**** CubicPower OpenStack Study ****
def get_description(cls):
return "The security groups extension."
@classmethod
**** CubicPower OpenStack Study ****
def get_namespace(cls):
# todo
return "http://docs.openstack.org/ext/securitygroups/api/v2.0"
@classmethod
**** CubicPower OpenStack Study ****
def get_updated(cls):
return "2012-10-05T10:00:00-00:00"
@classmethod
**** CubicPower OpenStack Study ****
def get_resources(cls):
"""Returns Ext Resources."""
my_plurals = [(key, key[:-1]) for key in RESOURCE_ATTRIBUTE_MAP.keys()]
attr.PLURALS.update(dict(my_plurals))
exts = []
plugin = manager.NeutronManager.get_plugin()
for resource_name in ['security_group', 'security_group_rule']:
collection_name = resource_name.replace('_', '-') + "s"
params = RESOURCE_ATTRIBUTE_MAP.get(resource_name + "s", dict())
quota.QUOTAS.register_resource_by_name(resource_name)
controller = base.create_resource(collection_name,
resource_name,
plugin, params, allow_bulk=True,
allow_pagination=True,
allow_sorting=True)
ex = extensions.ResourceExtension(collection_name,
controller,
attr_map=params)
exts.append(ex)
return exts
**** CubicPower OpenStack Study ****
def get_extended_resources(self, version):
if version == "2.0":
return dict(EXTENDED_ATTRIBUTES_2_0.items() +
RESOURCE_ATTRIBUTE_MAP.items())
else:
return {}
@six.add_metaclass(ABCMeta)
**** CubicPower OpenStack Study ****
class SecurityGroupPluginBase(object):
@abstractmethod
**** CubicPower OpenStack Study ****
def create_security_group(self, context, security_group):
pass
@abstractmethod
**** CubicPower OpenStack Study ****
def update_security_group(self, context, id, security_group):
pass
@abstractmethod
**** CubicPower OpenStack Study ****
def delete_security_group(self, context, id):
pass
@abstractmethod
**** CubicPower OpenStack Study ****
def get_security_groups(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
pass
@abstractmethod
**** CubicPower OpenStack Study ****
def get_security_group(self, context, id, fields=None):
pass
@abstractmethod
**** CubicPower OpenStack Study ****
def create_security_group_rule(self, context, security_group_rule):
pass
@abstractmethod
**** CubicPower OpenStack Study ****
def delete_security_group_rule(self, context, id):
pass
@abstractmethod
**** CubicPower OpenStack Study ****
def get_security_group_rules(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
pass
@abstractmethod
**** CubicPower OpenStack Study ****
def get_security_group_rule(self, context, id, fields=None):
pass