¡@

Home 

OpenStack Study: securitygroup.py

OpenStack Index

**** 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