¡@

Home 

OpenStack Study: firewall.py

OpenStack Index

**** CubicPower OpenStack Study ****

# vim: tabstop=4 shiftwidth=4 softtabstop=4

#

# Copyright 2013 Big Switch Networks, Inc.

# 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.

#

# @author: Sumit Naiksatam, sumitnaiksatam@gmail.com, Big Switch Networks, Inc.

import abc

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 resource_helper

from neutron.common import exceptions as qexception

from neutron.openstack.common import log as logging

from neutron.plugins.common import constants

from neutron.services.service_base import ServicePluginBase

LOG = logging.getLogger(__name__)

# Firewall Exceptions

**** CubicPower OpenStack Study ****

class FirewallNotFound(qexception.NotFound):

message = _("Firewall %(firewall_id)s could not be found.")

**** CubicPower OpenStack Study ****

class FirewallInUse(qexception.InUse):

message = _("Firewall %(firewall_id)s is still active.")

**** CubicPower OpenStack Study ****

class FirewallInPendingState(qexception.Conflict):

message = _("Operation cannot be performed since associated Firewall "

"%(firewall_id)s is in %(pending_state)s.")

**** CubicPower OpenStack Study ****

class FirewallPolicyNotFound(qexception.NotFound):

message = _("Firewall Policy %(firewall_policy_id)s could not be found.")

**** CubicPower OpenStack Study ****

class FirewallPolicyInUse(qexception.InUse):

message = _("Firewall Policy %(firewall_policy_id)s is being used.")

**** CubicPower OpenStack Study ****

class FirewallRuleNotFound(qexception.NotFound):

message = _("Firewall Rule %(firewall_rule_id)s could not be found.")

**** CubicPower OpenStack Study ****

class FirewallRuleInUse(qexception.InUse):

message = _("Firewall Rule %(firewall_rule_id)s is being used.")

**** CubicPower OpenStack Study ****

class FirewallRuleNotAssociatedWithPolicy(qexception.InvalidInput):

message = _("Firewall Rule %(firewall_rule_id)s is not associated "

" with Firewall Policy %(firewall_policy_id)s.")

**** CubicPower OpenStack Study ****

class FirewallRuleInvalidProtocol(qexception.InvalidInput):

message = _("Firewall Rule protocol %(protocol)s is not supported. "

"Only protocol values %(values)s and their integer "

"representation (0 to 255) are supported.")

**** CubicPower OpenStack Study ****

class FirewallRuleInvalidAction(qexception.InvalidInput):

message = _("Firewall rule action %(action)s is not supported. "

"Only action values %(values)s are supported.")

**** CubicPower OpenStack Study ****

class FirewallInvalidPortValue(qexception.InvalidInput):

message = _("Invalid value for port %(port)s.")

**** CubicPower OpenStack Study ****

class FirewallRuleInfoMissing(qexception.InvalidInput):

message = _("Missing rule info argument for insert/remove "

"rule operation.")

**** CubicPower OpenStack Study ****

class FirewallInternalDriverError(qexception.NeutronException):

"""Fwaas exception for all driver errors.

On any failure or exception in the driver, driver should log it and

raise this exception to the agent

"""

message = _("%(driver)s: Internal driver error.")

fw_valid_protocol_values = [None, constants.TCP, constants.UDP, constants.ICMP]

fw_valid_action_values = [constants.FWAAS_ALLOW, constants.FWAAS_DENY]

**** CubicPower OpenStack Study ****

def convert_protocol(value):

    if value is None:

        return

    if value.isdigit():

        val = int(value)

        if 0 <= val <= 255:

            return val

        else:

            raise FirewallRuleInvalidProtocol(protocol=value,

                                              values=

                                              fw_valid_protocol_values)

    elif value.lower() in fw_valid_protocol_values:

        return value.lower()

    else:

        raise FirewallRuleInvalidProtocol(protocol=value,

                                          values=

                                          fw_valid_protocol_values)

**** CubicPower OpenStack Study ****

def convert_action_to_case_insensitive(value):

    if value is None:

        return

    else:

        return value.lower()

**** CubicPower OpenStack Study ****

def convert_port_to_string(value):

    if value is None:

        return

    else:

        return str(value)

**** CubicPower OpenStack Study ****

def _validate_port_range(data, key_specs=None):

    if data is None:

        return

    data = str(data)

    ports = data.split(':')

    for p in ports:

        try:

            val = int(p)

        except (ValueError, TypeError):

            msg = _("Port '%s' is not a valid number") % p

            LOG.debug(msg)

            return msg

        if val <= 0 or val > 65535:

            msg = _("Invalid port '%s'") % p

            LOG.debug(msg)

            return msg

**** CubicPower OpenStack Study ****

