¡@

Home 

OpenStack Study: varmour_fwaas.py

OpenStack Index

**** CubicPower OpenStack Study ****

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

#

# Copyright 2013 vArmour 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: Gary Duan, gduan@varmour.com, vArmour Networks

from neutron.openstack.common import log as logging

from neutron.services.firewall.agents.varmour import varmour_api

from neutron.services.firewall.agents.varmour import varmour_utils as va_utils

from neutron.services.firewall.drivers import fwaas_base

LOG = logging.getLogger(__name__)

**** CubicPower OpenStack Study ****

class vArmourFwaasDriver(fwaas_base.FwaasDriverBase):

**** CubicPower OpenStack Study ****

    def __init__(self):

        LOG.debug(_("Initializing fwaas vArmour driver"))

        self.rest = varmour_api.vArmourRestAPI()

**** CubicPower OpenStack Study ****

    def create_firewall(self, apply_list, firewall):

        LOG.debug(_('create_firewall (%s)'), firewall['id'])

        return self.update_firewall(apply_list, firewall)

**** CubicPower OpenStack Study ****

    def update_firewall(self, apply_list, firewall):

        LOG.debug(_("update_firewall (%s)"), firewall['id'])

        if firewall['admin_state_up']:

            return self._update_firewall(apply_list, firewall)

        else:

            return self.apply_default_policy(apply_list, firewall)

**** CubicPower OpenStack Study ****

    def delete_firewall(self, apply_list, firewall):

        LOG.debug(_("delete_firewall (%s)"), firewall['id'])

        return self.apply_default_policy(apply_list, firewall)

**** CubicPower OpenStack Study ****

    def apply_default_policy(self, apply_list, firewall):

        LOG.debug(_("apply_default_policy (%s)"), firewall['id'])

        self.rest.auth()

        for ri in apply_list:

            self._clear_policy(ri, firewall)

        return True

**** CubicPower OpenStack Study ****

    def _update_firewall(self, apply_list, firewall):

        LOG.debug(_("Updating firewall (%s)"), firewall['id'])

        self.rest.auth()

        for ri in apply_list:

            self._clear_policy(ri, firewall)

            self._setup_policy(ri, firewall)

        return True

**** CubicPower OpenStack Study ****

    def _setup_policy(self, ri, fw):

        # create zones no matter if they exist. Interfaces are added by router

        body = {

            'type': 'L3',

            'interface': []

        }

        body['name'] = va_utils.get_trusted_zone_name(ri)

        self.rest.rest_api('POST', va_utils.REST_URL_CONF_ZONE, body)

        body['name'] = va_utils.get_untrusted_zone_name(ri)

        self.rest.rest_api('POST', va_utils.REST_URL_CONF_ZONE, body)

        self.rest.commit()

        servs = dict()

        addrs = dict()

        for rule in fw['firewall_rule_list']:

            if not rule['enabled']:

                continue

            if rule['ip_version'] == 4:

                service = self._make_service(ri, fw, rule, servs)

                s_addr = self._make_address(ri, fw, rule, addrs, True)

                d_addr = self._make_address(ri, fw, rule, addrs, False)

                policy = va_utils.get_firewall_policy_name(ri, fw, rule)

                z0 = va_utils.get_trusted_zone_name(ri)

                z1 = va_utils.get_untrusted_zone_name(ri)

                body = self._make_policy(policy + '_0', rule,

                                         z0, z0, s_addr, d_addr, service)

                self.rest.rest_api('POST', va_utils.REST_URL_CONF_POLICY, body)

                body = self._make_policy(policy + '_1', rule,

                                         z0, z1, s_addr, d_addr, service)

                self.rest.rest_api('POST', va_utils.REST_URL_CONF_POLICY, body)

                body = self._make_policy(policy + '_2', rule,

                                         z1, z0, s_addr, d_addr, service)

                self.rest.rest_api('POST', va_utils.REST_URL_CONF_POLICY, body)

                self.rest.commit()

            else:

                LOG.warn(_("Unsupported IP version rule."))

**** CubicPower OpenStack Study ****

    def _clear_policy(self, ri, fw):

        prefix = va_utils.get_firewall_object_prefix(ri, fw)

        self.rest.del_cfg_objs(va_utils.REST_URL_CONF_POLICY, prefix)

        self.rest.del_cfg_objs(va_utils.REST_URL_CONF_ADDR, prefix)

        self.rest.del_cfg_objs(va_utils.REST_URL_CONF_SERVICE, prefix)

**** CubicPower OpenStack Study ****

    def _make_service(self, ri, fw, rule, servs):

        prefix = va_utils.get_firewall_object_prefix(ri, fw)

        if rule.get('protocol'):

            key = rule.get('protocol')

            if rule.get('source_port'):

                key += '-' + rule.get('source_port')

            if rule.get('destination_port'):

                key += '-' + rule.get('destination_port')

        else:

            return

        if key in servs:

            name = '%s_%d' % (prefix, servs[key])

        else:

            # create new service object with index

            idx = len(servs)

            servs[key] = idx

            name = '%s_%d' % (prefix, idx)

            body = {'name': name}

            self.rest.rest_api('POST',

                               va_utils.REST_URL_CONF_SERVICE,

                               body)

            body = self._make_service_rule(rule)

            self.rest.rest_api('POST',

                               va_utils.REST_URL_CONF +

                               va_utils.REST_SERVICE_NAME % name,

                               body)

            self.rest.commit()

        return name

**** CubicPower OpenStack Study ****

    def _make_service_rule(self, rule):

        body = {

            'name': '1',

            'protocol': rule.get('protocol')

        }

        if 'source_port' in rule:

            body['source-start'] = rule['source_port']

            body['source-end'] = rule['source_port']

        if 'destination_port' in rule:

            body['dest-start'] = rule['destination_port']

            body['dest-end'] = rule['destination_port']

        return body

**** CubicPower OpenStack Study ****

    def _make_address(self, ri, fw, rule, addrs, is_src):

        prefix = va_utils.get_firewall_object_prefix(ri, fw)

        if is_src:

            key = rule.get('source_ip_address')

        else:

            key = rule.get('destination_ip_address')

        if not key:

            return

        if key in addrs:

            name = '%s_%d' % (prefix, addrs[key])

        else:

            # create new address object with idx

            idx = len(addrs)

            addrs[key] = idx

            name = '%s_%d' % (prefix, idx)

            body = {

                'name': name,

                'type': 'ipv4',

                'ipv4': key

            }

            self.rest.rest_api('POST', va_utils.REST_URL_CONF_ADDR, body)

            self.rest.commit()

        return name

**** CubicPower OpenStack Study ****

    def _make_policy(self, name, rule, zone0, zone1, s_addr, d_addr, service):

        body = {

            'name': name,

            'action': 'permit' if rule.get('action') == 'allow' else 'deny',

            'from': zone0,

            'to': zone1,

            'match-source-address': [s_addr or 'Any'],

            'match-dest-address': [d_addr or 'Any'],

            'match-service': [service or 'Any']

        }

        return body