def _validate_ip_or_subnet_or_none(data, valid_values=None):

    if data is None:

        return None

    msg_ip = attr._validate_ip_address(data, valid_values)

    if not msg_ip:

        return

    msg_subnet = attr._validate_subnet(data, valid_values)

    if not msg_subnet:

        return

    return _("%(msg_ip)s and %(msg_subnet)s") % {'msg_ip': msg_ip,

                                                 'msg_subnet': msg_subnet}

attr.validators['type:port_range'] = _validate_port_range

attr.validators['type:ip_or_subnet_or_none'] = _validate_ip_or_subnet_or_none

RESOURCE_ATTRIBUTE_MAP = {

    'firewall_rules': {

        'id': {'allow_post': False, 'allow_put': False,

               'validate': {'type:uuid': None},

               'is_visible': True, 'primary_key': True},

        'tenant_id': {'allow_post': True, 'allow_put': False,

                      'required_by_policy': True,

                      'is_visible': True},

        'name': {'allow_post': True, 'allow_put': True,

                 'validate': {'type:string': None},

                 'is_visible': True, 'default': ''},

        'description': {'allow_post': True, 'allow_put': True,

                        'validate': {'type:string': None},

                        'is_visible': True, 'default': ''},

        'firewall_policy_id': {'allow_post': False, 'allow_put': False,

                               'validate': {'type:uuid_or_none': None},

                               'is_visible': True},

        'shared': {'allow_post': True, 'allow_put': True,

                   'default': False, 'convert_to': attr.convert_to_boolean,

                   'is_visible': True, 'required_by_policy': True,

                   'enforce_policy': True},

        'protocol': {'allow_post': True, 'allow_put': True,

                     'is_visible': True, 'default': None,

                     'convert_to': convert_protocol,

                     'validate': {'type:values': fw_valid_protocol_values}},

        'ip_version': {'allow_post': True, 'allow_put': True,

                       'default': 4, 'convert_to': attr.convert_to_int,

                       'validate': {'type:values': [4, 6]},

                       'is_visible': True},

        'source_ip_address': {'allow_post': True, 'allow_put': True,

                              'validate': {'type:ip_or_subnet_or_none': None},

                              'is_visible': True, 'default': None},

        'destination_ip_address': {'allow_post': True, 'allow_put': True,

                                   'validate': {'type:ip_or_subnet_or_none':

                                                None},

                                   'is_visible': True, 'default': None},

        'source_port': {'allow_post': True, 'allow_put': True,

                        'validate': {'type:port_range': None},

                        'convert_to': convert_port_to_string,

                        'default': None, 'is_visible': True},

        'destination_port': {'allow_post': True, 'allow_put': True,

                             'validate': {'type:port_range': None},

                             'convert_to': convert_port_to_string,

                             'default': None, 'is_visible': True},

        'position': {'allow_post': False, 'allow_put': False,

                     'default': None, 'is_visible': True},

        'action': {'allow_post': True, 'allow_put': True,

                   'convert_to': convert_action_to_case_insensitive,

                   'validate': {'type:values': fw_valid_action_values},

                   'is_visible': True, 'default': 'deny'},

        'enabled': {'allow_post': True, 'allow_put': True,

                    'default': True, 'convert_to': attr.convert_to_boolean,

                    'is_visible': True},

    },

    'firewall_policies': {

        'id': {'allow_post': False, 'allow_put': False,

               'validate': {'type:uuid': None},

               'is_visible': True,

               'primary_key': True},

        'tenant_id': {'allow_post': True, 'allow_put': False,

                      'required_by_policy': True,

                      'is_visible': True},

        'name': {'allow_post': True, 'allow_put': True,

                 'validate': {'type:string': None},

                 'is_visible': True, 'default': ''},

        'description': {'allow_post': True, 'allow_put': True,

                        'validate': {'type:string': None},

                        'is_visible': True, 'default': ''},

        'shared': {'allow_post': True, 'allow_put': True,

                   'default': False, 'convert_to': attr.convert_to_boolean,

                   'is_visible': True, 'required_by_policy': True,

                   'enforce_policy': True},

        'firewall_rules': {'allow_post': True, 'allow_put': True,

                           'validate': {'type:uuid_list': None},

                           'convert_to': attr.convert_none_to_empty_list,

                           'default': None, 'is_visible': True},

        'audited': {'allow_post': True, 'allow_put': True,

                    'default': False, 'convert_to': attr.convert_to_boolean,

                    'is_visible': True},

    },

    'firewalls': {

        'id': {'allow_post': False, 'allow_put': False,

               'validate': {'type:uuid': None},

               'is_visible': True,

               'primary_key': True},

        'tenant_id': {'allow_post': True, 'allow_put': False,

                      'required_by_policy': True,

                      'is_visible': True},

        'name': {'allow_post': True, 'allow_put': True,

                 'validate': {'type:string': None},

                 'is_visible': True, 'default': ''},

        'description': {'allow_post': True, 'allow_put': True,

                        'validate': {'type:string': None},

                        'is_visible': True, 'default': ''},

        'admin_state_up': {'allow_post': True, 'allow_put': True,

                           'default': True,

                           'convert_to': attr.convert_to_boolean,

                           'is_visible': True},

        'status': {'allow_post': False, 'allow_put': False,

                   'is_visible': True},

        'shared': {'allow_post': True, 'allow_put': True,

                   'default': False, 'convert_to': attr.convert_to_boolean,

                   'is_visible': False, 'required_by_policy': True,

                   'enforce_policy': True},

        'firewall_policy_id': {'allow_post': True, 'allow_put': True,

                               'validate': {'type:uuid_or_none': None},

                               'is_visible': True},

    },

}

firewall_quota_opts = [

    cfg.IntOpt('quota_firewall',

               default=1,

               help=_('Number of firewalls allowed per tenant. '

                      'A negative value means unlimited.')),

    cfg.IntOpt('quota_firewall_policy',

               default=1,

               help=_('Number of firewall policies allowed per tenant. '

                      'A negative value means unlimited.')),

    cfg.IntOpt('quota_firewall_rule',

               default=-1,

               help=_('Number of firewall rules allowed per tenant. '

                      'A negative value means unlimited.')),

]

cfg.CONF.register_opts(firewall_quota_opts, 'QUOTAS')

**** CubicPower OpenStack Study ****

class Firewall(extensions.ExtensionDescriptor):

@classmethod

**** CubicPower OpenStack Study ****

    def get_name(cls):

        return "Firewall service"

    @classmethod

**** CubicPower OpenStack Study ****

    def get_alias(cls):

        return "fwaas"

    @classmethod

**** CubicPower OpenStack Study ****

    def get_description(cls):

        return "Extension for Firewall service"

    @classmethod

**** CubicPower OpenStack Study ****

    def get_namespace(cls):

        return "http://wiki.openstack.org/Neutron/FWaaS/API_1.0"

    @classmethod

**** CubicPower OpenStack Study ****

    def get_updated(cls):

        return "2013-02-25T10:00:00-00:00"

    @classmethod

**** CubicPower OpenStack Study ****

    def get_resources(cls):

        special_mappings = {'firewall_policies': 'firewall_policy'}

        plural_mappings = resource_helper.build_plural_mappings(

            special_mappings, RESOURCE_ATTRIBUTE_MAP)

        attr.PLURALS.update(plural_mappings)

        action_map = {'firewall_policy': {'insert_rule': 'PUT',

                                          'remove_rule': 'PUT'}}

        return resource_helper.build_resource_info(plural_mappings,

                                                   RESOURCE_ATTRIBUTE_MAP,

                                                   constants.FIREWALL,

                                                   action_map=action_map)

    @classmethod

**** CubicPower OpenStack Study ****

    def get_plugin_interface(cls):

        return FirewallPluginBase

**** CubicPower OpenStack Study ****

    def update_attributes_map(self, attributes):

        super(Firewall, self).update_attributes_map(

            attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP)

**** CubicPower OpenStack Study ****

    def get_extended_resources(self, version):

        if version == "2.0":

            return RESOURCE_ATTRIBUTE_MAP

        else:

            return {}

@six.add_metaclass(abc.ABCMeta)

**** CubicPower OpenStack Study ****

class FirewallPluginBase(ServicePluginBase):

**** CubicPower OpenStack Study ****

    def get_plugin_name(self):

        return constants.FIREWALL

**** CubicPower OpenStack Study ****

    def get_plugin_type(self):

        return constants.FIREWALL

**** CubicPower OpenStack Study ****

    def get_plugin_description(self):

        return 'Firewall service plugin'

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def get_firewalls(self, context, filters=None, fields=None):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def get_firewall(self, context, id, fields=None):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def create_firewall(self, context, firewall):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def update_firewall(self, context, id, firewall):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def delete_firewall(self, context, id):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def get_firewall_rules(self, context, filters=None, fields=None):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def get_firewall_rule(self, context, id, fields=None):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def create_firewall_rule(self, context, firewall_rule):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def update_firewall_rule(self, context, id, firewall_rule):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def delete_firewall_rule(self, context, id):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def get_firewall_policy(self, context, id, fields=None):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def get_firewall_policies(self, context, filters=None, fields=None):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def create_firewall_policy(self, context, firewall_policy):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def update_firewall_policy(self, context, id, firewall_policy):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def delete_firewall_policy(self, context, id):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def insert_rule(self, context, id, rule_info):

        pass

    @abc.abstractmethod

**** CubicPower OpenStack Study ****

    def remove_rule(self, context, id, rule_info):

        pass