diff --git a/.zuul.yaml b/.zuul.yaml index 24809b3f1..f1ba1281b 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -14,21 +14,17 @@ - neutron-fwaas-networking-midonet-cross-py35: voting: false - legacy-neutron-fwaas-v2-dsvm-tempest - - legacy-neutron-fwaas-v1-dsvm-tempest - legacy-neutron-fwaas-dsvm-functional - legacy-grenade-dsvm-neutron-fwaas-multinode: voting: false irrelevant-files: - ^(test-|)requirements.txt$ - ^setup.cfg$ - - legacy-neutron-fwaas-v1-dsvm-tempest-multinode: - voting: false - legacy-neutron-fwaas-v2-dsvm-tempest-multinode: voting: false gate: jobs: - legacy-neutron-fwaas-v2-dsvm-tempest - - legacy-neutron-fwaas-v1-dsvm-tempest - legacy-neutron-fwaas-dsvm-functional experimental: jobs: diff --git a/devstack/README.rst b/devstack/README.rst index 921ec7631..c6bd89ad4 100644 --- a/devstack/README.rst +++ b/devstack/README.rst @@ -6,10 +6,8 @@ This is setup as a DevStack plugin. For more information on DevStack plugins, see the `DevStack Plugins documentation `_. -Please note that the old 'q-fwaas' keyword still exists, and will run FWaaS V1. -This default will be changed during the Ocata cycle. The introduction of two -new keywords, 'q-fwaas-v1' and 'q-fwaas-v2' allow you to explicitly select the -version you with to run. +Please note that the old 'q-fwaas' keyword still exists, You can specify +enable_service q-fwaas or enable_service q-fwaas-v2 in local.conf How to run FWaaS V2 in DevStack =============================== @@ -32,25 +30,3 @@ testing. [[local|localrc]] enable_plugin neutron-fwaas https://review.openstack.org/p/openstack/neutron-fwaas refs/changes/50/214350/14 enable_service q-fwaas-v2 - -How to run FWaaS V1 in DevStack -=============================== - -Add the following to the localrc section of your local.conf to configure -FWaaS v1. - -.. code-block:: ini - - [[local|localrc]] - enable_plugin neutron-fwaas https://git.openstack.org/openstack/neutron-fwaas - enable_service q-fwaas-v1 - -To check a specific patchset that is currently under development, use a form -like the below example, which is checking out change 214350 patch set 14 for -testing. - -.. code-block:: ini - - [[local|localrc]] - enable_plugin neutron-fwaas https://review.openstack.org/p/openstack/neutron-fwaas refs/changes/50/214350/14 - enable_service q-fwaas-v1 diff --git a/devstack/plugin.sh b/devstack/plugin.sh index 727c78ecf..1c3fe2787 100755 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -38,14 +38,6 @@ function install_fwaas() { fi } -function configure_fwaas_v1() { - cp $NEUTRON_FWAAS_DIR/etc/neutron_fwaas.conf.sample $NEUTRON_FWAAS_CONF - neutron_fwaas_configure_driver fwaas - iniset_multiline $Q_L3_CONF_FILE fwaas agent_version v1 - iniset_multiline $Q_L3_CONF_FILE fwaas conntrack_driver conntrack - iniset_multiline $Q_L3_CONF_FILE fwaas driver $FWAAS_DRIVER_V1 -} - function configure_fwaas_v2() { # Add conf file cp $NEUTRON_FWAAS_DIR/etc/neutron_fwaas.conf.sample $NEUTRON_FWAAS_CONF @@ -93,13 +85,7 @@ function cleanup_fwaas() { } function neutron_fwaas_configure_common { - if is_service_enabled q-fwaas-v1 neutron-fwaas-v1; then - neutron_service_plugin_class_add $FWAAS_PLUGIN_V1 - elif is_service_enabled q-fwaas-v2 neutron-fwaas-v2; then - neutron_service_plugin_class_add $FWAAS_PLUGIN_V2 - else - neutron_service_plugin_class_add $FWAAS_PLUGIN_V1 - fi + neutron_service_plugin_class_add $FWAAS_PLUGIN_V2 } function neutron_fwaas_configure_driver { @@ -109,7 +95,7 @@ function neutron_fwaas_configure_driver { } # check for service enabled -if is_service_enabled q-svc neutron-api && is_service_enabled q-fwaas q-fwaas-v1 q-fwaas-v2 neutron-fwaas-v1 neutron-fwaas-v2; then +if is_service_enabled q-svc neutron-api && is_service_enabled q-fwaas q-fwaas-v2 neutron-fwaas-v2; then if [[ "$1" == "stack" && "$2" == "install" ]]; then # Perform installation of service source @@ -120,19 +106,11 @@ if is_service_enabled q-svc neutron-api && is_service_enabled q-fwaas q-fwaas-v1 # Configure after the other layer 1 and 2 services have been configured neutron_fwaas_configure_common neutron_fwaas_generate_config_files - if is_service_enabled q-fwaas-v1 neutron-fwaas-v1; then - echo_summary "Configuring neutron-fwaas for FWaaS v1" - configure_fwaas_v1 - elif is_service_enabled q-fwaas-v2 neutron-fwaas-v2; then - echo_summary "Configuring neutron-fwaas for FWaaS v2" - configure_fwaas_v2 - if is_service_enabled q-log neutron-log; then - echo_summary "Configuring FwaaS V2 packet log for l3 extension" - configure_l3_log_fwaas_v2 - fi - else - echo_summary "Configuring neutron-fwaas for FWaaS v1" - configure_fwaas_v1 + echo_summary "Configuring neutron-fwaas for FWaaS v2" + configure_fwaas_v2 + if is_service_enabled q-log neutron-log; then + echo_summary "Configuring FwaaS V2 packet log for l3 extension" + configure_l3_log_fwaas_v2 fi elif [[ "$1" == "stack" && "$2" == "extra" ]]; then diff --git a/devstack/settings b/devstack/settings index 824f97f75..ca5c98ff5 100644 --- a/devstack/settings +++ b/devstack/settings @@ -1,7 +1,5 @@ -FWAAS_DRIVER_V1=${FWAAS_DRIVER_V1:-iptables} FWAAS_DRIVER_V2=${FWAAS_DRIVER_V2:-iptables_v2} FW_L2_DRIVER=${FW_L2_DRIVER:-noop} -FWAAS_PLUGIN_V1=${FWAAS_PLUGIN:-firewall} FWAAS_PLUGIN_V2=${FWAAS_PLUGIN:-firewall_v2} NEUTRON_FWAAS_DIR=$DEST/neutron-fwaas diff --git a/neutron_fwaas/db/firewall/firewall_db.py b/neutron_fwaas/db/firewall/firewall_db.py index 82d70c174..f3d2018a5 100644 --- a/neutron_fwaas/db/firewall/firewall_db.py +++ b/neutron_fwaas/db/firewall/firewall_db.py @@ -13,38 +13,13 @@ # License for the specific language governing permissions and limitations # under the License. -import operator - -from neutron.db import common_db_mixin as base_db -from neutron.db.models import agent as agent_model -from neutron.db.models import l3agent as l3agent_model -from neutron_lib.callbacks import events -from neutron_lib.callbacks import registry -from neutron_lib.callbacks import resources -from neutron_lib import constants as nl_constants from neutron_lib.db import model_base -from neutron_lib.exceptions import firewall_v1 as f_exc -from neutron_lib.exceptions import l3 -from neutron_lib.plugins import directory -from oslo_config import cfg -from oslo_log import log as logging -from oslo_utils import uuidutils import sqlalchemy as sa from sqlalchemy.ext.orderinglist import ordering_list from sqlalchemy import orm -from sqlalchemy.orm import exc - -import netaddr - -from neutron_fwaas.common import fwaas_constants -from neutron_fwaas.db.firewall import firewall_router_insertion_db \ - as fw_r_ins_db -from neutron_fwaas.extensions import firewall as fw_ext - - -LOG = logging.getLogger(__name__) +# Note(annp): Keep firewall db v1 structure for migration class FirewallRule(model_base.BASEV2, model_base.HasId, model_base.HasProject): """Represents a Firewall rule.""" __tablename__ = 'firewall_rules' @@ -100,558 +75,15 @@ class FirewallPolicy(model_base.BASEV2, model_base.HasId, firewalls = orm.relationship(Firewall, backref='firewall_policies') -class Firewall_db_mixin(fw_ext.FirewallPluginBase, base_db.CommonDbMixin): - """Mixin class for Firewall DB implementation.""" +class FirewallRouterAssociation(model_base.BASEV2): - @property - def _core_plugin(self): - return directory.get_plugin() + """Tracks FW Router Association""" - def _get_firewall(self, context, id): - try: - return self._get_by_id(context, Firewall, id) - except exc.NoResultFound: - raise f_exc.FirewallNotFound(firewall_id=id) + __tablename__ = 'firewall_router_associations' - def _get_firewall_policy(self, context, id): - try: - return self._get_by_id(context, FirewallPolicy, id) - except exc.NoResultFound: - raise f_exc.FirewallPolicyNotFound(firewall_policy_id=id) - - def _get_firewall_rule(self, context, id): - try: - return self._get_by_id(context, FirewallRule, id) - except exc.NoResultFound: - raise f_exc.FirewallRuleNotFound(firewall_rule_id=id) - - def _make_firewall_dict(self, fw, fields=None): - res = {'id': fw['id'], - 'tenant_id': fw['tenant_id'], - 'name': fw['name'], - 'description': fw['description'], - 'shared': fw['shared'], - 'admin_state_up': fw['admin_state_up'], - 'status': fw['status'], - 'firewall_policy_id': fw['firewall_policy_id']} - return self._fields(res, fields) - - def _make_firewall_policy_dict(self, firewall_policy, fields=None): - fw_rules = [rule['id'] for rule in firewall_policy['firewall_rules']] - firewalls = [fw['id'] for fw in firewall_policy['firewalls']] - res = {'id': firewall_policy['id'], - 'tenant_id': firewall_policy['tenant_id'], - 'name': firewall_policy['name'], - 'description': firewall_policy['description'], - 'shared': firewall_policy['shared'], - 'audited': firewall_policy['audited'], - 'firewall_rules': fw_rules, - 'firewall_list': firewalls} - return self._fields(res, fields) - - def _make_firewall_rule_dict(self, firewall_rule, fields=None): - position = None - # We return the position only if the firewall_rule is bound to a - # firewall_policy. - if firewall_rule['firewall_policy_id']: - position = firewall_rule['position'] - src_port_range = self._get_port_range_from_min_max_ports( - firewall_rule['source_port_range_min'], - firewall_rule['source_port_range_max']) - dst_port_range = self._get_port_range_from_min_max_ports( - firewall_rule['destination_port_range_min'], - firewall_rule['destination_port_range_max']) - res = {'id': firewall_rule['id'], - 'tenant_id': firewall_rule['tenant_id'], - 'name': firewall_rule['name'], - 'description': firewall_rule['description'], - 'firewall_policy_id': firewall_rule['firewall_policy_id'], - 'shared': firewall_rule['shared'], - 'protocol': firewall_rule['protocol'], - 'ip_version': firewall_rule['ip_version'], - 'source_ip_address': firewall_rule['source_ip_address'], - 'destination_ip_address': - firewall_rule['destination_ip_address'], - 'source_port': src_port_range, - 'destination_port': dst_port_range, - 'action': firewall_rule['action'], - 'position': position, - 'enabled': firewall_rule['enabled']} - return self._fields(res, fields) - - def _make_firewall_dict_with_rules(self, context, firewall_id): - firewall = self.get_firewall(context, firewall_id) - fw_policy_id = firewall['firewall_policy_id'] - if fw_policy_id: - fw_rules_list = self.get_firewall_rules( - context, filters={'firewall_policy_id': [fw_policy_id]}) - fw_rules_list = sorted( - fw_rules_list, key=operator.itemgetter('position')) - firewall['firewall_rule_list'] = fw_rules_list - else: - firewall['firewall_rule_list'] = [] - # FIXME(Sumit): If the size of the firewall object we are creating - # here exceeds the largest message size supported by rabbit/qpid - # then we will have a problem. - return firewall - - def _check_firewall_rule_conflict(self, fwr_db, fwp_db): - if not fwr_db['shared']: - if fwr_db['tenant_id'] != fwp_db['tenant_id']: - raise f_exc.FirewallRuleConflict( - firewall_rule_id=fwr_db['id'], - project_id=fwr_db['tenant_id']) - - def _set_rules_for_policy(self, context, firewall_policy_db, fwp): - rule_id_list = fwp['firewall_rules'] - fwp_db = firewall_policy_db - with context.session.begin(subtransactions=True): - if not rule_id_list: - fwp_db.firewall_rules = [] - fwp_db.audited = False - return - # We will first check if the new list of rules is valid - filters = {'id': [r_id for r_id in rule_id_list]} - rules_in_db = self._get_collection_query(context, FirewallRule, - filters=filters) - rules_dict = dict((fwr_db['id'], fwr_db) for fwr_db in rules_in_db) - for fwrule_id in rule_id_list: - if fwrule_id not in rules_dict: - # If we find an invalid rule in the list we - # do not perform the update since this breaks - # the integrity of this list. - raise f_exc.FirewallRuleNotFound( - firewall_rule_id=fwrule_id) - elif rules_dict[fwrule_id]['firewall_policy_id']: - if (rules_dict[fwrule_id]['firewall_policy_id'] != - fwp_db['id']): - raise f_exc.FirewallRuleInUse( - firewall_rule_id=fwrule_id) - if 'shared' in fwp: - if fwp['shared'] and not rules_dict[fwrule_id]['shared']: - raise f_exc.FirewallRuleSharingConflict( - firewall_rule_id=fwrule_id, - firewall_policy_id=fwp_db['id']) - elif fwp_db['shared'] and not rules_dict[fwrule_id]['shared']: - raise f_exc.FirewallRuleSharingConflict( - firewall_rule_id=fwrule_id, - firewall_policy_id=fwp_db['id']) - for fwr_db in rules_in_db: - self._check_firewall_rule_conflict(fwr_db, fwp_db) - # New list of rules is valid so we will first reset the existing - # list and then add each rule in order. - # Note that the list could be empty in which case we interpret - # it as clearing existing rules. - fwp_db.firewall_rules = [] - for fwrule_id in rule_id_list: - fwp_db.firewall_rules.append(rules_dict[fwrule_id]) - fwp_db.firewall_rules.reorder() - fwp_db.audited = False - - def _check_unshared_rules_for_policy(self, fwp_db, fwp): - if fwp['shared']: - rules_in_db = fwp_db['firewall_rules'] - for fwr_db in rules_in_db: - if not fwr_db['shared']: - raise f_exc.FirewallPolicySharingConflict( - firewall_rule_id=fwr_db['id'], - firewall_policy_id=fwp_db['id']) - - def _process_rule_for_policy(self, context, firewall_policy_id, - firewall_rule_db, position): - with context.session.begin(subtransactions=True): - fwp_query = context.session.query( - FirewallPolicy).with_lockmode('update') - fwp_db = fwp_query.filter_by(id=firewall_policy_id).one() - if position: - # Note that although position numbering starts at 1, - # internal ordering of the list starts at 0, so we compensate. - fwp_db.firewall_rules.insert(position - 1, firewall_rule_db) - else: - fwp_db.firewall_rules.remove(firewall_rule_db) - fwp_db.firewall_rules.reorder() - fwp_db.audited = False - return self._make_firewall_policy_dict(fwp_db) - - def _get_min_max_ports_from_range(self, port_range): - if not port_range: - return [None, None] - min_port, sep, max_port = port_range.partition(":") - if not max_port: - max_port = min_port - self._validate_fwr_port_range(min_port, max_port) - return [int(min_port), int(max_port)] - - def _get_port_range_from_min_max_ports(self, min_port, max_port): - if not min_port: - return None - if min_port == max_port: - return str(min_port) - self._validate_fwr_port_range(min_port, max_port) - return '%s:%s' % (min_port, max_port) - - def _validate_fw_parameters(self, context, fw, fw_tenant_id): - if 'firewall_policy_id' not in fw: - return - fwp_id = fw['firewall_policy_id'] - fwp = self._get_firewall_policy(context, fwp_id) - if fw_tenant_id != fwp['tenant_id'] and not fwp['shared']: - raise f_exc.FirewallPolicyConflict(firewall_policy_id=fwp_id) - - def _validate_fwr_src_dst_ip_version(self, fwr): - src_version = dst_version = None - if fwr.get('source_ip_address', None): - src_version = netaddr.IPNetwork(fwr['source_ip_address']).version - if fwr.get('destination_ip_address', None): - dst_version = netaddr.IPNetwork( - fwr['destination_ip_address']).version - rule_ip_version = fwr.get('ip_version', None) - if ((src_version and src_version != rule_ip_version) or - (dst_version and dst_version != rule_ip_version)): - raise f_exc.FirewallIpAddressConflict() - - def _validate_fwr_port_range(self, min_port, max_port): - if int(min_port) > int(max_port): - port_range = '%s:%s' % (min_port, max_port) - raise f_exc.FirewallRuleInvalidPortValue(port=port_range) - - def _validate_fwr_protocol_parameters(self, fwr): - protocol = fwr.get('protocol', None) - if protocol not in (nl_constants.PROTO_NAME_TCP, - nl_constants.PROTO_NAME_UDP): - if (fwr.get('source_port', None) or - fwr.get('destination_port', None)): - raise f_exc.FirewallRuleInvalidICMPParameter( - param="Source, destination port") - - def create_firewall(self, context, firewall, status=None): - LOG.debug("create_firewall() called") - fw = firewall['firewall'] - tenant_id = fw['tenant_id'] - # distributed routers may required a more complex state machine; - # the introduction of a new 'CREATED' state allows this, whilst - # keeping a backward compatible behavior of the logical resource. - if not status: - status = (nl_constants.CREATED if cfg.CONF.router_distributed - else nl_constants.PENDING_CREATE) - with context.session.begin(subtransactions=True): - self._validate_fw_parameters(context, fw, tenant_id) - firewall_db = Firewall( - id=uuidutils.generate_uuid(), - tenant_id=tenant_id, - name=fw['name'], - description=fw['description'], - firewall_policy_id=fw['firewall_policy_id'], - admin_state_up=fw['admin_state_up'], - status=status) - context.session.add(firewall_db) - return self._make_firewall_dict(firewall_db) - - def update_firewall(self, context, id, firewall): - LOG.debug("update_firewall() called") - fw = firewall['firewall'] - with context.session.begin(subtransactions=True): - fw_db = self.get_firewall(context, id) - self._validate_fw_parameters(context, fw, fw_db['tenant_id']) - count = context.session.query(Firewall).filter_by(id=id).update(fw) - if not count: - raise f_exc.FirewallNotFound(firewall_id=id) - return self.get_firewall(context, id) - - def update_firewall_status(self, context, id, status, not_in=None): - """Conditionally update firewall status. - - Status transition is performed only if firewall is not in the specified - states as defined by 'not_in' list. - """ - # filter in_ wants iterable objects, None isn't. - not_in = not_in or [] - with context.session.begin(subtransactions=True): - return (context.session.query(Firewall). - filter(Firewall.id == id). - filter(~Firewall.status.in_(not_in)). - update({'status': status}, synchronize_session=False)) - - def delete_firewall(self, context, id): - LOG.debug("delete_firewall() called") - with context.session.begin(subtransactions=True): - # Note: Plugin should ensure that it's okay to delete if the - # firewall is active - count = context.session.query(Firewall).filter_by(id=id).delete() - if not count: - raise f_exc.FirewallNotFound(firewall_id=id) - - def get_firewall(self, context, id, fields=None): - LOG.debug("get_firewall() called") - fw = self._get_firewall(context, id) - return self._make_firewall_dict(fw, fields) - - def get_firewalls(self, context, filters=None, fields=None): - LOG.debug("get_firewalls() called") - return self._get_collection(context, Firewall, - self._make_firewall_dict, - filters=filters, fields=fields) - - def get_firewalls_count(self, context, filters=None): - LOG.debug("get_firewalls_count() called") - return self._get_collection_count(context, Firewall, - filters=filters) - - def create_firewall_policy(self, context, firewall_policy): - LOG.debug("create_firewall_policy() called") - fwp = firewall_policy['firewall_policy'] - with context.session.begin(subtransactions=True): - fwp_db = FirewallPolicy(id=uuidutils.generate_uuid(), - tenant_id=fwp['tenant_id'], - name=fwp['name'], - description=fwp['description'], - shared=fwp['shared']) - context.session.add(fwp_db) - self._set_rules_for_policy(context, fwp_db, fwp) - fwp_db.audited = fwp['audited'] - return self._make_firewall_policy_dict(fwp_db) - - def update_firewall_policy(self, context, id, firewall_policy): - LOG.debug("update_firewall_policy() called") - fwp = firewall_policy['firewall_policy'] - with context.session.begin(subtransactions=True): - fwp_db = self._get_firewall_policy(context, id) - # check tenant ids are same for fw and fwp or not - if not fwp.get('shared', True) and fwp_db.firewalls: - for fw in fwp_db['firewalls']: - if fwp_db['tenant_id'] != fw['tenant_id']: - raise f_exc.FirewallPolicyInUse( - firewall_policy_id=id) - # check any existing rules are not shared - if 'shared' in fwp and 'firewall_rules' not in fwp: - self._check_unshared_rules_for_policy(fwp_db, fwp) - elif 'firewall_rules' in fwp: - self._set_rules_for_policy(context, fwp_db, fwp) - del fwp['firewall_rules'] - if 'audited' not in fwp: - fwp['audited'] = False - fwp_db.update(fwp) - return self._make_firewall_policy_dict(fwp_db) - - def delete_firewall_policy(self, context, id): - LOG.debug("delete_firewall_policy() called") - with context.session.begin(subtransactions=True): - fwp = self._get_firewall_policy(context, id) - # Ensure that the firewall_policy is not - # being used - qry = context.session.query(Firewall) - if qry.filter_by(firewall_policy_id=id).first(): - raise f_exc.FirewallPolicyInUse(firewall_policy_id=id) - else: - context.session.delete(fwp) - - def get_firewall_policy(self, context, id, fields=None): - LOG.debug("get_firewall_policy() called") - fwp = self._get_firewall_policy(context, id) - return self._make_firewall_policy_dict(fwp, fields) - - def get_firewall_policies(self, context, filters=None, fields=None): - LOG.debug("get_firewall_policies() called") - return self._get_collection(context, FirewallPolicy, - self._make_firewall_policy_dict, - filters=filters, fields=fields) - - def get_firewalls_policies_count(self, context, filters=None): - LOG.debug("get_firewall_policies_count() called") - return self._get_collection_count(context, FirewallPolicy, - filters=filters) - - def create_firewall_rule(self, context, firewall_rule): - LOG.debug("create_firewall_rule() called") - fwr = firewall_rule['firewall_rule'] - self._validate_fwr_protocol_parameters(fwr) - self._validate_fwr_src_dst_ip_version(fwr) - if not fwr['protocol'] and (fwr['source_port'] or - fwr['destination_port']): - raise f_exc.FirewallRuleWithPortWithoutProtocolInvalid() - src_port_min, src_port_max = self._get_min_max_ports_from_range( - fwr['source_port']) - dst_port_min, dst_port_max = self._get_min_max_ports_from_range( - fwr['destination_port']) - with context.session.begin(subtransactions=True): - fwr_db = FirewallRule( - id=uuidutils.generate_uuid(), - tenant_id=fwr['tenant_id'], - name=fwr['name'], - description=fwr['description'], - shared=fwr['shared'], - protocol=fwr['protocol'], - ip_version=fwr['ip_version'], - source_ip_address=fwr['source_ip_address'], - destination_ip_address=fwr['destination_ip_address'], - source_port_range_min=src_port_min, - source_port_range_max=src_port_max, - destination_port_range_min=dst_port_min, - destination_port_range_max=dst_port_max, - action=fwr['action'], - enabled=fwr['enabled']) - context.session.add(fwr_db) - return self._make_firewall_rule_dict(fwr_db) - - def update_firewall_rule(self, context, id, firewall_rule): - LOG.debug("update_firewall_rule() called") - fwr = firewall_rule['firewall_rule'] - self._validate_fwr_protocol_parameters(fwr) - self._validate_fwr_src_dst_ip_version(fwr) - fwr_db = self._get_firewall_rule(context, id) - if fwr_db.firewall_policy_id: - fwp_db = self._get_firewall_policy(context, - fwr_db.firewall_policy_id) - if 'shared' in fwr and not fwr['shared']: - if fwr_db['tenant_id'] != fwp_db['tenant_id']: - raise f_exc.FirewallRuleInUse(firewall_rule_id=id) - if 'source_port' in fwr: - src_port_min, src_port_max = self._get_min_max_ports_from_range( - fwr['source_port']) - fwr['source_port_range_min'] = src_port_min - fwr['source_port_range_max'] = src_port_max - del fwr['source_port'] - if 'destination_port' in fwr: - dst_port_min, dst_port_max = self._get_min_max_ports_from_range( - fwr['destination_port']) - fwr['destination_port_range_min'] = dst_port_min - fwr['destination_port_range_max'] = dst_port_max - del fwr['destination_port'] - with context.session.begin(subtransactions=True): - protocol = fwr.get('protocol', fwr_db['protocol']) - if not protocol: - sport = fwr.get('source_port_range_min', - fwr_db['source_port_range_min']) - dport = fwr.get('destination_port_range_min', - fwr_db['destination_port_range_min']) - if sport or dport: - raise f_exc.FirewallRuleWithPortWithoutProtocolInvalid() - fwr_db.update(fwr) - if fwr_db.firewall_policy_id: - fwp_db.audited = False - return self._make_firewall_rule_dict(fwr_db) - - def delete_firewall_rule(self, context, id): - LOG.debug("delete_firewall_rule() called") - with context.session.begin(subtransactions=True): - fwr = self._get_firewall_rule(context, id) - if fwr.firewall_policy_id: - raise f_exc.FirewallRuleInUse(firewall_rule_id=id) - context.session.delete(fwr) - - def get_firewall_rule(self, context, id, fields=None): - LOG.debug("get_firewall_rule() called") - fwr = self._get_firewall_rule(context, id) - return self._make_firewall_rule_dict(fwr, fields) - - def get_firewall_rules(self, context, filters=None, fields=None): - LOG.debug("get_firewall_rules() called") - return self._get_collection(context, FirewallRule, - self._make_firewall_rule_dict, - filters=filters, fields=fields) - - def get_firewalls_rules_count(self, context, filters=None): - LOG.debug("get_firewall_rules_count() called") - return self._get_collection_count(context, FirewallRule, - filters=filters) - - def _validate_insert_remove_rule_request(self, id, rule_info): - if not rule_info or 'firewall_rule_id' not in rule_info: - raise f_exc.FirewallRuleInfoMissing() - - def insert_rule(self, context, id, rule_info): - LOG.debug("insert_rule() called") - self._validate_insert_remove_rule_request(id, rule_info) - firewall_rule_id = rule_info['firewall_rule_id'] - insert_before = True - ref_firewall_rule_id = None - if not firewall_rule_id: - raise f_exc.FirewallRuleNotFound(firewall_rule_id=None) - if 'insert_before' in rule_info: - ref_firewall_rule_id = rule_info['insert_before'] - if not ref_firewall_rule_id and 'insert_after' in rule_info: - # If insert_before is set, we will ignore insert_after. - ref_firewall_rule_id = rule_info['insert_after'] - insert_before = False - with context.session.begin(subtransactions=True): - fwr_db = self._get_firewall_rule(context, firewall_rule_id) - fwp_db = self._get_firewall_policy(context, id) - if fwr_db.firewall_policy_id: - raise f_exc.FirewallRuleInUse(firewall_rule_id=fwr_db['id']) - self._check_firewall_rule_conflict(fwr_db, fwp_db) - if ref_firewall_rule_id: - # If reference_firewall_rule_id is set, the new rule - # is inserted depending on the value of insert_before. - # If insert_before is set, the new rule is inserted before - # reference_firewall_rule_id, and if it is not set the new - # rule is inserted after reference_firewall_rule_id. - ref_fwr_db = self._get_firewall_rule( - context, ref_firewall_rule_id) - if ref_fwr_db.firewall_policy_id != id: - raise f_exc.FirewallRuleNotAssociatedWithPolicy( - firewall_rule_id=ref_fwr_db['id'], - firewall_policy_id=id) - if insert_before: - position = ref_fwr_db.position - else: - position = ref_fwr_db.position + 1 - else: - # If reference_firewall_rule_id is not set, it is assumed - # that the new rule needs to be inserted at the top. - # insert_before field is ignored. - # So default insertion is always at the top. - # Also note that position numbering starts at 1. - position = 1 - return self._process_rule_for_policy(context, id, fwr_db, - position) - - def remove_rule(self, context, id, rule_info): - LOG.debug("remove_rule() called") - self._validate_insert_remove_rule_request(id, rule_info) - firewall_rule_id = rule_info['firewall_rule_id'] - if not firewall_rule_id: - raise f_exc.FirewallRuleNotFound(firewall_rule_id=None) - with context.session.begin(subtransactions=True): - fwr_db = self._get_firewall_rule(context, firewall_rule_id) - if fwr_db.firewall_policy_id != id: - raise f_exc.FirewallRuleNotAssociatedWithPolicy( - firewall_rule_id=fwr_db['id'], - firewall_policy_id=id) - return self._process_rule_for_policy(context, id, fwr_db, None) - - def get_firewall_tenant_ids_on_host(self, context, host): - query = context.session.query(Firewall.tenant_id) - query = query.join(fw_r_ins_db.FirewallRouterAssociation) - query = query.join(l3agent_model.RouterL3AgentBinding, - l3agent_model.RouterL3AgentBinding.router_id == - fw_r_ins_db.FirewallRouterAssociation.router_id) - query = query.join(agent_model.Agent) - query = query.filter(agent_model.Agent.host == host) - query = query.distinct() - return [item[0] for item in query] - - -def migration_callback(resource, event, trigger, **kwargs): - context = kwargs['context'] - router = kwargs['router'] - fw_plugin = directory.get_plugin(fwaas_constants.FIREWALL) - if fw_plugin: - tenant_firewalls = fw_plugin.get_firewalls( - context, filters={'tenant_id': [router['tenant_id']]}) - if tenant_firewalls: - raise l3.RouterInUse(router_id=router['id']) - - -def subscribe(): - registry.subscribe( - migration_callback, resources.ROUTER, events.BEFORE_UPDATE) - -# NOTE(armax): multiple FW service plugins (potentially out of tree) may -# inherit from firewall_db and may need the callbacks to be processed. Having -# an implicit subscription (through the module import) preserves the existing -# behavior, and at the same time it avoids fixing it manually in each and -# every fw plugin out there. That said, The subscription is also made -# explicitly in the reference fw plugin. The subscription operation is -# idempotent so there is no harm in registering the same callback multiple -# times. -subscribe() + fw_id = sa.Column(sa.String(36), + sa.ForeignKey('firewalls.id', ondelete="CASCADE"), + primary_key=True) + router_id = sa.Column(sa.String(36), + sa.ForeignKey('routers.id', ondelete="CASCADE"), + primary_key=True) diff --git a/neutron_fwaas/db/firewall/firewall_router_insertion_db.py b/neutron_fwaas/db/firewall/firewall_router_insertion_db.py deleted file mode 100644 index 143f69968..000000000 --- a/neutron_fwaas/db/firewall/firewall_router_insertion_db.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright 2015 Cisco Systems 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. - -from neutron_lib.db import model_base -from neutron_lib.exceptions import firewall_v1 as fwrtrins -from oslo_log import helpers as log_helpers -from oslo_log import log as logging -import sqlalchemy as sa - - -LOG = logging.getLogger(__name__) - - -class FirewallRouterAssociation(model_base.BASEV2): - - """Tracks FW Router Association""" - - __tablename__ = 'firewall_router_associations' - - fw_id = sa.Column(sa.String(36), - sa.ForeignKey('firewalls.id', ondelete="CASCADE"), - primary_key=True) - router_id = sa.Column(sa.String(36), - sa.ForeignKey('routers.id', ondelete="CASCADE"), - primary_key=True) - - -class FirewallRouterInsertionDbMixin(object): - - """Access methods for the firewall_router_associations table.""" - - @log_helpers.log_method_call - def set_routers_for_firewall(self, context, fw): - """Sets the routers associated with the fw.""" - with context.session.begin(subtransactions=True): - for r_id in fw['router_ids']: - fw_rtr_db = FirewallRouterAssociation(fw_id=fw['fw_id'], - router_id=r_id) - context.session.add(fw_rtr_db) - - @log_helpers.log_method_call - def get_firewall_routers(self, context, fwid): - """Gets all routers associated with a firewall.""" - with context.session.begin(subtransactions=True): - fw_rtr_qry = context.session.query( - FirewallRouterAssociation.router_id) - fw_rtr_rows = fw_rtr_qry.filter_by(fw_id=fwid) - fw_rtrs = [entry.router_id for entry in fw_rtr_rows] - LOG.debug("get_firewall_routers(): fw_rtrs: %s", fw_rtrs) - return fw_rtrs - - @log_helpers.log_method_call - def validate_firewall_routers_not_in_use( - self, context, router_ids, fwid=None): - """Validate if router-ids not associated with any firewall. - - If any of the router-ids in the list is already associated with - a firewall, raise an exception else just return. - """ - fw_rtr_qry = context.session.query(FirewallRouterAssociation.router_id) - fw_rtrs = fw_rtr_qry.filter( - FirewallRouterAssociation.router_id.in_(router_ids), - FirewallRouterAssociation.fw_id != fwid).all() - if fw_rtrs: - router_ids = [entry.router_id for entry in fw_rtrs] - raise fwrtrins.FirewallRouterInUse(router_ids=router_ids) - - @log_helpers.log_method_call - def update_firewall_routers(self, context, fw): - """Update the firewall with new routers. - - This involves removing existing router associations and replacing - it with the new router associations provided in the update method. - """ - with context.session.begin(subtransactions=True): - fw_rtr_qry = context.session.query(FirewallRouterAssociation) - fw_rtr_qry.filter_by(fw_id=fw['fw_id']).delete() - if fw['router_ids']: - self.set_routers_for_firewall(context, fw) - - # TODO(sridar): Investigate potential corner case if rpc failure - # happens on PENDING_UPDATE and agent did not restart. Evaluate - # complexity vs benefit of holding on to old entries until ack - # from agent. - - return fw diff --git a/neutron_fwaas/db/models/head.py b/neutron_fwaas/db/models/head.py index 54830c613..49082f0d7 100644 --- a/neutron_fwaas/db/models/head.py +++ b/neutron_fwaas/db/models/head.py @@ -12,8 +12,6 @@ from neutron_lib.db import model_base -from neutron_fwaas.db.firewall import firewall_db # noqa -from neutron_fwaas.db.firewall import firewall_router_insertion_db # noqa from neutron_fwaas.db.firewall.v2 import firewall_db_v2 # noqa diff --git a/neutron_fwaas/policies/__init__.py b/neutron_fwaas/policies/__init__.py index 62edfe7b8..0f156640e 100644 --- a/neutron_fwaas/policies/__init__.py +++ b/neutron_fwaas/policies/__init__.py @@ -12,7 +12,6 @@ import itertools -from neutron_fwaas.policies import firewall from neutron_fwaas.policies import firewall_group from neutron_fwaas.policies import firewall_policy from neutron_fwaas.policies import firewall_rule @@ -20,7 +19,6 @@ from neutron_fwaas.policies import firewall_rule def list_rules(): return itertools.chain( - firewall.list_rules(), firewall_group.list_rules(), firewall_policy.list_rules(), firewall_rule.list_rules(), diff --git a/neutron_fwaas/policies/firewall.py b/neutron_fwaas/policies/firewall.py deleted file mode 100644 index ac528a43b..000000000 --- a/neutron_fwaas/policies/firewall.py +++ /dev/null @@ -1,113 +0,0 @@ -# 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 oslo_policy import policy - -from neutron_fwaas.policies import base - - -rules = [ - policy.RuleDefault( - 'shared_firewalls', - 'field:firewalls:shared=True', - '(FWaaS v1) Definition of shared firewalls' - ), - - policy.DocumentedRuleDefault( - 'create_firewall', - base.RULE_ANY, - '(FWaaS v1) Create a firewall', - [ - { - 'method': 'POST', - 'path': '/fw/firewalls', - }, - ] - ), - policy.DocumentedRuleDefault( - 'update_firewall', - base.RULE_ADMIN_OR_OWNER, - '(FWaaS v1) Update a firewall', - [ - { - 'method': 'PUT', - 'path': '/fw/firewalls/{id}', - }, - ] - ), - policy.DocumentedRuleDefault( - 'delete_firewall', - base.RULE_ADMIN_OR_OWNER, - '(FWaaS v1) Delete a firewall', - [ - { - 'method': 'DELETE', - 'path': '/fw/firewalls/{id}', - }, - ] - ), - - policy.DocumentedRuleDefault( - 'create_firewall:shared', - base.RULE_ADMIN_ONLY, - '(FWaaS v1) Create a shared firewall', - [ - { - 'method': 'POST', - 'path': '/fw/firewalls', - }, - ] - ), - policy.DocumentedRuleDefault( - 'update_firewall:shared', - base.RULE_ADMIN_ONLY, - '(FWaaS v1) Update ``shared`` attribute of a firewall', - [ - { - 'method': 'PUT', - 'path': '/fw/firewalls/{id}', - }, - ] - ), - # TODO(amotoki): Drop this rule as it has no effect. - policy.DocumentedRuleDefault( - 'delete_firewall:shared', - base.RULE_ADMIN_ONLY, - '(FWaaS v1) Delete a shared firewall', - [ - { - 'method': 'DELETE', - 'path': '/fw/firewalls/{id}', - }, - ] - ), - - policy.DocumentedRuleDefault( - 'get_firewall', - 'rule:admin_or_owner or rule:shared_firewalls', - '(FWaaS v1) Get firewalls', - [ - { - 'method': 'GET', - 'path': '/fw/firewalls', - }, - { - 'method': 'GET', - 'path': '/fw/firewalls/{id}', - }, - ] - ), -] - - -def list_rules(): - return rules diff --git a/neutron_fwaas/services/firewall/fwaas_plugin.py b/neutron_fwaas/services/firewall/fwaas_plugin.py deleted file mode 100644 index a9b0ece2b..000000000 --- a/neutron_fwaas/services/firewall/fwaas_plugin.py +++ /dev/null @@ -1,444 +0,0 @@ -# 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. - -from neutron import service -from neutron_lib.api.definitions import firewall as fw_ext -from neutron_lib.api import extensions -from neutron_lib import constants as nl_constants -from neutron_lib import context as neutron_context -from neutron_lib.exceptions import firewall_v1 as f_exc -from neutron_lib.plugins import constants as plugin_constants -from neutron_lib.plugins import directory -from neutron_lib import rpc as n_rpc -from oslo_config import cfg -from oslo_log import log as logging -import oslo_messaging - -from neutron_fwaas.common import fwaas_constants as f_const -from neutron_fwaas.db.firewall import firewall_db -from neutron_fwaas.db.firewall import firewall_router_insertion_db - - -LOG = logging.getLogger(__name__) - - -class FirewallCallbacks(object): - target = oslo_messaging.Target(version='1.0') - - def __init__(self, plugin): - super(FirewallCallbacks, self).__init__() - self.plugin = plugin - - def set_firewall_status(self, context, firewall_id, status, **kwargs): - """Agent uses this to set a firewall's status.""" - LOG.debug("Setting firewall %s to status: %s", firewall_id, status) - # Sanitize status first - if status in (nl_constants.ACTIVE, nl_constants.DOWN, - nl_constants.INACTIVE): - to_update = status - else: - to_update = nl_constants.ERROR - # ignore changing status if firewall expects to be deleted - # That case means that while some pending operation has been - # performed on the backend, neutron server received delete request - # and changed firewall status to PENDING_DELETE - updated = self.plugin.update_firewall_status( - context, firewall_id, to_update, - not_in=(nl_constants.PENDING_DELETE,)) - if updated: - LOG.debug("firewall %s status set: %s", firewall_id, to_update) - return updated and to_update != nl_constants.ERROR - - def firewall_deleted(self, context, firewall_id, **kwargs): - """Agent uses this to indicate firewall is deleted.""" - LOG.debug("firewall_deleted() called") - try: - with context.session.begin(subtransactions=True): - fw_db = self.plugin._get_firewall(context, firewall_id) - # allow to delete firewalls in ERROR state - if fw_db.status in (nl_constants.PENDING_DELETE, - nl_constants.ERROR): - self.plugin.delete_db_firewall_object(context, firewall_id) - return True - else: - LOG.warning('Firewall %(fw)s unexpectedly deleted by ' - 'agent, status was %(status)s', - {'fw': firewall_id, 'status': fw_db.status}) - fw_db.update({"status": nl_constants.ERROR}) - return False - except f_exc.FirewallNotFound: - LOG.info('Firewall %s already deleted', firewall_id) - return True - - def get_firewalls_for_tenant(self, context, **kwargs): - """Agent uses this to get all firewalls and rules for a tenant.""" - LOG.debug("get_firewalls_for_tenant() called") - fw_list = [] - for fw in self.plugin.get_firewalls(context): - fw_with_rules = self.plugin._make_firewall_dict_with_rules( - context, fw['id']) - if fw['status'] == nl_constants.PENDING_DELETE: - fw_with_rules['add-router-ids'] = [] - fw_with_rules['del-router-ids'] = fw['router_ids'] - else: - fw_with_rules['add-router-ids'] = fw['router_ids'] - fw_with_rules['del-router-ids'] = [] - fw_list.append(fw_with_rules) - return fw_list - - def get_tenants_with_firewalls(self, context, **kwargs): - """Agent uses this to get all tenants that have firewalls.""" - LOG.debug("get_tenants_with_firewalls() called") - host = kwargs['host'] - ctx = neutron_context.get_admin_context() - tenant_ids = self.plugin.get_firewall_tenant_ids_on_host(ctx, host) - return tenant_ids - - -class FirewallAgentApi(object): - """Plugin side of plugin to agent RPC API.""" - - def __init__(self, topic, host): - self.host = host - target = oslo_messaging.Target(topic=topic, version='1.0') - self.client = n_rpc.get_client(target) - - def _prepare_rpc_client(self, host=None): - if host: - return self.client.prepare(server=host) - else: - # historical behaviour (RPC broadcast) - return self.client.prepare(fanout=True) - - def create_firewall(self, context, firewall, host=None): - cctxt = self._prepare_rpc_client(host) - # TODO(blallau) host param is not used on agent side (to be removed) - cctxt.cast(context, 'create_firewall', firewall=firewall, - host=self.host) - - def update_firewall(self, context, firewall, host=None): - cctxt = self._prepare_rpc_client(host) - # TODO(blallau) host param is not used on agent side (to be removed) - cctxt.cast(context, 'update_firewall', firewall=firewall, - host=self.host) - - def delete_firewall(self, context, firewall, host=None): - cctxt = self._prepare_rpc_client(host) - # TODO(blallau) host param is not used on agent side (to be removed) - cctxt.cast(context, 'delete_firewall', firewall=firewall, - host=self.host) - - -class FirewallPlugin( - firewall_db.Firewall_db_mixin, - firewall_router_insertion_db.FirewallRouterInsertionDbMixin): - - """Implementation of the Neutron Firewall Service Plugin. - - This class manages the workflow of FWaaS request/response. - Most DB related works are implemented in class - firewall_db.Firewall_db_mixin. - """ - supported_extension_aliases = ["fwaas", "fwaasrouterinsertion"] - path_prefix = fw_ext.API_PREFIX - - def __init__(self): - """Do the initialization for the firewall service plugin here.""" - - self.agent_rpc = FirewallAgentApi( - f_const.FW_AGENT, - cfg.CONF.host - ) - firewall_db.subscribe() - - rpc_worker = service.RpcWorker([self], worker_process_count=0) - self.add_worker(rpc_worker) - - def start_rpc_listeners(self): - self.endpoints = [FirewallCallbacks(self)] - - self.conn = n_rpc.Connection() - self.conn.create_consumer( - f_const.FIREWALL_PLUGIN, self.endpoints, fanout=False) - return self.conn.consume_in_threads() - - def _get_hosts_to_notify(self, context, router_ids): - """Returns all hosts to send notification about firewall update""" - l3_plugin = directory.get_plugin(plugin_constants.L3) - no_broadcast = ( - extensions.is_extension_supported( - l3_plugin, nl_constants.L3_AGENT_SCHEDULER_EXT_ALIAS) and - getattr(l3_plugin, 'get_l3_agents_hosting_routers', False)) - if no_broadcast: - agents = l3_plugin.get_l3_agents_hosting_routers( - context, router_ids, admin_state_up=True, active=True) - return [a.host for a in agents] - - # NOTE(blallau): default: FirewallAgentAPI performs RPC broadcast - return [None] - - def _rpc_update_firewall(self, context, firewall_id): - status_update = {"firewall": {"status": nl_constants.PENDING_UPDATE}} - super(FirewallPlugin, self).update_firewall(context, firewall_id, - status_update) - fw_with_rules = self._make_firewall_dict_with_rules(context, - firewall_id) - # this is triggered on an update to fw rule or policy, no - # change in associated routers. - fw_update_rtrs = self.get_firewall_routers(context, firewall_id) - fw_with_rules['add-router-ids'] = fw_update_rtrs - fw_with_rules['del-router-ids'] = [] - - hosts = self._get_hosts_to_notify(context, fw_update_rtrs) - for host in hosts: - self.agent_rpc.update_firewall(context, fw_with_rules, - host=host) - - def _rpc_update_firewall_policy(self, context, firewall_policy_id): - firewall_policy = self.get_firewall_policy(context, firewall_policy_id) - if firewall_policy: - for firewall_id in firewall_policy['firewall_list']: - self._rpc_update_firewall(context, firewall_id) - - def _ensure_update_firewall(self, context, firewall_id): - fwall = self.get_firewall(context, firewall_id) - if fwall['status'] in [nl_constants.PENDING_CREATE, - nl_constants.PENDING_UPDATE, - nl_constants.PENDING_DELETE]: - raise f_exc.FirewallInPendingState(firewall_id=firewall_id, - pending_state=fwall['status']) - - def _ensure_update_firewall_policy(self, context, firewall_policy_id): - firewall_policy = self.get_firewall_policy(context, firewall_policy_id) - if firewall_policy and 'firewall_list' in firewall_policy: - for firewall_id in firewall_policy['firewall_list']: - self._ensure_update_firewall(context, firewall_id) - - def _ensure_update_firewall_rule(self, context, firewall_rule_id): - fw_rule = self.get_firewall_rule(context, firewall_rule_id) - if 'firewall_policy_id' in fw_rule and fw_rule['firewall_policy_id']: - self._ensure_update_firewall_policy(context, - fw_rule['firewall_policy_id']) - - def _get_routers_for_create_firewall(self, tenant_id, context, firewall): - # pop router_id as this goes in the router association db - # and not firewall db - router_ids = firewall['firewall'].pop('router_ids', None) - if router_ids == nl_constants.ATTR_NOT_SPECIFIED: - # old semantics router-ids keyword not specified pick up - # all routers on tenant. - l3_plugin = directory.get_plugin(plugin_constants.L3) - ctx = neutron_context.get_admin_context() - routers = l3_plugin.get_routers(ctx) - router_ids = [ - router['id'] - for router in routers - if router['tenant_id'] == tenant_id] - # validation can still fail this if there is another fw - # which is associated with one of these routers. - self.validate_firewall_routers_not_in_use(context, router_ids) - return router_ids - else: - if not router_ids: - # This indicates that user specifies no routers. - return [] - else: - # some router(s) provided. - self.validate_firewall_routers_not_in_use(context, router_ids) - return router_ids - - def create_firewall(self, context, firewall): - LOG.debug("create_firewall() called") - - fw_new_rtrs = self._get_routers_for_create_firewall( - firewall['firewall']['tenant_id'], context, firewall) - - if not fw_new_rtrs: - # no messaging to agent needed, and fw needs to go - # to INACTIVE(no associated rtrs) state. - status = nl_constants.INACTIVE - fw = super(FirewallPlugin, self).create_firewall( - context, firewall, status) - fw['router_ids'] = [] - return fw - else: - fw = super(FirewallPlugin, self).create_firewall( - context, firewall) - fw['router_ids'] = fw_new_rtrs - - fw_with_rules = ( - self._make_firewall_dict_with_rules(context, fw['id'])) - - fw_with_rtrs = {'fw_id': fw['id'], - 'router_ids': fw_new_rtrs} - self.set_routers_for_firewall(context, fw_with_rtrs) - fw_with_rules['add-router-ids'] = fw_new_rtrs - fw_with_rules['del-router-ids'] = [] - - hosts = self._get_hosts_to_notify(context, fw_new_rtrs) - for host in hosts: - self.agent_rpc.create_firewall(context, fw_with_rules, - host=host) - return fw - - def update_firewall(self, context, id, firewall): - LOG.debug("update_firewall() called on firewall %s", id) - - self._ensure_update_firewall(context, id) - # pop router_id as this goes in the router association db - # and not firewall db - router_ids = firewall['firewall'].pop('router_ids', None) - fw_current_rtrs = fw_new_rtrs = self.get_firewall_routers( - context, id) - if router_ids is not None: - if router_ids == []: - # This indicates that user is indicating no routers. - fw_new_rtrs = [] - else: - self.validate_firewall_routers_not_in_use( - context, router_ids, id) - fw_new_rtrs = router_ids - self.update_firewall_routers(context, {'fw_id': id, - 'router_ids': fw_new_rtrs}) - - if not fw_new_rtrs and not fw_current_rtrs: - # no messaging to agent needed, and we need to continue - # in INACTIVE state - firewall['firewall']['status'] = nl_constants.INACTIVE - fw = super(FirewallPlugin, self).update_firewall( - context, id, firewall) - fw['router_ids'] = [] - return fw - else: - firewall['firewall']['status'] = nl_constants.PENDING_UPDATE - fw = super(FirewallPlugin, self).update_firewall( - context, id, firewall) - fw['router_ids'] = fw_new_rtrs - - fw_with_rules = ( - self._make_firewall_dict_with_rules(context, fw['id'])) - - # determine rtrs to add fw to and del from - fw_with_rules['add-router-ids'] = fw_new_rtrs - fw_with_rules['del-router-ids'] = list( - set(fw_current_rtrs).difference(set(fw_new_rtrs))) - - # last-router drives agent to ack with status to set state to INACTIVE - fw_with_rules['last-router'] = not fw_new_rtrs - - LOG.debug("update_firewall %s: Add Routers: %s, Del Routers: %s", - fw['id'], - fw_with_rules['add-router-ids'], - fw_with_rules['del-router-ids']) - - hosts = self._get_hosts_to_notify(context, list( - set(fw_new_rtrs).union(set(fw_current_rtrs)))) - for host in hosts: - self.agent_rpc.update_firewall(context, fw_with_rules, - host=host) - return fw - - def delete_db_firewall_object(self, context, id): - super(FirewallPlugin, self).delete_firewall(context, id) - - def delete_firewall(self, context, id): - LOG.debug("delete_firewall() called on firewall %s", id) - fw_with_rules = ( - self._make_firewall_dict_with_rules(context, id)) - fw_delete_rtrs = self.get_firewall_routers(context, id) - fw_with_rules['del-router-ids'] = fw_delete_rtrs - fw_with_rules['add-router-ids'] = [] - if not fw_with_rules['del-router-ids']: - # no routers to delete on the agent side - self.delete_db_firewall_object(context, id) - else: - status = {"firewall": {"status": nl_constants.PENDING_DELETE}} - super(FirewallPlugin, self).update_firewall(context, id, status) - # Reflect state change in fw_with_rules - fw_with_rules['status'] = status['firewall']['status'] - hosts = self._get_hosts_to_notify(context, fw_delete_rtrs) - if hosts: - for host in hosts: - self.agent_rpc.delete_firewall(context, fw_with_rules, - host=host) - else: - # NOTE(blallau): we directly delete the firewall - # if router is not associated to an agent - self.delete_db_firewall_object(context, id) - - def update_firewall_policy(self, context, id, firewall_policy): - LOG.debug("update_firewall_policy() called") - self._ensure_update_firewall_policy(context, id) - fwp = super(FirewallPlugin, - self).update_firewall_policy(context, id, firewall_policy) - self._rpc_update_firewall_policy(context, id) - return fwp - - def update_firewall_rule(self, context, id, firewall_rule): - LOG.debug("update_firewall_rule() called") - self._ensure_update_firewall_rule(context, id) - fwr = super(FirewallPlugin, - self).update_firewall_rule(context, id, firewall_rule) - firewall_policy_id = fwr['firewall_policy_id'] - if firewall_policy_id: - self._rpc_update_firewall_policy(context, firewall_policy_id) - return fwr - - def _notify_firewall_updates(self, context, resource, update_info): - notifier = n_rpc.get_notifier('network') - notifier.info(context, resource, update_info) - - def insert_rule(self, context, id, rule_info): - LOG.debug("insert_rule() called") - self._ensure_update_firewall_policy(context, id) - fwp = super(FirewallPlugin, - self).insert_rule(context, id, rule_info) - self._rpc_update_firewall_policy(context, id) - resource = 'firewall_policy.update.insert_rule' - self._notify_firewall_updates(context, resource, rule_info) - return fwp - - def remove_rule(self, context, id, rule_info): - LOG.debug("remove_rule() called") - self._ensure_update_firewall_policy(context, id) - fwp = super(FirewallPlugin, - self).remove_rule(context, id, rule_info) - self._rpc_update_firewall_policy(context, id) - resource = 'firewall_policy.update.remove_rule' - self._notify_firewall_updates(context, resource, rule_info) - return fwp - - def get_firewalls(self, context, filters=None, fields=None): - LOG.debug("fwaas get_firewalls() called") - has_id_field = not fields or 'id' in fields - if not has_id_field: - fields = fields + ['id'] - fw_list = super(FirewallPlugin, self).get_firewalls( - context, filters, fields) - if not fields or 'router_ids' in fields: - for fw in fw_list: - fw['router_ids'] = self.get_firewall_routers(context, fw['id']) - if not has_id_field: - for fw in fw_list: - del fw['id'] - return fw_list - - def get_firewall(self, context, id, fields=None): - LOG.debug("fwaas get_firewall() called") - res = super(FirewallPlugin, self).get_firewall( - context, id, fields) - fw_current_rtrs = self.get_firewall_routers(context, id) - res['router_ids'] = fw_current_rtrs - return res diff --git a/neutron_fwaas/services/firewall/service_drivers/agents/drivers/linux/iptables_fwaas.py b/neutron_fwaas/services/firewall/service_drivers/agents/drivers/linux/iptables_fwaas.py deleted file mode 100644 index 523837af7..000000000 --- a/neutron_fwaas/services/firewall/service_drivers/agents/drivers/linux/iptables_fwaas.py +++ /dev/null @@ -1,431 +0,0 @@ -# Copyright 2013 Dell 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. - -from neutron.agent.linux import iptables_manager -from neutron.common import utils -from neutron_lib import constants -from neutron_lib.exceptions import firewall_v1 as f_exc -from oslo_log import log as logging - -from neutron_fwaas.common import fwaas_constants as f_const -from neutron_fwaas.services.firewall.service_drivers.agents.drivers import\ - conntrack_base -from neutron_fwaas.services.firewall.service_drivers.agents.drivers import\ - fwaas_base - - -LOG = logging.getLogger(__name__) -FWAAS_DRIVER_NAME = 'Fwaas iptables driver' -FWAAS_DEFAULT_CHAIN = 'fwaas-default-policy' - -FWAAS_TO_IPTABLE_ACTION_MAP = {'allow': 'ACCEPT', - 'deny': 'DROP', - 'reject': 'REJECT'} - -CHAIN_NAME_PREFIX = {constants.INGRESS_DIRECTION: 'i', - constants.EGRESS_DIRECTION: 'o'} - -""" Firewall rules are applied on internal-interfaces of Neutron router. - The packets ingressing tenant's network will be on the output - direction on internal-interfaces. -""" -IPTABLES_DIR = {constants.INGRESS_DIRECTION: '-o', - constants.EGRESS_DIRECTION: '-i'} -IPV4 = 'ipv4' -IPV6 = 'ipv6' -IP_VER_TAG = {IPV4: 'v4', - IPV6: 'v6'} - -INTERNAL_DEV_PREFIX = 'qr-' -SNAT_INT_DEV_PREFIX = 'sg-' -ROUTER_2_FIP_DEV_PREFIX = 'rfp-' - - -class IptablesFwaasDriver(fwaas_base.FwaasDriverBase): - """IPTables driver for Firewall As A Service.""" - - def __init__(self): - LOG.debug("Initializing fwaas iptables driver") - self.pre_firewall = None - self.conntrack = conntrack_base.load_and_init_conntrack_driver() - - def create_firewall(self, agent_mode, apply_list, firewall): - LOG.debug('Creating firewall %(fw_id)s for tenant %(tid)s', - {'fw_id': firewall['id'], 'tid': firewall['tenant_id']}) - try: - if firewall['admin_state_up']: - self._setup_firewall(agent_mode, apply_list, firewall) - self._remove_conntrack_new_firewall(agent_mode, - apply_list, firewall) - self.pre_firewall = dict(firewall) - else: - self.apply_default_policy(agent_mode, apply_list, firewall) - except (LookupError, RuntimeError): - # catch known library exceptions and raise Fwaas generic exception - LOG.exception("Failed to create firewall: %s", firewall['id']) - raise f_exc.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME) - - def _get_ipt_mgrs_with_if_prefix(self, agent_mode, router_info): - """Gets the iptables manager along with the if prefix to apply rules. - - With DVR we can have differing namespaces depending on which agent - (on Network or Compute node). Also, there is an associated i/f for - each namespace. The iptables on the relevant namespace and matching - i/f are provided. On the Network node we could have both the snat - namespace and a fip so this is provided back as a list - so in that - scenario rules can be applied on both. - """ - if not router_info.router.get('distributed'): - return [{'ipt': router_info.iptables_manager, - 'if_prefix': INTERNAL_DEV_PREFIX}] - ipt_mgrs = [] - # TODO(sridar): refactor to get strings to a common location. - if agent_mode == 'dvr_snat': - if router_info.snat_iptables_manager: - ipt_mgrs.append({'ipt': router_info.snat_iptables_manager, - 'if_prefix': SNAT_INT_DEV_PREFIX}) - if router_info.rtr_fip_connect: - # handle the fip case on n/w or compute node. - ipt_mgrs.append({'ipt': router_info.iptables_manager, - 'if_prefix': ROUTER_2_FIP_DEV_PREFIX}) - return ipt_mgrs - - def delete_firewall(self, agent_mode, apply_list, firewall): - LOG.debug('Deleting firewall %(fw_id)s for tenant %(tid)s', - {'fw_id': firewall['id'], 'tid': firewall['tenant_id']}) - fwid = firewall['id'] - try: - for router_info in apply_list: - ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix( - agent_mode, router_info) - for ipt_if_prefix in ipt_if_prefix_list: - ipt_mgr = ipt_if_prefix['ipt'] - self._remove_chains(fwid, ipt_mgr) - self._remove_default_chains(ipt_mgr) - # apply the changes immediately (no defer in firewall path) - ipt_mgr.defer_apply_off() - self.pre_firewall = None - except (LookupError, RuntimeError): - # catch known library exceptions and raise Fwaas generic exception - LOG.exception("Failed to delete firewall: %s", fwid) - raise f_exc.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME) - - def update_firewall(self, agent_mode, apply_list, firewall): - LOG.debug('Updating firewall %(fw_id)s for tenant %(tid)s', - {'fw_id': firewall['id'], 'tid': firewall['tenant_id']}) - try: - if firewall['admin_state_up']: - self._setup_firewall(agent_mode, apply_list, firewall) - if self.pre_firewall: - self._remove_conntrack_updated_firewall(agent_mode, - apply_list, self.pre_firewall, firewall) - else: - self._remove_conntrack_new_firewall(agent_mode, - apply_list, firewall) - else: - self.apply_default_policy(agent_mode, apply_list, firewall) - self.pre_firewall = dict(firewall) - except (LookupError, RuntimeError): - # catch known library exceptions and raise Fwaas generic exception - LOG.exception("Failed to update firewall: %s", firewall['id']) - raise f_exc.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME) - - def apply_default_policy(self, agent_mode, apply_list, firewall): - LOG.debug('Applying firewall %(fw_id)s for tenant %(tid)s', - {'fw_id': firewall['id'], 'tid': firewall['tenant_id']}) - fwid = firewall['id'] - try: - for router_info in apply_list: - ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix( - agent_mode, router_info) - for ipt_if_prefix in ipt_if_prefix_list: - # the following only updates local memory; no hole in FW - ipt_mgr = ipt_if_prefix['ipt'] - self._remove_chains(fwid, ipt_mgr) - self._remove_default_chains(ipt_mgr) - - # create default 'DROP ALL' policy chain - self._add_default_policy_chain_v4v6(ipt_mgr) - self._enable_policy_chain(fwid, ipt_if_prefix) - - # apply the changes immediately (no defer in firewall path) - ipt_mgr.defer_apply_off() - except (LookupError, RuntimeError): - # catch known library exceptions and raise Fwaas generic exception - LOG.exception( - "Failed to apply default policy on firewall: %s", fwid) - raise f_exc.FirewallInternalDriverError(driver=FWAAS_DRIVER_NAME) - - def _setup_firewall(self, agent_mode, apply_list, firewall): - fwid = firewall['id'] - for router_info in apply_list: - ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix( - agent_mode, router_info) - for ipt_if_prefix in ipt_if_prefix_list: - ipt_mgr = ipt_if_prefix['ipt'] - # the following only updates local memory; no hole in FW - self._remove_chains(fwid, ipt_mgr) - self._remove_default_chains(ipt_mgr) - - # create default 'DROP ALL' policy chain - self._add_default_policy_chain_v4v6(ipt_mgr) - #create chain based on configured policy - self._setup_chains(firewall, ipt_if_prefix) - - # apply the changes immediately (no defer in firewall path) - ipt_mgr.defer_apply_off() - - def _get_chain_name(self, fwid, ver, direction): - return '%s%s%s' % (CHAIN_NAME_PREFIX[direction], - IP_VER_TAG[ver], - fwid) - - def _setup_chains(self, firewall, ipt_if_prefix): - """Create Fwaas chain using the rules in the policy - """ - fw_rules_list = firewall['firewall_rule_list'] - fwid = firewall['id'] - ipt_mgr = ipt_if_prefix['ipt'] - - #default rules for invalid packets and established sessions - invalid_rule = self._drop_invalid_packets_rule() - est_rule = self._allow_established_rule() - - for ver in [IPV4, IPV6]: - if ver == IPV4: - table = ipt_mgr.ipv4['filter'] - else: - table = ipt_mgr.ipv6['filter'] - ichain_name = self._get_chain_name( - fwid, ver, constants.INGRESS_DIRECTION) - ochain_name = self._get_chain_name( - fwid, ver, constants.EGRESS_DIRECTION) - for name in [ichain_name, ochain_name]: - table.add_chain(name) - table.add_rule(name, invalid_rule) - table.add_rule(name, est_rule) - - for rule in fw_rules_list: - if not rule['enabled']: - continue - iptbl_rule = self._convert_fwaas_to_iptables_rule(rule) - if rule['ip_version'] == 4: - ver = IPV4 - table = ipt_mgr.ipv4['filter'] - else: - ver = IPV6 - table = ipt_mgr.ipv6['filter'] - ichain_name = self._get_chain_name( - fwid, ver, constants.INGRESS_DIRECTION) - ochain_name = self._get_chain_name( - fwid, ver, constants.EGRESS_DIRECTION) - table.add_rule(ichain_name, iptbl_rule) - table.add_rule(ochain_name, iptbl_rule) - self._enable_policy_chain(fwid, ipt_if_prefix) - - def _find_changed_rules(self, pre_firewall, firewall): - """Find the rules changed between the current firewall - and the updating rule - """ - changed_rules = [] - fw_rules_list = firewall[f_const.FIREWALL_RULE_LIST] - pre_fw_rules_list = pre_firewall[f_const.FIREWALL_RULE_LIST] - for pre_fw_rule in pre_fw_rules_list: - for fw_rule in fw_rules_list: - if (pre_fw_rule.get('id') == fw_rule.get('id') and - pre_fw_rule != fw_rule): - changed_rules.append(pre_fw_rule) - changed_rules.append(fw_rule) - return changed_rules - - def _find_removed_rules(self, pre_firewall, firewall): - fw_rules_list = firewall[f_const.FIREWALL_RULE_LIST] - pre_fw_rules_list = pre_firewall[f_const.FIREWALL_RULE_LIST] - fw_rule_ids = [fw_rule.get('id') for fw_rule in fw_rules_list] - removed_rules = [pre_fw_rule for pre_fw_rule in - pre_fw_rules_list if pre_fw_rule.get('id') not in fw_rule_ids] - return removed_rules - - def _find_new_rules(self, pre_firewall, firewall): - return self._find_removed_rules(firewall, pre_firewall) - - def _remove_conntrack_new_firewall(self, agent_mode, apply_list, firewall): - """Remove conntrack when create new firewall""" - routers_list = list(set(apply_list)) - for router_info in routers_list: - ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix( - agent_mode, router_info) - for ipt_if_prefix in ipt_if_prefix_list: - ipt_mgr = ipt_if_prefix['ipt'] - self.conntrack.flush_entries(ipt_mgr.namespace) - - def _remove_conntrack_updated_firewall(self, agent_mode, - apply_list, pre_firewall, firewall): - """Remove conntrack when updated firewall""" - router_list = list(set(apply_list)) - for router_info in router_list: - ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix( - agent_mode, router_info) - for ipt_if_prefix in ipt_if_prefix_list: - ipt_mgr = ipt_if_prefix['ipt'] - ch_rules = self._find_changed_rules(pre_firewall, - firewall) - i_rules = self._find_new_rules(pre_firewall, firewall) - r_rules = self._find_removed_rules(pre_firewall, firewall) - removed_conntrack_rules_list = ch_rules + i_rules + r_rules - self.conntrack.delete_entries(removed_conntrack_rules_list, - ipt_mgr.namespace) - - def _remove_default_chains(self, nsid): - """Remove fwaas default policy chain.""" - self._remove_chain_by_name(IPV4, FWAAS_DEFAULT_CHAIN, nsid) - self._remove_chain_by_name(IPV6, FWAAS_DEFAULT_CHAIN, nsid) - - def _remove_chains(self, fwid, ipt_mgr): - """Remove fwaas policy chain.""" - for ver in [IPV4, IPV6]: - for direction in [constants.INGRESS_DIRECTION, - constants.EGRESS_DIRECTION]: - chain_name = self._get_chain_name(fwid, ver, direction) - self._remove_chain_by_name(ver, chain_name, ipt_mgr) - - def _add_default_policy_chain_v4v6(self, ipt_mgr): - ipt_mgr.ipv4['filter'].add_chain(FWAAS_DEFAULT_CHAIN) - ipt_mgr.ipv4['filter'].add_rule(FWAAS_DEFAULT_CHAIN, '-j DROP') - ipt_mgr.ipv6['filter'].add_chain(FWAAS_DEFAULT_CHAIN) - ipt_mgr.ipv6['filter'].add_rule(FWAAS_DEFAULT_CHAIN, '-j DROP') - - def _remove_chain_by_name(self, ver, chain_name, ipt_mgr): - if ver == IPV4: - ipt_mgr.ipv4['filter'].remove_chain(chain_name) - else: - ipt_mgr.ipv6['filter'].remove_chain(chain_name) - - def _add_rules_to_chain(self, ipt_mgr, ver, chain_name, rules): - if ver == IPV4: - table = ipt_mgr.ipv4['filter'] - else: - table = ipt_mgr.ipv6['filter'] - for rule in rules: - table.add_rule(chain_name, rule) - - def _enable_policy_chain(self, fwid, ipt_if_prefix): - bname = iptables_manager.binary_name - ipt_mgr = ipt_if_prefix['ipt'] - if_prefix = ipt_if_prefix['if_prefix'] - - for (ver, tbl) in [(IPV4, ipt_mgr.ipv4['filter']), - (IPV6, ipt_mgr.ipv6['filter'])]: - for direction in [constants.INGRESS_DIRECTION, - constants.EGRESS_DIRECTION]: - chain_name = self._get_chain_name(fwid, ver, direction) - chain_name = iptables_manager.get_chain_name(chain_name) - if chain_name in tbl.chains: - jump_rule = ['%s %s+ -j %s-%s' % (IPTABLES_DIR[direction], - if_prefix, bname, chain_name)] - self._add_rules_to_chain(ipt_mgr, - ver, 'FORWARD', jump_rule) - - #jump to DROP_ALL policy - chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN) - jump_rule = ['-o %s+ -j %s-%s' % (if_prefix, bname, chain_name)] - self._add_rules_to_chain(ipt_mgr, IPV4, 'FORWARD', jump_rule) - self._add_rules_to_chain(ipt_mgr, IPV6, 'FORWARD', jump_rule) - - #jump to DROP_ALL policy - chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN) - jump_rule = ['-i %s+ -j %s-%s' % (if_prefix, bname, chain_name)] - self._add_rules_to_chain(ipt_mgr, IPV4, 'FORWARD', jump_rule) - self._add_rules_to_chain(ipt_mgr, IPV6, 'FORWARD', jump_rule) - - def _convert_fwaas_to_iptables_rule(self, rule): - action = FWAAS_TO_IPTABLE_ACTION_MAP[rule.get('action')] - - # Output ordering is important here as it must exactly match what - # is returned by iptables-save. If not we risk unnecessarily removing - # and readding rules. - args = [] - - args += self._protocol_arg(rule.get('protocol')) - - args += self._ip_prefix_arg('s', rule.get('source_ip_address')) - args += self._ip_prefix_arg('d', rule.get('destination_ip_address')) - - # iptables adds '-m protocol' when any source - # or destination port number is specified - if (rule.get('source_port') is not None or - rule.get('destination_port') is not None): - args += self._match_arg(rule.get('protocol')) - - args += self._port_arg('sport', - rule.get('protocol'), - rule.get('source_port')) - - args += self._port_arg('dport', - rule.get('protocol'), - rule.get('destination_port')) - - args += self._action_arg(action) - - iptables_rule = ' '.join(args) - return iptables_rule - - def _drop_invalid_packets_rule(self): - return '-m state --state INVALID -j DROP' - - def _allow_established_rule(self): - return '-m state --state RELATED,ESTABLISHED -j ACCEPT' - - def _action_arg(self, action): - if not action: - return [] - - args = ['-j', action] - - return args - - def _protocol_arg(self, protocol): - if not protocol: - return [] - - args = ['-p', protocol] - - return args - - def _match_arg(self, protocol): - if not protocol: - return [] - - protocol_modules = {'udp': 'udp', 'tcp': 'tcp', - 'icmp': 'icmp', 'ipv6-icmp': 'icmp6'} - # iptables adds '-m protocol' when the port number is specified - args = ['-m', protocol_modules[protocol]] - - return args - - def _port_arg(self, direction, protocol, port): - if protocol not in ['udp', 'tcp'] or port is None: - return [] - - args = ['--%s' % direction, '%s' % port] - - return args - - def _ip_prefix_arg(self, direction, ip_prefix): - if not(ip_prefix): - return [] - - args = ['-%s' % direction, '%s' % utils.ip_to_cidr(ip_prefix)] - return args diff --git a/neutron_fwaas/services/firewall/service_drivers/agents/l3reference/firewall_l3_agent.py b/neutron_fwaas/services/firewall/service_drivers/agents/l3reference/firewall_l3_agent.py deleted file mode 100644 index bfa5db4d1..000000000 --- a/neutron_fwaas/services/firewall/service_drivers/agents/l3reference/firewall_l3_agent.py +++ /dev/null @@ -1,428 +0,0 @@ -# Copyright (c) 2013 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 neutron_lib.agent import l3_extension -from neutron_lib import constants as nl_constants -from neutron_lib import context -from neutron_lib.exceptions import firewall_v1 as fw_ext -from neutron_lib import rpc as n_rpc -from oslo_config import cfg -from oslo_log import helpers as log_helpers -from oslo_log import log as logging - -from neutron_fwaas.common import fwaas_constants -from neutron_fwaas.common import resources as f_resources -from neutron_fwaas.services.firewall.service_drivers.agents \ - import firewall_agent_api as api -from neutron_fwaas.services.firewall.service_drivers.agents \ - import firewall_service - -LOG = logging.getLogger(__name__) - -#TODO(njohnston): There needs to be some extrapolation of the common code -# between this module and firewall_l3_agent_v2.py. - - -class FWaaSL3PluginApi(api.FWaaSPluginApiMixin): - """Agent side of the FWaaS agent to FWaaS Plugin RPC API.""" - def __init__(self, topic, host): - super(FWaaSL3PluginApi, self).__init__(topic, host) - - def get_firewalls_for_tenant(self, context, **kwargs): - """Get the Firewalls with rules from the Plugin to send to driver.""" - LOG.debug("Retrieve Firewall with rules from Plugin") - cctxt = self.client.prepare() - return cctxt.call(context, 'get_firewalls_for_tenant', host=self.host) - - def get_tenants_with_firewalls(self, context, **kwargs): - """Get all Tenants that have Firewalls configured from plugin.""" - LOG.debug("Retrieve Tenants with Firewalls configured from Plugin") - cctxt = self.client.prepare() - return cctxt.call(context, - 'get_tenants_with_firewalls', host=self.host) - - -class FWaaSL3AgentExtension(l3_extension.L3AgentExtension): - """FWaaS Agent support to be used by Neutron L3 agent.""" - - SUPPORTED_RESOURCE_TYPES = [f_resources.FIREWALL_GROUP, - f_resources.FIREWALL_POLICY, - f_resources.FIREWALL_RULE] - - def initialize(self, connection, driver_type): - self._register_rpc_consumers(connection) - - def consume_api(self, agent_api): - LOG.debug("FWaaS consume_api call occurred with %s", agent_api) - self.agent_api = agent_api - - def _register_rpc_consumers(self, connection): - #TODO(njohnston): Add RPC consumer connection loading here. - pass - - def start_rpc_listeners(self, conf): - self.endpoints = [self] - - self.conn = n_rpc.Connection() - self.conn.create_consumer( - fwaas_constants.FW_AGENT, self.endpoints, fanout=False) - return self.conn.consume_in_threads() - - def __init__(self, host, conf): - LOG.debug("Initializing firewall agent") - self.agent_api = None - self.neutron_service_plugins = None - self.conf = conf - self.fwaas_enabled = cfg.CONF.fwaas.enabled - self.start_rpc_listeners(conf) - - # None means l3-agent has no information on the server - # configuration due to the lack of RPC support. - if self.neutron_service_plugins is not None: - fwaas_plugin_configured = (fwaas_constants.FIREWALL - in self.neutron_service_plugins) - if fwaas_plugin_configured and not self.fwaas_enabled: - msg = ("FWaaS plugin is configured in the server side, but " - "FWaaS is disabled in L3-agent.") - LOG.error(msg) - raise SystemExit(1) - self.fwaas_enabled = self.fwaas_enabled and fwaas_plugin_configured - - if self.fwaas_enabled: - # NOTE: Temp location for creating service and loading driver - self.fw_service = firewall_service.FirewallService() - self.fwaas_driver = self.fw_service.load_device_drivers() - self.services_sync_needed = False - # setup RPC to msg fwaas plugin - self.fwplugin_rpc = FWaaSL3PluginApi(fwaas_constants.FIREWALL_PLUGIN, - host) - - def _has_router_insertion_fields(self, fw): - return 'add-router-ids' in fw - - def _get_router_ids_for_fw(self, context, fw, to_delete=False): - """Return the router_ids either from fw dict or tenant routers.""" - if self._has_router_insertion_fields(fw): - # it is a new version of plugin - return (fw['del-router-ids'] if to_delete - else fw['add-router-ids']) - else: - return [router['id'] for router in - self.agent_api.get_routers_in_project(fw['tenant_id'])] - - def _get_routers_in_project(self, project_id): - if self.agent_api is None: - LOG.exception("FWaaS RPC call failed; L3 agent_api failure") - return self.agent_api.get_routers_in_project(project_id) - - def _get_router_info_list_for_tenant(self, router_ids, tenant_id): - """Returns the list of router info objects on which to apply the fw.""" - return [ri for ri in self._get_routers_in_project(tenant_id) - if ri.router_id in router_ids and - self.agent_api.is_router_in_namespace(ri.router_id)] - - def _invoke_driver_for_sync_from_plugin(self, ctx, router_info_list, fw): - """Invoke the delete driver method for status of PENDING_DELETE and - update method for all other status to (re)apply on driver which is - Idempotent. - """ - if fw['status'] == nl_constants.PENDING_DELETE: - try: - self.fwaas_driver.delete_firewall( - self.conf.agent_mode, - router_info_list, - fw) - self.fwplugin_rpc.firewall_deleted( - ctx, - fw['id']) - except fw_ext.FirewallInternalDriverError: - LOG.error("Firewall Driver Error on fw state %(fwmsg)s " - "for fw: %(fwid)s", - {'fwmsg': fw['status'], 'fwid': fw['id']}) - self.fwplugin_rpc.set_firewall_status( - ctx, - fw['id'], - nl_constants.ERROR) - else: - # PENDING_UPDATE, PENDING_CREATE, ... - try: - self.fwaas_driver.update_firewall( - self.conf.agent_mode, - router_info_list, - fw) - if fw['admin_state_up']: - status = nl_constants.ACTIVE - else: - status = nl_constants.DOWN - except fw_ext.FirewallInternalDriverError: - LOG.error("Firewall Driver Error on fw state %(fwmsg)s " - "for fw: %(fwid)s", - {'fwmsg': fw['status'], 'fwid': fw['id']}) - status = nl_constants.ERROR - - self.fwplugin_rpc.set_firewall_status( - ctx, - fw['id'], - status) - - def _process_router_add(self, router): - """On router add, get fw with rules from plugin and update driver.""" - LOG.debug("Process router add, router_id: '%s'", router['id']) - router_ids = router['id'] - router_info_list = self._get_router_info_list_for_tenant( - [router_ids], - router['tenant_id']) - if router_info_list: - # Get the firewall with rules - # for the tenant the router is on. - ctx = context.Context('', router['tenant_id']) - fw_list = self.fwplugin_rpc.get_firewalls_for_tenant(ctx) - for fw in fw_list: - if self._has_router_insertion_fields(fw): - # if router extension present apply only if router in fw - if (not (router_ids in fw['add-router-ids']) and - not (router_ids in fw['del-router-ids'])): - continue - self._invoke_driver_for_sync_from_plugin( - ctx, - router_info_list, - fw) - # router can be present only on one fw - return - - def add_router(self, context, new_router): - """On router add, get fw with rules from plugin and update driver. - - Handles agent restart, when a router is added, query the plugin to - check if this router is in the router list for any firewall. If so - install firewall rules on this router. - """ - # avoid msg to plugin when fwaas is not configured - if not self.fwaas_enabled: - return - try: - self._process_router_add(new_router) - except Exception: - LOG.exception( - "FWaaS RPC info call failed for '%s'.", new_router['id']) - self.services_sync_needed = True - - def update_router(self, context, updated_router): - """The update_router method is just a synonym for add_router""" - self.add_router(context, updated_router) - - def delete_router(self, context, new_router): - """Handles router deletion. There is basically nothing to do for this - in the context of FWaaS with an IPTables driver; the namespace will - already have been deleted, taking the IPTables rules with it. - """ - #TODO(njohnston): When another firewall driver is implemented, look at - # expanding this out so that the driver can handle deletion calls. - pass - - def process_services_sync(self, ctx): - if not self.services_sync_needed: - return - - """On RPC issues sync with plugin and apply the sync data.""" - # avoid msg to plugin when fwaas is not configured - if not self.fwaas_enabled: - return - try: - # get the list of tenants with firewalls configured - # from the plugin - tenant_ids = self.fwplugin_rpc.get_tenants_with_firewalls(ctx) - LOG.debug("Tenants with Firewalls: '%s'", tenant_ids) - for tenant_id in tenant_ids: - ctx = context.Context('', tenant_id) - fw_list = self.fwplugin_rpc.get_firewalls_for_tenant(ctx) - for fw in fw_list: - if fw['status'] == nl_constants.PENDING_DELETE: - self.delete_firewall(ctx, fw, self.host) - # no need to apply sync data for ACTIVE fw - elif fw['status'] != nl_constants.ACTIVE: - self.update_firewall(ctx, fw, self.host) - self.services_sync_needed = False - except Exception: - LOG.exception("Failed fwaas process services sync") - self.services_sync_needed = True - - @log_helpers.log_method_call - def create_firewall(self, context, firewall, host): - """Handle Rpc from plugin to create a firewall.""" - - router_ids = self._get_router_ids_for_fw(context, firewall) - if not router_ids: - return - router_info_list = self._get_router_info_list_for_tenant( - router_ids, - firewall['tenant_id']) - LOG.debug("Create: Add firewall on Router List: '%s'", - [ri.router['id'] for ri in router_info_list]) - # call into the driver - try: - self.fwaas_driver.create_firewall( - self.conf.agent_mode, - router_info_list, - firewall) - if firewall['admin_state_up']: - status = nl_constants.ACTIVE - else: - status = nl_constants.DOWN - except fw_ext.FirewallInternalDriverError: - LOG.error("Firewall Driver Error for create_firewall " - "for firewall: %s", firewall['id']) - status = nl_constants.ERROR - - try: - # send status back to plugin - self.fwplugin_rpc.set_firewall_status( - context, - firewall['id'], - status) - except Exception: - LOG.exception("FWaaS RPC failure in create_firewall " - "for firewall: %s", firewall['id']) - self.services_sync_needed = True - - @log_helpers.log_method_call - def update_firewall(self, context, firewall, host): - """Handle Rpc from plugin to update a firewall.""" - - status = "" - if self._has_router_insertion_fields(firewall): - # with the router_ids extension, we may need to delete and add - # based on the list of routers. On the older version, we just - # update (add) all routers on the tenant - delete not needed. - router_ids = self._get_router_ids_for_fw( - context, firewall, to_delete=True) - if router_ids: - router_info_list = self._get_router_info_list_for_tenant( - router_ids, - firewall['tenant_id']) - # remove the firewall from this set of routers - # but no ack sent yet, check if we need to add - LOG.debug("Update: Delete firewall on Router List: '%s'", - [ri.router['id'] for ri in router_info_list]) - try: - self.fwaas_driver.delete_firewall( - self.conf.agent_mode, - router_info_list, - firewall) - if firewall['last-router']: - status = nl_constants.INACTIVE - elif firewall['admin_state_up']: - status = nl_constants.ACTIVE - else: - status = nl_constants.DOWN - except fw_ext.FirewallInternalDriverError: - LOG.error( - "Firewall Driver Error for " - "update_firewall for firewall: %s", firewall['id']) - status = nl_constants.ERROR - - # handle the add router and/or rule, policy, firewall - # attribute updates - if status not in (nl_constants.ERROR, nl_constants.INACTIVE): - router_ids = self._get_router_ids_for_fw(context, firewall) - if router_ids or firewall['router_ids']: - router_info_list = self._get_router_info_list_for_tenant( - router_ids + firewall['router_ids'], - firewall['tenant_id']) - LOG.debug("Update: Add firewall on Router List: '%s'", - [ri.router['id'] for ri in router_info_list]) - # call into the driver - try: - self.fwaas_driver.update_firewall( - self.conf.agent_mode, - router_info_list, - firewall) - if firewall['admin_state_up']: - status = nl_constants.ACTIVE - else: - status = nl_constants.DOWN - except fw_ext.FirewallInternalDriverError: - LOG.error( - "Firewall Driver Error for " - "update_firewall for firewall: %s", firewall['id']) - status = nl_constants.ERROR - else: - status = nl_constants.INACTIVE - try: - # send status back to plugin - self.fwplugin_rpc.set_firewall_status( - context, - firewall['id'], - status) - except Exception: - LOG.exception("FWaaS RPC failure in update_firewall " - "for firewall: %s", firewall['id']) - self.services_sync_needed = True - - @log_helpers.log_method_call - def delete_firewall(self, context, firewall, host): - """Handle Rpc from plugin to delete a firewall.""" - - router_ids = self._get_router_ids_for_fw( - context, firewall, to_delete=True) - if router_ids: - router_info_list = self._get_router_info_list_for_tenant( - router_ids, - firewall['tenant_id']) - LOG.debug( - "Delete firewall %(fw)s on routers: '%(routers)s'", - {'fw': firewall['id'], - 'routers': [ri.router['id'] for ri in router_info_list]}) - # call into the driver - try: - self.fwaas_driver.delete_firewall( - self.conf.agent_mode, - router_info_list, - firewall) - if firewall['admin_state_up']: - status = nl_constants.ACTIVE - else: - status = nl_constants.DOWN - except fw_ext.FirewallInternalDriverError: - LOG.error("Firewall Driver Error for delete_firewall " - "for firewall: %s", firewall['id']) - status = nl_constants.ERROR - - try: - # send status back to plugin - if status in [nl_constants.ACTIVE, nl_constants.DOWN]: - self.fwplugin_rpc.firewall_deleted(context, firewall['id']) - else: - self.fwplugin_rpc.set_firewall_status( - context, - firewall['id'], - status) - except Exception: - LOG.exception("FWaaS RPC failure in delete_firewall " - "for firewall: %s", firewall['id']) - self.services_sync_needed = True - - def ha_state_change(self, context, data): - pass - - -class L3WithFWaaS(FWaaSL3AgentExtension): - - def __init__(self, conf=None): - if conf: - self.conf = conf - else: - self.conf = cfg.CONF - super(L3WithFWaaS, self).__init__(host=self.conf.host, conf=self.conf) diff --git a/neutron_fwaas/tests/functional/db/test_migrations.py b/neutron_fwaas/tests/functional/db/test_migrations.py index 37099c451..9b3fcb3f0 100644 --- a/neutron_fwaas/tests/functional/db/test_migrations.py +++ b/neutron_fwaas/tests/functional/db/test_migrations.py @@ -22,9 +22,10 @@ from neutron_fwaas.db.models import head # EXTERNAL_TABLES should contain all names of tables that are not related to # current repo. -EXTERNAL_TABLES = set(external.TABLES) - set(external.FWAAS_TABLES) +EXTERNAL_TABLES = set(external.TABLES) # Model moved to vendor repo EXTERNAL_TABLES.update({'cisco_firewall_associations'}) +EXTERNAL_TABLES.update({'firewall_router_associations'}) VERSION_TABLE = 'alembic_version_fwaas' diff --git a/neutron_fwaas/tests/tempest_plugin/tests/api/base.py b/neutron_fwaas/tests/tempest_plugin/tests/api/base.py deleted file mode 100644 index cd0b2ebfe..000000000 --- a/neutron_fwaas/tests/tempest_plugin/tests/api/base.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) 2015 Midokura SARL -# 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 tempest.api.network import base - -from neutron_fwaas.tests.tempest_plugin.tests import fwaas_client - - -class BaseFWaaSTest(fwaas_client.FWaaSClientMixin, base.BaseNetworkTest): - pass diff --git a/neutron_fwaas/tests/tempest_plugin/tests/api/test_fwaas_extensions.py b/neutron_fwaas/tests/tempest_plugin/tests/api/test_fwaas_extensions.py deleted file mode 100644 index 04bd20a0c..000000000 --- a/neutron_fwaas/tests/tempest_plugin/tests/api/test_fwaas_extensions.py +++ /dev/null @@ -1,447 +0,0 @@ -# Copyright 2014 NEC Corporation. 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. - -import six - -from tempest.common import utils -from tempest import config -from tempest.lib.common.utils import data_utils -from tempest.lib.common.utils import test_utils -from tempest.lib import decorators -from tempest.lib import exceptions as lib_exc - -from neutron_fwaas.tests.tempest_plugin.tests.api import base - -CONF = config.CONF - - -class FWaaSExtensionTestJSON(base.BaseFWaaSTest): - - """ - Tests the following operations in the Neutron API using the REST client for - Neutron: - - List firewall rules - Create firewall rule - Update firewall rule - Delete firewall rule - Show firewall rule - List firewall policies - Create firewall policy - Update firewall policy - Insert firewall rule to policy - Remove firewall rule from policy - Insert firewall rule after/before rule in policy - Update firewall policy audited attribute - Delete firewall policy - Show firewall policy - List firewall - Create firewall - Update firewall - Delete firewall - Show firewall - """ - - @classmethod - def resource_setup(cls): - super(FWaaSExtensionTestJSON, cls).resource_setup() - if not utils.is_extension_enabled('fwaas', 'network'): - msg = "FWaaS Extension not enabled." - raise cls.skipException(msg) - - def setUp(self): - super(FWaaSExtensionTestJSON, self).setUp() - self.fw_rule = self.create_firewall_rule(action="allow", - protocol="tcp") - self.fw_policy = self.create_firewall_policy() - - def _try_delete_router(self, router): - # delete router, if it exists - try: - self.delete_router(router) - # if router is not found, this means it was deleted in the test - except lib_exc.NotFound: - pass - - def _try_delete_policy(self, policy_id): - # delete policy, if it exists - try: - self.firewall_policies_client.delete_firewall_policy(policy_id) - # if policy is not found, this means it was deleted in the test - except lib_exc.NotFound: - pass - - def _try_delete_rule(self, rule_id): - # delete rule, if it exists - try: - self.firewall_rules_client.delete_firewall_rule(rule_id) - # if rule is not found, this means it was deleted in the test - except lib_exc.NotFound: - pass - - def _try_delete_firewall(self, fw_id): - # delete firewall, if it exists - try: - self.firewalls_client.delete_firewall(fw_id) - # if firewall is not found, this means it was deleted in the test - except lib_exc.NotFound: - pass - - self.firewalls_client.wait_for_resource_deletion(fw_id) - - def _wait_until_ready(self, fw_id): - target_states = ('ACTIVE', 'CREATED') - - def _wait(): - firewall = self.firewalls_client.show_firewall(fw_id) - firewall = firewall['firewall'] - return firewall['status'] in target_states - - if not test_utils.call_until_true(_wait, CONF.network.build_timeout, - CONF.network.build_interval): - m = ("Timed out waiting for firewall %s to reach %s state(s)" % - (fw_id, target_states)) - raise lib_exc.TimeoutException(m) - - def _wait_until_deleted(self, fw_id): - def _wait(): - try: - firewall = self.firewalls_client.show_firewall(fw_id) - except lib_exc.NotFound: - return True - - fw_status = firewall['firewall']['status'] - if fw_status == 'ERROR': - raise lib_exc.DeleteErrorException(resource_id=fw_id) - - if not test_utils.call_until_true(_wait, CONF.network.build_timeout, - CONF.network.build_interval): - m = ("Timed out waiting for firewall %s deleted" % fw_id) - raise lib_exc.TimeoutException(m) - - @decorators.idempotent_id('1b84cf01-9c09-4ce7-bc72-b15e39076468') - @decorators.attr(type='smoke') - def test_list_firewall_rules(self): - # List firewall rules - fw_rules = self.firewall_rules_client.list_firewall_rules() - fw_rules = fw_rules['firewall_rules'] - self.assertIn((self.fw_rule['id'], - self.fw_rule['name'], - self.fw_rule['action'], - self.fw_rule['protocol'], - self.fw_rule['ip_version'], - self.fw_rule['enabled']), - [(m['id'], - m['name'], - m['action'], - m['protocol'], - m['ip_version'], - m['enabled']) for m in fw_rules]) - - @decorators.idempotent_id('563564f7-7077-4f5e-8cdc-51f37ae5a2b9') - @decorators.attr(type='smoke') - def test_create_update_delete_firewall_rule(self): - # Create firewall rule - body = self.firewall_rules_client.create_firewall_rule( - name=data_utils.rand_name("fw-rule"), - action="allow", - protocol="tcp") - fw_rule_id = body['firewall_rule']['id'] - self.addCleanup(self._try_delete_rule, fw_rule_id) - - # Update firewall rule - body = self.firewall_rules_client.update_firewall_rule(fw_rule_id, - action="deny") - self.assertEqual("deny", body["firewall_rule"]['action']) - - # Delete firewall rule - self.firewall_rules_client.delete_firewall_rule(fw_rule_id) - # Confirm deletion - fw_rules = self.firewall_rules_client.list_firewall_rules() - self.assertNotIn(fw_rule_id, - [m['id'] for m in fw_rules['firewall_rules']]) - - @decorators.idempotent_id('3ff8c08e-26ff-4034-ae48-810ed213a998') - @decorators.attr(type='smoke') - def test_show_firewall_rule(self): - # show a created firewall rule - fw_rule = self.firewall_rules_client.show_firewall_rule( - self.fw_rule['id']) - for key, value in six.iteritems(fw_rule['firewall_rule']): - self.assertEqual(self.fw_rule[key], value) - - @decorators.idempotent_id('1086dd93-a4c0-4bbb-a1bd-6d4bc62c199f') - @decorators.attr(type='smoke') - def test_list_firewall_policies(self): - fw_policies = self.firewall_policies_client.list_firewall_policies() - fw_policies = fw_policies['firewall_policies'] - self.assertIn((self.fw_policy['id'], - self.fw_policy['name'], - self.fw_policy['firewall_rules']), - [(m['id'], - m['name'], - m['firewall_rules']) for m in fw_policies]) - - @decorators.idempotent_id('bbf37b6c-498c-421e-9c95-45897d3ed775') - @decorators.attr(type='smoke') - def test_create_update_delete_firewall_policy(self): - # Create firewall policy - body = self.firewall_policies_client.create_firewall_policy( - name=data_utils.rand_name("fw-policy")) - fw_policy_id = body['firewall_policy']['id'] - self.addCleanup(self._try_delete_policy, fw_policy_id) - - # Update firewall policy - body = self.firewall_policies_client.update_firewall_policy( - fw_policy_id, - name="updated_policy") - updated_fw_policy = body["firewall_policy"] - self.assertEqual("updated_policy", updated_fw_policy['name']) - - # Delete firewall policy - self.firewall_policies_client.delete_firewall_policy(fw_policy_id) - # Confirm deletion - fw_policies = self.firewall_policies_client.list_firewall_policies() - fw_policies = fw_policies['firewall_policies'] - self.assertNotIn(fw_policy_id, [m['id'] for m in fw_policies]) - - @decorators.idempotent_id('1df59b3a-517e-41d4-96f6-fc31cf4ecff2') - @decorators.attr(type='smoke') - def test_show_firewall_policy(self): - # show a created firewall policy - fw_policy = self.firewall_policies_client.show_firewall_policy( - self.fw_policy['id']) - fw_policy = fw_policy['firewall_policy'] - for key, value in six.iteritems(fw_policy): - self.assertEqual(self.fw_policy[key], value) - - @decorators.idempotent_id('02082a03-3cdd-4789-986a-1327dd80bfb7') - @decorators.attr(type='smoke') - def test_create_show_delete_firewall(self): - # Create tenant network resources required for an ACTIVE firewall - network = self.create_network() - subnet = self.create_subnet(network) - router = self.create_router( - data_utils.rand_name('router-'), - admin_state_up=True) - self.addCleanup(self._try_delete_router, router) - self.routers_client.add_router_interface(router['id'], - subnet_id=subnet['id']) - - # Create firewall - body = self.firewalls_client.create_firewall( - name=data_utils.rand_name("firewall"), - firewall_policy_id=self.fw_policy['id']) - created_firewall = body['firewall'] - firewall_id = created_firewall['id'] - self.addCleanup(self._try_delete_firewall, firewall_id) - - # Wait for the firewall resource to become ready - self._wait_until_ready(firewall_id) - - # show a created firewall - firewall = self.firewalls_client.show_firewall(firewall_id) - firewall = firewall['firewall'] - - for key, value in six.iteritems(firewall): - if key == 'status': - continue - self.assertEqual(created_firewall[key], value) - - # list firewall - firewalls = self.firewalls_client.list_firewalls() - firewalls = firewalls['firewalls'] - self.assertIn((created_firewall['id'], - created_firewall['name'], - created_firewall['firewall_policy_id']), - [(m['id'], - m['name'], - m['firewall_policy_id']) for m in firewalls]) - - # Delete firewall - self.firewalls_client.delete_firewall(firewall_id) - - # Wait for the firewall resource to be deleted - self._wait_until_deleted(firewall_id) - - # Confirm deletion - firewalls = self.firewalls_client.list_firewalls()['firewalls'] - self.assertNotIn(firewall_id, [m['id'] for m in firewalls]) - - @decorators.idempotent_id('1355cf5c-77d4-4bb9-87d7-e50c194d08b5') - def test_firewall_insertion_mode_add_remove_router(self): - # Create legacy routers - router1 = self.create_router( - data_utils.rand_name('router-'), - admin_state_up=True) - self.addCleanup(self._try_delete_router, router1) - router2 = self.create_router( - data_utils.rand_name('router-'), - admin_state_up=True) - self.addCleanup(self._try_delete_router, router2) - - # Create firewall on a router1 - body = self.firewalls_client.create_firewall( - name=data_utils.rand_name("firewall"), - firewall_policy_id=self.fw_policy['id'], - router_ids=[router1['id']]) - created_firewall = body['firewall'] - firewall_id = created_firewall['id'] - self.addCleanup(self._try_delete_firewall, firewall_id) - - self.assertEqual([router1['id']], created_firewall['router_ids']) - - # Legacy routers are scheduled on L3 agents on network plug events - # Hence firewall resource will not became ready at this stage - network = self.create_network() - subnet = self.create_subnet(network) - self.routers_client.add_router_interface(router1['id'], - subnet_id=subnet['id']) - # Wait for the firewall resource to become ready - self._wait_until_ready(firewall_id) - - # Add router2 to the firewall - body = self.firewalls_client.update_firewall( - firewall_id, router_ids=[router1['id'], router2['id']]) - updated_firewall = body['firewall'] - self.assertIn(router2['id'], updated_firewall['router_ids']) - self.assertEqual(2, len(updated_firewall['router_ids'])) - - # Wait for the firewall resource to become ready - self._wait_until_ready(firewall_id) - - # Remove router1 from the firewall - body = self.firewalls_client.update_firewall( - firewall_id, router_ids=[router2['id']]) - updated_firewall = body['firewall'] - self.assertNotIn(router1['id'], updated_firewall['router_ids']) - self.assertEqual(1, len(updated_firewall['router_ids'])) - - @decorators.idempotent_id('c60ceff5-d51f-451d-b6e6-cb983d16ab6b') - def test_firewall_insertion_mode_one_firewall_per_router(self): - # Create router required for an ACTIVE firewall - router = self.create_router( - data_utils.rand_name('router1-'), - admin_state_up=True) - self.addCleanup(self._try_delete_router, router) - - # Create firewall - body = self.firewalls_client.create_firewall( - name=data_utils.rand_name("firewall"), - firewall_policy_id=self.fw_policy['id'], - router_ids=[router['id']]) - created_firewall = body['firewall'] - self.addCleanup(self._try_delete_firewall, created_firewall['id']) - - # Try to create firewall with the same router - self.assertRaisesRegex( - lib_exc.Conflict, - "already associated with other firewall", - self.firewalls_client.create_firewall, - name=data_utils.rand_name("firewall"), - firewall_policy_id=self.fw_policy['id'], - router_ids=[router['id']]) - - @decorators.attr(type='smoke') - @decorators.idempotent_id('53305b4b-9897-4e01-87c0-2ae386083180') - def test_firewall_rule_insertion_position_removal_rule_from_policy(self): - # Create firewall rule - body = self.firewall_rules_client.create_firewall_rule( - name=data_utils.rand_name("fw-rule"), - action="allow", - protocol="tcp") - fw_rule_id1 = body['firewall_rule']['id'] - self.addCleanup(self._try_delete_rule, fw_rule_id1) - # Create firewall policy - body = self.firewall_policies_client.create_firewall_policy( - name=data_utils.rand_name("fw-policy")) - fw_policy_id = body['firewall_policy']['id'] - self.addCleanup(self._try_delete_policy, fw_policy_id) - - # Insert rule to firewall policy - self.firewall_policies_client.insert_firewall_rule_in_policy( - fw_policy_id, fw_rule_id1, '', '') - - # Verify insertion of rule in policy - self.assertIn(fw_rule_id1, self._get_list_fw_rule_ids(fw_policy_id)) - # Create another firewall rule - body = self.firewall_rules_client.create_firewall_rule( - name=data_utils.rand_name("fw-rule"), - action="allow", - protocol="icmp") - fw_rule_id2 = body['firewall_rule']['id'] - self.addCleanup(self._try_delete_rule, fw_rule_id2) - - # Insert rule to firewall policy after the first rule - self.firewall_policies_client.insert_firewall_rule_in_policy( - fw_policy_id, fw_rule_id2, fw_rule_id1, '') - - # Verify the position of rule after insertion - fw_rule = self.firewall_rules_client.show_firewall_rule( - fw_rule_id2) - - self.assertEqual(int(fw_rule['firewall_rule']['position']), 2) - # Remove rule from the firewall policy - self.firewall_policies_client.remove_firewall_rule_from_policy( - fw_policy_id, fw_rule_id2) - # Insert rule to firewall policy before the first rule - self.firewall_policies_client.insert_firewall_rule_in_policy( - fw_policy_id, fw_rule_id2, '', fw_rule_id1) - # Verify the position of rule after insertion - fw_rule = self.firewall_rules_client.show_firewall_rule( - fw_rule_id2) - self.assertEqual(int(fw_rule['firewall_rule']['position']), 1) - # Remove rule from the firewall policy - self.firewall_policies_client.remove_firewall_rule_from_policy( - fw_policy_id, fw_rule_id2) - # Verify removal of rule from firewall policy - self.assertNotIn(fw_rule_id2, self._get_list_fw_rule_ids(fw_policy_id)) - - # Remove rule from the firewall policy - self.firewall_policies_client.remove_firewall_rule_from_policy( - fw_policy_id, fw_rule_id1) - - # Verify removal of rule from firewall policy - self.assertNotIn(fw_rule_id1, self._get_list_fw_rule_ids(fw_policy_id)) - - def _get_list_fw_rule_ids(self, fw_policy_id): - fw_policy = self.firewall_policies_client.show_firewall_policy( - fw_policy_id) - return [ruleid for ruleid in fw_policy['firewall_policy'] - ['firewall_rules']] - - @decorators.idempotent_id('8515ca8a-0d2f-4298-b5ff-6f924e4587ca') - def test_update_firewall_policy_audited_attribute(self): - # Create firewall rule - body = self.firewall_rules_client.create_firewall_rule( - name=data_utils.rand_name("fw-rule"), - action="allow", - protocol="icmp") - fw_rule_id = body['firewall_rule']['id'] - self.addCleanup(self._try_delete_rule, fw_rule_id) - # Create firewall policy - body = self.firewall_policies_client.create_firewall_policy( - name=data_utils.rand_name('fw-policy')) - fw_policy_id = body['firewall_policy']['id'] - self.addCleanup(self._try_delete_policy, fw_policy_id) - self.assertFalse(body['firewall_policy']['audited']) - # Update firewall policy audited attribute to true - self.firewall_policies_client.update_firewall_policy(fw_policy_id, - audited=True) - # Insert Firewall rule to firewall policy - self.firewall_policies_client.insert_firewall_rule_in_policy( - fw_policy_id, fw_rule_id, '', '') - body = self.firewall_policies_client.show_firewall_policy( - fw_policy_id) - self.assertFalse(body['firewall_policy']['audited']) diff --git a/neutron_fwaas/tests/tempest_plugin/tests/fwaas_client.py b/neutron_fwaas/tests/tempest_plugin/tests/fwaas_client.py deleted file mode 100644 index b8cfc1175..000000000 --- a/neutron_fwaas/tests/tempest_plugin/tests/fwaas_client.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright (c) 2015 Midokura SARL -# 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. - -import time - -from tempest import config -from tempest.lib.common.utils import data_utils -from tempest.lib.common.utils import test_utils -from tempest.lib import exceptions as lib_exc - -from neutron_fwaas.tests.tempest_plugin.services import client -from neutron_lib import constants as nl_constants - -CONF = config.CONF - - -class FWaaSClientMixin(object): - - @classmethod - def resource_setup(cls): - super(FWaaSClientMixin, cls).resource_setup() - manager = cls.os_primary - default_params = config.service_client_config() - cls.firewalls_client = client.FirewallsClient( - manager.auth_provider, - CONF.network.catalog_type, - CONF.network.region or CONF.identity.region, - endpoint_type=CONF.network.endpoint_type, - build_interval=CONF.network.build_interval, - build_timeout=CONF.network.build_timeout, - **default_params) - cls.firewall_policies_client = client.FirewallPoliciesClient( - manager.auth_provider, - CONF.network.catalog_type, - CONF.network.region or CONF.identity.region, - endpoint_type=CONF.network.endpoint_type, - build_interval=CONF.network.build_interval, - build_timeout=CONF.network.build_timeout, - **default_params) - cls.firewall_rules_client = client.FirewallRulesClient( - manager.auth_provider, - CONF.network.catalog_type, - CONF.network.region or CONF.identity.region, - endpoint_type=CONF.network.endpoint_type, - build_interval=CONF.network.build_interval, - build_timeout=CONF.network.build_timeout, - **default_params) - - def create_firewall_rule(self, **kwargs): - body = self.firewall_rules_client.create_firewall_rule( - name=data_utils.rand_name("fw-rule"), - **kwargs) - fw_rule = body['firewall_rule'] - self.addCleanup(test_utils.call_and_ignore_notfound_exc, - self.firewall_rules_client.delete_firewall_rule, - fw_rule['id']) - return fw_rule - - def create_firewall_policy(self, **kwargs): - body = self.firewall_policies_client.create_firewall_policy( - name=data_utils.rand_name("fw-policy"), - **kwargs) - fw_policy = body['firewall_policy'] - self.addCleanup(test_utils.call_and_ignore_notfound_exc, - self.firewall_policies_client.delete_firewall_policy, - fw_policy['id']) - return fw_policy - - def create_firewall(self, **kwargs): - body = self.firewalls_client.create_firewall( - name=data_utils.rand_name("fw"), - **kwargs) - fw = body['firewall'] - self.addCleanup(test_utils.call_and_ignore_notfound_exc, - self.delete_firewall_and_wait, - fw['id']) - return fw - - def delete_firewall_and_wait(self, firewall_id): - self.firewalls_client.delete_firewall(firewall_id) - self._wait_firewall_while(firewall_id, [nl_constants.PENDING_DELETE], - not_found_ok=True) - - def _wait_firewall_ready(self, firewall_id): - self._wait_firewall_while(firewall_id, - [nl_constants.PENDING_CREATE, - nl_constants.PENDING_UPDATE]) - - def _wait_firewall_while(self, firewall_id, statuses, not_found_ok=False): - start = int(time.time()) - if not_found_ok: - expected_exceptions = (lib_exc.NotFound) - else: - expected_exceptions = () - while True: - try: - fw = self.firewalls_client.show_firewall(firewall_id) - except expected_exceptions: - break - status = fw['firewall']['status'] - if status not in statuses: - break - if int(time.time()) - start >= self.firewalls_client.build_timeout: - msg = ("Firewall %(firewall)s failed to reach " - "non PENDING status (current %(status)s)") % { - "firewall": firewall_id, - "status": status, - } - raise lib_exc.TimeoutException(msg) - time.sleep(1) diff --git a/neutron_fwaas/tests/tempest_plugin/tests/scenario/base.py b/neutron_fwaas/tests/tempest_plugin/tests/scenario/base.py index 1bf2816ec..93d9630f8 100644 --- a/neutron_fwaas/tests/tempest_plugin/tests/scenario/base.py +++ b/neutron_fwaas/tests/tempest_plugin/tests/scenario/base.py @@ -17,7 +17,6 @@ from tempest import config from tempest.lib.common import ssh from tempest.lib import exceptions as lib_exc -from neutron_fwaas.tests.tempest_plugin.tests import fwaas_client from neutron_fwaas.tests.tempest_plugin.tests import fwaas_v2_client from neutron_fwaas.tests.tempest_plugin.tests.scenario import manager @@ -64,12 +63,6 @@ class FWaaSScenarioTestBase(object): raise -class FWaaSScenarioTest(fwaas_client.FWaaSClientMixin, - FWaaSScenarioTestBase, - manager.NetworkScenarioTest): - pass - - class FWaaSScenarioTest_V2(fwaas_v2_client.FWaaSClientMixin, FWaaSScenarioTestBase, manager.NetworkScenarioTest): diff --git a/neutron_fwaas/tests/tempest_plugin/tests/scenario/test_fwaas.py b/neutron_fwaas/tests/tempest_plugin/tests/scenario/test_fwaas.py deleted file mode 100644 index bc2a976a3..000000000 --- a/neutron_fwaas/tests/tempest_plugin/tests/scenario/test_fwaas.py +++ /dev/null @@ -1,379 +0,0 @@ -# Copyright (c) 2015 Midokura SARL -# 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. - -import testscenarios - -from tempest.common import utils -from tempest import config -from tempest.lib import decorators - -from neutron_fwaas.tests.tempest_plugin.tests.scenario import base - -CONF = config.CONF - -load_tests = testscenarios.load_tests_apply_scenarios - - -class TestFWaaS(base.FWaaSScenarioTest): - scenarios = [ - ('without router insersion', { - 'router_insertion': False, - }), - ('with router insersion', { - 'router_insertion': True, - }), - ] - - def setUp(self): - super(TestFWaaS, self).setUp() - required_exts = ['fwaas', 'security-group', 'router'] - if self.router_insertion: - required_exts.append('fwaasrouterinsertion') - for ext in required_exts: - if not utils.is_extension_enabled(ext, 'network'): - msg = "%s Extension not enabled." % ext - raise self.skipException(msg) - self._router_ids = None - - def _create_server(self, network, security_group=None): - keys = self.create_keypair() - kwargs = {} - if security_group is not None: - kwargs['security_groups'] = [{'name': security_group['name']}] - server = self.create_server( - key_name=keys['name'], - networks=[{'uuid': network['id']}], - wait_until='ACTIVE', - **kwargs) - return server, keys - - def _create_firewall(self, **kwargs): - if self._router_ids is not None: - kwargs['router_ids'] = self._router_ids - return self.create_firewall(**kwargs) - - def _empty_policy(self, **kwargs): - # NOTE(yamamoto): an empty policy would deny all - fw_policy = self.create_firewall_policy(firewall_rules=[]) - fw = self._create_firewall(firewall_policy_id=fw_policy['id']) - self._wait_firewall_ready(fw['id']) - return { - 'fw': fw, - 'fw_policy': fw_policy, - } - - def _all_disabled_rules(self, **kwargs): - # NOTE(yamamoto): a policy whose rules are all disabled would deny all - fw_rule = self.create_firewall_rule(action="allow", enabled=False) - fw_policy = self.create_firewall_policy(firewall_rules=[fw_rule['id']]) - fw = self._create_firewall(firewall_policy_id=fw_policy['id']) - self._wait_firewall_ready(fw['id']) - return { - 'fw': fw, - 'fw_policy': fw_policy, - 'fw_rule': fw_rule, - } - - def _block_ip(self, server1_fixed_ip, server2_fixed_ip, **kwargs): - rules = [ - # NOTE(yamamoto): The filtering is taken place after - # destination ip is rewritten to fixed-ip. - self.create_firewall_rule(destination_ip_address=server1_fixed_ip, - action="deny"), - self.create_firewall_rule(destination_ip_address=server2_fixed_ip, - action="deny"), - self.create_firewall_rule(action="allow"), - ] - rule_ids = [r['id'] for r in rules] - fw_policy = self.create_firewall_policy(firewall_rules=rule_ids) - fw = self._create_firewall(firewall_policy_id=fw_policy['id']) - self._wait_firewall_ready(fw['id']) - return { - 'fw': fw, - 'fw_policy': fw_policy, - 'server1_fixed_ip': server1_fixed_ip, - 'server2_fixed_ip': server2_fixed_ip, - } - - def _block_icmp(self, **kwargs): - fw_rule = self.create_firewall_rule( - protocol="icmp", - action="deny") - fw_rule_allow = self.create_firewall_rule( - action="allow") - fw_policy = self.create_firewall_policy( - firewall_rules=[fw_rule['id'], fw_rule_allow['id']]) - fw = self._create_firewall(firewall_policy_id=fw_policy['id']) - self._wait_firewall_ready(fw['id']) - return { - 'fw': fw, - 'fw_policy': fw_policy, - 'fw_rule': fw_rule, - } - - def _block_all_with_default_allow(self, **kwargs): - fw_rule = self.create_firewall_rule( - action="deny") - fw_rule_allow = self.create_firewall_rule( - action="allow") - fw_policy = self.create_firewall_policy( - firewall_rules=[fw_rule['id'], fw_rule_allow['id']]) - fw = self._create_firewall(firewall_policy_id=fw_policy['id']) - self._wait_firewall_ready(fw['id']) - return { - 'fw': fw, - 'fw_policy': fw_policy, - 'fw_rule': fw_rule, - } - - def _admin_disable(self, **kwargs): - # NOTE(yamamoto): A firewall with admin_state_up=False would block all - fw_rule = self.create_firewall_rule(action="allow") - fw_policy = self.create_firewall_policy(firewall_rules=[fw_rule['id']]) - fw = self._create_firewall(firewall_policy_id=fw_policy['id'], - admin_state_up=False) - self._wait_firewall_ready(fw['id']) - return { - 'fw': fw, - 'fw_policy': fw_policy, - 'fw_rule': fw_rule, - } - - def _allow_ssh_and_icmp(self, ctx): - fw_ssh_rule = self.create_firewall_rule( - protocol="tcp", - destination_port=22, - action="allow") - fw_icmp_rule = self.create_firewall_rule( - protocol="icmp", - action="allow") - for rule in [fw_ssh_rule, fw_icmp_rule]: - self.firewall_policies_client.insert_firewall_rule_in_policy( - firewall_policy_id=ctx['fw_policy']['id'], - firewall_rule_id=rule['id'], - insert_before=ctx['fw_rule']['id']) - self.addCleanup( - self._remove_rule_and_wait, - firewall_id=ctx['fw']['id'], - firewall_policy_id=ctx['fw_policy']['id'], - firewall_rule_id=rule['id']) - self._wait_firewall_ready(ctx['fw']['id']) - - def _remove_rule_and_wait(self, firewall_id, firewall_policy_id, - firewall_rule_id): - self.firewall_policies_client.remove_firewall_rule_from_policy( - firewall_policy_id=firewall_policy_id, - firewall_rule_id=firewall_rule_id) - self._wait_firewall_ready(firewall_id) - - def _delete_fw(self, ctx): - self.delete_firewall_and_wait(ctx['fw']['id']) - - def _set_admin_up(self, firewall_id, up): - self.firewalls_client.update_firewall(firewall_id=firewall_id, - admin_state_up=up) - self._wait_firewall_ready(firewall_id=firewall_id) - - def _admin_enable(self, ctx): - self._set_admin_up(ctx['fw']['id'], up=True) - - def _remove_rule(self, ctx): - self._remove_rule_and_wait( - firewall_id=ctx['fw']['id'], - firewall_policy_id=ctx['fw_policy']['id'], - firewall_rule_id=ctx['fw_rule']['id']) - - def _disable_rule(self, ctx): - self.firewall_rules_client.update_firewall_rule( - firewall_rule_id=ctx['fw_rule']['id'], - enabled=False) - self._wait_firewall_ready(ctx['fw']['id']) - - def _allow_ip(self, ctx): - self._delete_fw(ctx) - server1_fixed_ip = ctx['server1_fixed_ip'] - server2_fixed_ip = ctx['server2_fixed_ip'] - rules = [ - # NOTE(yamamoto): The filtering is taken place after - # destination ip is rewritten to fixed-ip. - # The return traffic should be allowed regardless - # of firewall rules. - self.create_firewall_rule( - destination_ip_address=server1_fixed_ip, - action="allow"), - self.create_firewall_rule( - destination_ip_address=server2_fixed_ip, - action="allow"), - ] - rule_ids = [r['id'] for r in rules] - fw_policy = self.create_firewall_policy(firewall_rules=rule_ids) - fw = self._create_firewall(firewall_policy_id=fw_policy['id']) - self._wait_firewall_ready(fw['id']) - - def _confirm_allowed(self, **kwargs): - self.check_connectivity(check_reverse_icmp_ip=self._public_gateway_ip, - **kwargs) - - def _confirm_allowed_oneway(self, **kwargs): - # Can ping and ssh, but can't ping back to the public gateway. - # Same as _confirm_allowed if _public_gateway_ip is None. - self.check_connectivity(check_reverse_icmp_ip=self._public_gateway_ip, - should_reverse_connect=False, **kwargs) - - def _confirm_blocked(self, **kwargs): - self.check_connectivity(should_connect=False, **kwargs) - - def _confirm_icmp_blocked_but_tcp(self, **kwargs): - self.check_connectivity(should_connect=False, check_ssh=False, - **kwargs) - self.check_connectivity(check_icmp=False, **kwargs) - - def _create_topology(self): - """Create a topology for testing - - +--------+ +-----------+ - |"server"| | "subnet" | - | VM +-------------+ "network" | - +--------+ +----+------+ - | - | router interface port - +----+-----+ - | "router" | - +----+-----+ - | router gateway port - | - | - +----+------------------+ - | existing network | - | ("public_network_id") | - +-----------------------+ - """ - public_network_id = CONF.network.public_network_id - network, subnet, router = self.create_networks() - security_group = self._create_security_group() - server, keys = self._create_server(network, - security_group=security_group) - private_key = keys['private_key'] - server_floating_ip = self.create_floating_ip(server, public_network_id) - fixed_ip = list(server['addresses'].values())[0][0]['addr'] - floating_ip = server_floating_ip['floating_ip_address'] - return fixed_ip, floating_ip, private_key, router - - def _get_public_gateway_ip(self): - self._public_gateway_ip = None - router = self._get_router() - ext_gw_info = router['external_gateway_info'] - ext_fixed_ips = ext_gw_info['external_fixed_ips'] - for ip in ext_fixed_ips: - subnet_id = ip['subnet_id'] - res = self.os_admin.subnets_client.show_subnet(subnet_id) - subnet = res['subnet'] - # REVISIT(yamamoto): IPv4 assumption - if subnet['ip_version'] == 4: - self._public_gateway_ip = subnet['gateway_ip'] - return - - def _test_firewall_basic(self, block, allow=None, - confirm_allowed=None, confirm_blocked=None): - if allow is None: - allow = self._delete_fw - if confirm_allowed is None: - confirm_allowed = self._confirm_allowed - if confirm_blocked is None: - confirm_blocked = self._confirm_blocked - ssh_login = CONF.validation.image_ssh_user - - if self.router_insertion and CONF.network.public_router_id: - # NOTE(yamamoto): If public_router_id is configured - # router1 and router2 will be the same router. - msg = "This test assumes no public_router_id configured" - raise self.skipException(msg) - - server1_fixed_ip, server1_floating_ip, private_key1, router1 = \ - self._create_topology() - server2_fixed_ip, server2_floating_ip, private_key2, router2 = \ - self._create_topology() - self._get_public_gateway_ip() - if self.router_insertion: - # Specify the router when creating a firewall and ensures that - # the other router (router2) is not affected by the firewall - self._router_ids = [router1['id']] - confirm_allowed2 = self.check_connectivity - confirm_blocked2 = self.check_connectivity - else: - # Without router insertion, all routers should be affected - # equally - confirm_allowed2 = confirm_allowed - confirm_blocked2 = confirm_blocked - self.check_connectivity(ip_address=server1_floating_ip, - username=ssh_login, - private_key=private_key1) - self.check_connectivity(ip_address=server2_floating_ip, - username=ssh_login, - private_key=private_key2) - ctx = block(server1_fixed_ip=server1_fixed_ip, - server1_floating_ip=server1_floating_ip, - server2_fixed_ip=server2_fixed_ip, - server2_floating_ip=server2_floating_ip) - confirm_blocked(ip_address=server1_floating_ip, username=ssh_login, - private_key=private_key1) - confirm_blocked2(ip_address=server2_floating_ip, username=ssh_login, - private_key=private_key2) - allow(ctx) - confirm_allowed(ip_address=server1_floating_ip, username=ssh_login, - private_key=private_key1) - confirm_allowed2(ip_address=server2_floating_ip, username=ssh_login, - private_key=private_key2) - - @decorators.idempotent_id('f970f6b3-6541-47ac-a9ea-f769be1e21a8') - def test_firewall_block_ip(self): - self._test_firewall_basic(block=self._block_ip, allow=self._allow_ip, - confirm_allowed=self._confirm_allowed_oneway) - - @decorators.idempotent_id('b985d010-994a-4055-bd5c-9e961464ccde') - def test_firewall_block_icmp(self): - self._test_firewall_basic( - block=self._block_icmp, - confirm_blocked=self._confirm_icmp_blocked_but_tcp) - - @decorators.idempotent_id('ca473af0-26f9-4fad-9550-1c34371c900e') - def test_firewall_insert_rule(self): - self._test_firewall_basic( - block=self._block_icmp, - allow=self._allow_ssh_and_icmp, - confirm_blocked=self._confirm_icmp_blocked_but_tcp) - - @decorators.idempotent_id('54a937a6-cecf-444c-b3f9-b67a1c1b7411') - def test_firewall_remove_rule(self): - self._test_firewall_basic(block=self._block_all_with_default_allow, - allow=self._remove_rule) - - @decorators.idempotent_id('12a18776-9b60-4479-9988-f45971c96a92') - def test_firewall_disable_rule(self): - self._test_firewall_basic(block=self._block_all_with_default_allow, - allow=self._disable_rule) - - @decorators.idempotent_id('a2a58c1f-49ad-4b5f-9463-e746b9efe08a') - def test_firewall_empty_policy(self): - self._test_firewall_basic(block=self._empty_policy) - - @decorators.idempotent_id('477a47e0-5156-4784-9417-f77970d85c36') - def test_firewall_all_disabled_rules(self): - self._test_firewall_basic(block=self._all_disabled_rules) - - @decorators.idempotent_id('a83f51c5-1a18-4d2a-a778-c368e4d95c29') - def test_firewall_admin_disable(self): - self._test_firewall_basic(block=self._admin_disable, - allow=self._admin_enable) diff --git a/neutron_fwaas/tests/unit/db/firewall/test_firewall_db.py b/neutron_fwaas/tests/unit/db/firewall/test_firewall_db.py deleted file mode 100644 index 31ab174d9..000000000 --- a/neutron_fwaas/tests/unit/db/firewall/test_firewall_db.py +++ /dev/null @@ -1,1527 +0,0 @@ -# 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. - -import contextlib - -import mock -from neutron.api import extensions as api_ext -from neutron.common import config -from neutron.tests.unit.db import test_db_base_plugin_v2 as test_db_plugin -from neutron_lib.api.definitions import firewall -from neutron_lib import constants as nl_constants -from neutron_lib import context -from neutron_lib.exceptions import firewall_v1 as f_exc -from neutron_lib.exceptions import l3 -from neutron_lib.plugins import directory -from oslo_config import cfg -from oslo_utils import importutils -from oslo_utils import uuidutils -import six -import webob.exc - -from neutron_fwaas.db.firewall import firewall_db as fdb -from neutron_fwaas import extensions -from neutron_fwaas.services.firewall import fwaas_plugin - - -DB_FW_PLUGIN_KLASS = ( - "neutron_fwaas.db.firewall.firewall_db.Firewall_db_mixin" -) -FWAAS_PLUGIN = 'neutron_fwaas.services.firewall.fwaas_plugin' -DELETEFW_PATH = FWAAS_PLUGIN + '.FirewallAgentApi.delete_firewall' -extensions_path = ':'.join(extensions.__path__) -DESCRIPTION = 'default description' -SHARED = True -PROTOCOL = 'tcp' -IP_VERSION = 4 -SOURCE_IP_ADDRESS_RAW = '1.1.1.1' -DESTINATION_IP_ADDRESS_RAW = '2.2.2.2' -SOURCE_PORT = '55000:56000' -DESTINATION_PORT = '56000:57000' -ACTION = 'allow' -AUDITED = True -ENABLED = True -ADMIN_STATE_UP = True - - -class FakeAgentApi(fwaas_plugin.FirewallCallbacks): - """ - This class used to mock the AgentAPI delete method inherits from - FirewallCallbacks because it needs access to the firewall_deleted method. - The delete_firewall method belongs to the FirewallAgentApi, which has - no access to the firewall_deleted method normally because it's not - responsible for deleting the firewall from the DB. However, it needs - to in the unit tests since there is no agent to call back. - """ - def __init__(self): - pass - - def delete_firewall(self, context, firewall, **kwargs): - self.plugin = directory.get_plugin('FIREWALL') - self.firewall_deleted(context, firewall['id'], **kwargs) - - -class FirewallPluginDbTestCase(test_db_plugin.NeutronDbPluginV2TestCase): - resource_prefix_map = dict( - (k, firewall.API_PREFIX) - for k in firewall.RESOURCE_ATTRIBUTE_MAP.keys() - ) - - def setUp(self, core_plugin=None, fw_plugin=None, ext_mgr=None): - self.agentapi_delf_p = mock.patch(DELETEFW_PATH, create=True, - new=FakeAgentApi().delete_firewall) - self.agentapi_delf_p.start() - if not fw_plugin: - fw_plugin = DB_FW_PLUGIN_KLASS - service_plugins = {'fw_plugin_name': fw_plugin} - - fdb.Firewall_db_mixin.supported_extension_aliases = ["fwaas"] - fdb.Firewall_db_mixin.path_prefix = firewall.API_PREFIX - super(FirewallPluginDbTestCase, self).setUp( - ext_mgr=ext_mgr, - service_plugins=service_plugins - ) - - if not ext_mgr: - self.plugin = importutils.import_object(fw_plugin) - ext_mgr = api_ext.PluginAwareExtensionManager( - extensions_path, - {'FIREWALL': self.plugin} - ) - app = config.load_paste_app('extensions_test_app') - self.ext_api = api_ext.ExtensionMiddleware(app, ext_mgr=ext_mgr) - - def _test_list_resources(self, resource, items, - neutron_context=None, - query_params=None): - if resource.endswith('y'): - resource_plural = resource.replace('y', 'ies') - else: - resource_plural = resource + 's' - - res = self._list(resource_plural, - neutron_context=neutron_context, - query_params=query_params) - resource = resource.replace('-', '_') - if query_params is None or ('fields' not in query_params): - self.assertEqual( - sorted([i[resource]['id'] for i in items]), - sorted([i['id'] for i in res[resource_plural]])) - else: - self.assertEqual( - sorted([i for i in items]), - sorted([i for i in res[resource_plural]])) - - def _get_test_firewall_rule_attrs(self, name='firewall_rule1'): - attrs = {'name': name, - 'tenant_id': self._tenant_id, - 'project_id': self._tenant_id, - 'shared': SHARED, - 'protocol': PROTOCOL, - 'ip_version': IP_VERSION, - 'source_ip_address': SOURCE_IP_ADDRESS_RAW, - 'destination_ip_address': DESTINATION_IP_ADDRESS_RAW, - 'source_port': SOURCE_PORT, - 'destination_port': DESTINATION_PORT, - 'action': ACTION, - 'enabled': ENABLED} - return attrs - - def _get_test_firewall_policy_attrs(self, name='firewall_policy1', - audited=AUDITED): - attrs = {'name': name, - 'description': DESCRIPTION, - 'tenant_id': self._tenant_id, - 'project_id': self._tenant_id, - 'shared': SHARED, - 'firewall_rules': [], - 'audited': audited} - return attrs - - def _get_test_firewall_attrs(self, name='firewall_1', - status='PENDING_CREATE'): - attrs = {'name': name, - 'tenant_id': self._tenant_id, - 'project_id': self._tenant_id, - 'admin_state_up': ADMIN_STATE_UP, - 'status': status} - - return attrs - - def _create_firewall_policy(self, fmt, name, description, shared, - firewall_rules, audited, - expected_res_status=None, **kwargs): - tenant_id = kwargs.get('tenant_id', self._tenant_id) - data = {'firewall_policy': {'name': name, - 'description': description, - 'tenant_id': tenant_id, - 'project_id': tenant_id, - 'shared': shared, - 'firewall_rules': firewall_rules, - 'audited': audited}} - - fw_policy_req = self.new_create_request('firewall_policies', data, fmt) - fw_policy_res = fw_policy_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(expected_res_status, fw_policy_res.status_int) - - return fw_policy_res - - def _replace_firewall_status(self, attrs, old_status, new_status): - if attrs['status'] is old_status: - attrs['status'] = new_status - return attrs - - @contextlib.contextmanager - def firewall_policy(self, fmt=None, name='firewall_policy1', - description=DESCRIPTION, shared=True, - firewall_rules=None, audited=True, - do_delete=True, **kwargs): - if firewall_rules is None: - firewall_rules = [] - if not fmt: - fmt = self.fmt - res = self._create_firewall_policy(fmt, name, description, shared, - firewall_rules, audited, - **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - firewall_policy = self.deserialize(fmt or self.fmt, res) - yield firewall_policy - if do_delete: - self._delete('firewall_policies', - firewall_policy['firewall_policy']['id']) - - def _create_firewall_rule(self, fmt, name, shared, protocol, - ip_version, source_ip_address, - destination_ip_address, source_port, - destination_port, action, enabled, - expected_res_status=None, **kwargs): - tenant_id = kwargs.get('tenant_id', self._tenant_id) - data = {'firewall_rule': {'name': name, - 'tenant_id': tenant_id, - 'project_id': tenant_id, - 'shared': shared, - 'protocol': protocol, - 'ip_version': ip_version, - 'source_ip_address': source_ip_address, - 'destination_ip_address': - destination_ip_address, - 'source_port': source_port, - 'destination_port': destination_port, - 'action': action, - 'enabled': enabled}} - - fw_rule_req = self.new_create_request('firewall_rules', data, fmt) - fw_rule_res = fw_rule_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(expected_res_status, fw_rule_res.status_int) - - return fw_rule_res - - @contextlib.contextmanager - def firewall_rule(self, fmt=None, name='firewall_rule1', - shared=SHARED, protocol=PROTOCOL, ip_version=IP_VERSION, - source_ip_address=SOURCE_IP_ADDRESS_RAW, - destination_ip_address=DESTINATION_IP_ADDRESS_RAW, - source_port=SOURCE_PORT, - destination_port=DESTINATION_PORT, - action=ACTION, enabled=ENABLED, - do_delete=True, **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_firewall_rule(fmt, name, shared, protocol, - ip_version, source_ip_address, - destination_ip_address, - source_port, destination_port, - action, enabled, **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - firewall_rule = self.deserialize(fmt or self.fmt, res) - yield firewall_rule - if do_delete: - self._delete('firewall_rules', - firewall_rule['firewall_rule']['id']) - - def _create_firewall(self, fmt, name, description, firewall_policy_id, - admin_state_up=True, expected_res_status=None, - **kwargs): - tenant_id = kwargs.get('tenant_id', self._tenant_id) - if firewall_policy_id is None: - res = self._create_firewall_policy(fmt, 'fwp', - description=DESCRIPTION, - shared=True, - firewall_rules=[], - tenant_id=tenant_id, - audited=AUDITED) - firewall_policy = self.deserialize(fmt or self.fmt, res) - firewall_policy_id = firewall_policy["firewall_policy"]["id"] - data = {'firewall': {'name': name, - 'description': description, - 'firewall_policy_id': firewall_policy_id, - 'admin_state_up': admin_state_up}} - ctx = kwargs.get('context', None) - if ctx is None or ctx.is_admin: - data['firewall'].update({'tenant_id': tenant_id}) - data['firewall'].update({'project_id': tenant_id}) - router_ids = kwargs.get('router_ids', None) - if router_ids: - data['firewall'].update({'router_ids': router_ids}) - firewall_req = self.new_create_request('firewalls', data, fmt, - context=ctx) - firewall_res = firewall_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(expected_res_status, firewall_res.status_int) - - return firewall_res - - @contextlib.contextmanager - def firewall(self, fmt=None, name='firewall_1', description=DESCRIPTION, - firewall_policy_id=None, admin_state_up=True, - do_delete=True, **kwargs): - if not fmt: - fmt = self.fmt - res = self._create_firewall(fmt, name, description, firewall_policy_id, - admin_state_up, **kwargs) - if res.status_int >= 400: - raise webob.exc.HTTPClientError(code=res.status_int) - firewall = self.deserialize(fmt or self.fmt, res) - yield firewall - if do_delete: - self._delete('firewalls', firewall['firewall']['id']) - - def _rule_action(self, action, id, firewall_rule_id, insert_before=None, - insert_after=None, expected_code=webob.exc.HTTPOk.code, - expected_body=None, body_data=None): - # We intentionally do this check for None since we want to distinguish - # from empty dictionary - if body_data is None: - if action == 'insert': - body_data = {'firewall_rule_id': firewall_rule_id, - 'insert_before': insert_before, - 'insert_after': insert_after} - else: - body_data = {'firewall_rule_id': firewall_rule_id} - - req = self.new_action_request('firewall_policies', - body_data, id, - "%s_rule" % action) - res = req.get_response(self.ext_api) - self.assertEqual(expected_code, res.status_int) - response = self.deserialize(self.fmt, res) - if expected_body: - self.assertEqual(expected_body, response) - return response - - def _compare_firewall_rule_lists(self, firewall_policy_id, - observed_list, expected_list): - position = 0 - for r1, r2 in zip(observed_list, expected_list): - rule = r1['firewall_rule'] - rule['firewall_policy_id'] = firewall_policy_id - position += 1 - rule['position'] = position - for k in rule: - self.assertEqual(r2[k], rule[k]) - - -class TestFirewallDBPlugin(FirewallPluginDbTestCase): - - def test_create_firewall_policy(self): - name = "firewall_policy1" - attrs = self._get_test_firewall_policy_attrs(name) - - with self.firewall_policy(name=name, shared=SHARED, - firewall_rules=None, - audited=AUDITED) as firewall_policy: - for k, v in six.iteritems(attrs): - self.assertEqual(v, firewall_policy['firewall_policy'][k]) - - def test_create_firewall_policy_with_rules(self): - name = "firewall_policy1" - attrs = self._get_test_firewall_policy_attrs(name) - - with self.firewall_rule(name='fwr1') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2, \ - self.firewall_rule(name='fwr3') as fwr3: - fr = [fwr1, fwr2, fwr3] - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - attrs['firewall_rules'] = fw_rule_ids - with self.firewall_policy(name=name, shared=SHARED, - firewall_rules=fw_rule_ids, - audited=AUDITED) as fwp: - for k, v in six.iteritems(attrs): - self.assertEqual(v, fwp['firewall_policy'][k]) - - def test_create_admin_firewall_policy_with_other_tenant_rules(self): - with self.firewall_rule(shared=False) as fr: - fw_rule_ids = [fr['firewall_rule']['id']] - res = self._create_firewall_policy(None, 'firewall_policy1', - description=DESCRIPTION, - shared=SHARED, - firewall_rules=fw_rule_ids, - audited=AUDITED, - tenant_id='admin-tenant') - self.assertEqual(webob.exc.HTTPConflict.code, res.status_int) - - def test_create_firewall_policy_with_previously_associated_rule(self): - with self.firewall_rule() as fwr: - fw_rule_ids = [fwr['firewall_rule']['id']] - with self.firewall_policy(firewall_rules=fw_rule_ids): - res = self._create_firewall_policy( - None, 'firewall_policy2', description=DESCRIPTION, - shared=SHARED, firewall_rules=fw_rule_ids, - audited=AUDITED) - self.assertEqual(409, res.status_int) - - def test_create_shared_firewall_policy_with_unshared_rule(self): - with self.firewall_rule(shared=False) as fwr: - fw_rule_ids = [fwr['firewall_rule']['id']] - res = self._create_firewall_policy( - None, 'firewall_policy1', description=DESCRIPTION, shared=True, - firewall_rules=fw_rule_ids, audited=AUDITED) - self.assertEqual(webob.exc.HTTPConflict.code, res.status_int) - - def test_show_firewall_policy(self): - name = "firewall_policy1" - attrs = self._get_test_firewall_policy_attrs(name) - - with self.firewall_policy(name=name, shared=SHARED, - firewall_rules=None, - audited=AUDITED) as fwp: - req = self.new_show_request('firewall_policies', - fwp['firewall_policy']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_policy'][k]) - - def test_list_firewall_policies(self): - with self.firewall_policy(name='fwp1', description='fwp') as fwp1, \ - self.firewall_policy(name='fwp2', description='fwp') as fwp2, \ - self.firewall_policy(name='fwp3', description='fwp') as fwp3: - fw_policies = [fwp1, fwp2, fwp3] - self._test_list_resources('firewall_policy', - fw_policies, - query_params='description=fwp') - - def test_update_firewall_policy(self): - name = "new_firewall_policy1" - attrs = self._get_test_firewall_policy_attrs(name, audited=False) - - with self.firewall_policy(shared=SHARED, - firewall_rules=None, - audited=AUDITED) as fwp: - data = {'firewall_policy': {'name': name}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = self.deserialize(self.fmt, req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_policy'][k]) - - def _test_update_firewall_policy(self, with_audited): - with self.firewall_policy(name='firewall_policy1', - description='fwp', - audited=AUDITED) as fwp: - attrs = self._get_test_firewall_policy_attrs(audited=with_audited) - data = {'firewall_policy': - {'description': 'fw_p1'}} - if with_audited: - data['firewall_policy']['audited'] = 'True' - - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs['description'] = 'fw_p1' - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_policy'][k]) - - def test_update_firewall_policy_set_audited_false(self): - self._test_update_firewall_policy(with_audited=False) - - def test_update_firewall_policy_with_audited_set_true(self): - self._test_update_firewall_policy(with_audited=True) - - def test_update_firewall_policy_with_rules(self): - attrs = self._get_test_firewall_policy_attrs() - - with self.firewall_rule(name='fwr1') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2, \ - self.firewall_rule(name='fwr3') as fwr3: - with self.firewall_policy() as fwp: - fr = [fwr1, fwr2, fwr3] - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - attrs['firewall_rules'] = fw_rule_ids - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs['audited'] = False - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_policy'][k]) - - def test_update_firewall_policy_replace_rules(self): - attrs = self._get_test_firewall_policy_attrs() - - with self.firewall_rule(name='fwr1') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2, \ - self.firewall_rule(name='fwr3') as fwr3, \ - self.firewall_rule(name='fwr4') as fwr4: - frs = [fwr1, fwr2, fwr3, fwr4] - fr1 = frs[0:2] - fr2 = frs[2:4] - with self.firewall_policy() as fwp: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr1] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - - fw_rule_ids = [r['firewall_rule']['id'] for r in fr2] - attrs['firewall_rules'] = fw_rule_ids - new_data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', new_data, - fwp['firewall_policy']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs['audited'] = False - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_policy'][k]) - - def test_update_firewall_policy_reorder_rules(self): - attrs = self._get_test_firewall_policy_attrs() - - with self.firewall_rule(name='fwr1') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2, \ - self.firewall_rule(name='fwr3') as fwr3, \ - self.firewall_rule(name='fwr4') as fwr4: - fr = [fwr1, fwr2, fwr3, fwr4] - with self.firewall_policy() as fwp: - fw_rule_ids = [fr[2]['firewall_rule']['id'], - fr[3]['firewall_rule']['id']] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - # shuffle the rules, add more rules - fw_rule_ids = [fr[1]['firewall_rule']['id'], - fr[3]['firewall_rule']['id'], - fr[2]['firewall_rule']['id'], - fr[0]['firewall_rule']['id']] - attrs['firewall_rules'] = fw_rule_ids - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - rules = [] - for rule_id in fw_rule_ids: - req = self.new_show_request('firewall_rules', - rule_id, - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - rules.append(res['firewall_rule']) - self.assertEqual(1, rules[0]['position']) - self.assertEqual(fr[1]['firewall_rule']['id'], rules[0]['id']) - self.assertEqual(2, rules[1]['position']) - self.assertEqual(fr[3]['firewall_rule']['id'], rules[1]['id']) - self.assertEqual(3, rules[2]['position']) - self.assertEqual(fr[2]['firewall_rule']['id'], rules[2]['id']) - self.assertEqual(4, rules[3]['position']) - self.assertEqual(fr[0]['firewall_rule']['id'], rules[3]['id']) - - def test_update_firewall_policy_with_non_existing_rule(self): - attrs = self._get_test_firewall_policy_attrs() - - with self.firewall_rule(name='fwr1') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2: - fr = [fwr1, fwr2] - with self.firewall_policy() as fwp: - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - # appending non-existent rule - fw_rule_ids.append(uuidutils.generate_uuid()) - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = req.get_response(self.ext_api) - # check that the firewall_rule was not found - self.assertEqual(404, res.status_int) - # check if none of the rules got added to the policy - req = self.new_show_request('firewall_policies', - fwp['firewall_policy']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_policy'][k]) - - def test_update_shared_firewall_policy_with_unshared_rule(self): - with self.firewall_rule(name='fwr1', shared=False) as fr: - with self.firewall_policy() as fwp: - fw_rule_ids = [fr['firewall_rule']['id']] - # update shared policy with unshared rule - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(webob.exc.HTTPConflict.code, res.status_int) - - def test_update_firewall_policy_with_shared_attr_unshared_rule(self): - with self.firewall_rule(name='fwr1', shared=False) as fr: - with self.firewall_policy(shared=False) as fwp: - fw_rule_ids = [fr['firewall_rule']['id']] - # update shared policy with shared attr and unshared rule - data = {'firewall_policy': {'shared': True, - 'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(webob.exc.HTTPConflict.code, res.status_int) - - def test_update_firewall_policy_with_shared_attr_exist_unshare_rule(self): - with self.firewall_rule(name='fwr1', shared=False) as fr: - fw_rule_ids = [fr['firewall_rule']['id']] - with self.firewall_policy(shared=False, - firewall_rules=fw_rule_ids) as fwp: - # update policy with shared attr - data = {'firewall_policy': {'shared': True}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(webob.exc.HTTPConflict.code, res.status_int) - - def test_update_firewall_policy_assoc_with_other_tenant_firewall(self): - with self.firewall_policy(shared=True, tenant_id='tenant1') as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id): - data = {'firewall_policy': {'shared': False}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(webob.exc.HTTPConflict.code, res.status_int) - - def test_delete_firewall_policy(self): - ctx = context.get_admin_context() - with self.firewall_policy(do_delete=False) as fwp: - fwp_id = fwp['firewall_policy']['id'] - req = self.new_delete_request('firewall_policies', fwp_id) - res = req.get_response(self.ext_api) - self.assertEqual(204, res.status_int) - self.assertRaises(f_exc.FirewallPolicyNotFound, - self.plugin.get_firewall_policy, - ctx, fwp_id) - - def test_delete_firewall_policy_with_rule(self): - ctx = context.get_admin_context() - attrs = self._get_test_firewall_policy_attrs() - with self.firewall_policy(do_delete=False) as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall_rule(name='fwr1') as fr: - fr_id = fr['firewall_rule']['id'] - fw_rule_ids = [fr_id] - attrs['firewall_rules'] = fw_rule_ids - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - fw_rule = self.plugin.get_firewall_rule(ctx, fr_id) - self.assertEqual(fwp_id, fw_rule['firewall_policy_id']) - req = self.new_delete_request('firewall_policies', fwp_id) - res = req.get_response(self.ext_api) - self.assertEqual(204, res.status_int) - self.assertRaises(f_exc.FirewallPolicyNotFound, - self.plugin.get_firewall_policy, - ctx, fwp_id) - fw_rule = self.plugin.get_firewall_rule(ctx, fr_id) - self.assertIsNone(fw_rule['firewall_policy_id']) - - def test_delete_firewall_policy_with_firewall_association(self): - attrs = self._get_test_firewall_attrs() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=ADMIN_STATE_UP): - req = self.new_delete_request('firewall_policies', fwp_id) - res = req.get_response(self.ext_api) - self.assertEqual(409, res.status_int) - - def test_create_firewall_rule(self): - attrs = self._get_test_firewall_rule_attrs() - - with self.firewall_rule() as firewall_rule: - for k, v in six.iteritems(attrs): - self.assertEqual(v, firewall_rule['firewall_rule'][k]) - - attrs['source_port'] = None - attrs['destination_port'] = None - with self.firewall_rule(source_port=None, - destination_port=None) as firewall_rule: - for k, v in six.iteritems(attrs): - self.assertEqual(v, firewall_rule['firewall_rule'][k]) - - attrs['source_port'] = '10000' - attrs['destination_port'] = '80' - with self.firewall_rule(source_port=10000, - destination_port=80) as firewall_rule: - for k, v in six.iteritems(attrs): - self.assertEqual(v, firewall_rule['firewall_rule'][k]) - - attrs['source_port'] = '10000' - attrs['destination_port'] = '80' - with self.firewall_rule(source_port='10000', - destination_port='80') as firewall_rule: - for k, v in six.iteritems(attrs): - self.assertEqual(v, firewall_rule['firewall_rule'][k]) - - def test_create_firewall_src_port_illegal_range(self): - attrs = self._get_test_firewall_rule_attrs() - attrs['source_port'] = '65535:1024' - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(400, res.status_int) - - def test_create_firewall_dest_port_illegal_range(self): - attrs = self._get_test_firewall_rule_attrs() - attrs['destination_port'] = '65535:1024' - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(400, res.status_int) - - def test_create_firewall_rule_icmp_with_port(self): - attrs = self._get_test_firewall_rule_attrs() - attrs['protocol'] = 'icmp' - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(400, res.status_int) - - def test_create_firewall_rule_icmp_without_port(self): - attrs = self._get_test_firewall_rule_attrs() - - attrs['protocol'] = 'icmp' - attrs['source_port'] = None - attrs['destination_port'] = None - with self.firewall_rule(source_port=None, - destination_port=None, - protocol='icmp') as firewall_rule: - for k, v in six.iteritems(attrs): - self.assertEqual(v, firewall_rule['firewall_rule'][k]) - - def test_create_firewall_without_source(self): - attrs = self._get_test_firewall_rule_attrs() - attrs['source_ip_address'] = None - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(201, res.status_int) - - def test_create_firewall_rule_without_destination(self): - attrs = self._get_test_firewall_rule_attrs() - attrs['destination_ip_address'] = None - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(201, res.status_int) - - def test_create_firewall_rule_without_protocol_with_dport(self): - attrs = self._get_test_firewall_rule_attrs() - attrs['protocol'] = None - attrs['source_port'] = None - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(400, res.status_int) - - def test_create_firewall_rule_without_protocol_with_sport(self): - attrs = self._get_test_firewall_rule_attrs() - attrs['protocol'] = None - attrs['destination_port'] = None - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(400, res.status_int) - - def test_show_firewall_rule_with_fw_policy_not_associated(self): - attrs = self._get_test_firewall_rule_attrs() - with self.firewall_rule() as fw_rule: - req = self.new_show_request('firewall_rules', - fw_rule['firewall_rule']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_rule'][k]) - - def test_show_firewall_rule_with_fw_policy_associated(self): - attrs = self._get_test_firewall_rule_attrs() - with self.firewall_rule() as fw_rule: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - data = {'firewall_policy': - {'firewall_rules': - [fw_rule['firewall_rule']['id']]}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - req = self.new_show_request('firewall_rules', - fw_rule['firewall_rule']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_rule'][k]) - - def test_create_firewall_rule_with_ipv6_addrs_and_wrong_ip_version(self): - attrs = self._get_test_firewall_rule_attrs() - attrs['source_ip_address'] = '::/0' - attrs['destination_ip_address'] = '2001:db8:3::/64' - attrs['ip_version'] = 4 - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(400, res.status_int) - - attrs = self._get_test_firewall_rule_attrs() - attrs['source_ip_address'] = None - attrs['destination_ip_address'] = '2001:db8:3::/64' - attrs['ip_version'] = 4 - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(400, res.status_int) - - attrs = self._get_test_firewall_rule_attrs() - attrs['source_ip_address'] = '::/0' - attrs['destination_ip_address'] = None - attrs['ip_version'] = 4 - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(400, res.status_int) - - def test_list_firewall_rules(self): - with self.firewall_rule(name='fwr1') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2, \ - self.firewall_rule(name='fwr3') as fwr3: - fr = [fwr1, fwr2, fwr3] - query_params = 'protocol=tcp' - self._test_list_resources('firewall_rule', fr, - query_params=query_params) - - def test_update_firewall_rule(self): - name = "new_firewall_rule1" - attrs = self._get_test_firewall_rule_attrs(name) - - attrs['source_port'] = '10:20' - attrs['destination_port'] = '30:40' - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'protocol': PROTOCOL, - 'source_port': '10:20', - 'destination_port': '30:40'}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_rule'][k]) - - attrs['source_port'] = '10000' - attrs['destination_port'] = '80' - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'protocol': PROTOCOL, - 'source_port': 10000, - 'destination_port': 80}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_rule'][k]) - - attrs['source_port'] = '10000' - attrs['destination_port'] = '80' - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'protocol': PROTOCOL, - 'source_port': '10000', - 'destination_port': '80'}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_rule'][k]) - - attrs['source_port'] = None - attrs['destination_port'] = None - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'name': name, - 'source_port': None, - 'destination_port': None}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_rule'][k]) - - def test_update_firewall_rule_with_port_and_no_proto(self): - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'protocol': None, - 'destination_port': 80}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(400, res.status_int) - - def test_update_firewall_rule_without_ports_and_no_proto(self): - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'protocol': None, - 'destination_port': None, - 'source_port': None}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(200, res.status_int) - - def test_update_firewall_rule_with_port(self): - with self.firewall_rule(source_port=None, - destination_port=None, - protocol=None) as fwr: - data = {'firewall_rule': {'destination_port': 80}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(400, res.status_int) - - def test_update_firewall_rule_with_port_illegal_range(self): - with self.firewall_rule() as fwr: - data = {'firewall_rule': {'destination_port': '65535:1024'}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(400, res.status_int) - - def test_update_firewall_rule_with_port_and_protocol(self): - with self.firewall_rule(source_port=None, - destination_port=None, - protocol=None) as fwr: - data = {'firewall_rule': {'destination_port': 80, - 'protocol': 'tcp'}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(200, res.status_int) - - def test_update_firewall_rule_icmp_with_port(self): - with self.firewall_rule(source_port=None, - destination_port=None, - protocol=None) as fwr: - data = {'firewall_rule': {'destination_port': 80, - 'protocol': 'icmp'}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(400, res.status_int) - - def test_update_firewall_rule_with_policy_associated(self): - name = "new_firewall_rule1" - attrs = self._get_test_firewall_rule_attrs(name) - with self.firewall_rule() as fwr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - fwr_id = fwr['firewall_rule']['id'] - data = {'firewall_policy': {'firewall_rules': [fwr_id]}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - data = {'firewall_rule': {'name': name}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs['firewall_policy_id'] = fwp_id - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall_rule'][k]) - req = self.new_show_request('firewall_policies', - fwp['firewall_policy']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - self.assertEqual( - [fwr_id], - res['firewall_policy']['firewall_rules']) - self.assertFalse(res['firewall_policy']['audited']) - - def test_update_firewall_rule_associated_with_other_tenant_policy(self): - with self.firewall_rule(shared=True, tenant_id='tenant1') as fwr: - fwr_id = [fwr['firewall_rule']['id']] - with self.firewall_policy(shared=False, - firewall_rules=fwr_id): - data = {'firewall_rule': {'shared': False}} - req = self.new_update_request('firewall_rules', data, - fwr['firewall_rule']['id']) - res = req.get_response(self.ext_api) - self.assertEqual(webob.exc.HTTPConflict.code, res.status_int) - - def test_delete_firewall_rule(self): - ctx = context.get_admin_context() - with self.firewall_rule(do_delete=False) as fwr: - fwr_id = fwr['firewall_rule']['id'] - req = self.new_delete_request('firewall_rules', fwr_id) - res = req.get_response(self.ext_api) - self.assertEqual(204, res.status_int) - self.assertRaises(f_exc.FirewallRuleNotFound, - self.plugin.get_firewall_rule, - ctx, fwr_id) - - def test_delete_firewall_rule_with_policy_associated(self): - attrs = self._get_test_firewall_rule_attrs() - with self.firewall_rule() as fwr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - fwr_id = fwr['firewall_rule']['id'] - data = {'firewall_policy': {'firewall_rules': [fwr_id]}} - req = self.new_update_request('firewall_policies', data, - fwp['firewall_policy']['id']) - req.get_response(self.ext_api) - req = self.new_delete_request('firewall_rules', fwr_id) - res = req.get_response(self.ext_api) - self.assertEqual(409, res.status_int) - - def _test_create_firewall(self, attrs): - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - name=attrs['name'], - firewall_policy_id=fwp_id, - admin_state_up=ADMIN_STATE_UP - ) as firewall: - for k, v in six.iteritems(attrs): - self.assertEqual(v, firewall['firewall'][k]) - - def test_create_firewall(self): - attrs = self._get_test_firewall_attrs("firewall1") - self._test_create_firewall(attrs) - - def test_create_firewall_with_dvr(self): - cfg.CONF.set_override('router_distributed', True) - attrs = self._get_test_firewall_attrs("firewall1", "CREATED") - self._test_create_firewall(attrs) - - def test_create_firewall_with_fwp_does_not_exist(self): - fmt = self.fmt - fw_name = "firewall1" - description = "my_firewall1" - not_found_fwp_id = uuidutils.generate_uuid() - self._create_firewall(fmt, fw_name, - description, not_found_fwp_id, - ADMIN_STATE_UP, - expected_res_status=404) - - def test_create_firewall_with_fwp_not_found_on_different_tenant(self): - fmt = self.fmt - fw_name = "firewall1" - description = "my_firewall1" - with self.firewall_policy(shared=False, tenant_id='tenant2') as fwp: - fwp_id = fwp['firewall_policy']['id'] - ctx = context.Context('not_admin', 'tenant1') - self._create_firewall(fmt, fw_name, - description, fwp_id, - context=ctx, - expected_res_status=404) - - def test_create_firewall_with_admin_and_fwp_different_tenant(self): - fmt = self.fmt - fw_name = "firewall1" - description = "my_firewall1" - with self.firewall_policy(shared=False, tenant_id='tenant2') as fwp: - fwp_id = fwp['firewall_policy']['id'] - ctx = context.get_admin_context() - self._create_firewall(fmt, fw_name, - description, fwp_id, - tenant_id="admin-tenant", - context=ctx, - expected_res_status=409) - - def test_create_firewall_with_admin_and_fwp_is_shared(self): - fw_name = "fw_with_shared_fwp" - with self.firewall_policy(tenant_id="tenantX") as fwp: - fwp_id = fwp['firewall_policy']['id'] - ctx = context.get_admin_context() - target_tenant = 'tenant1' - with self.firewall(name=fw_name, firewall_policy_id=fwp_id, - tenant_id=target_tenant, context=ctx, - admin_state_up=ADMIN_STATE_UP) as fw: - self.assertEqual(target_tenant, fw['firewall']['tenant_id']) - - def test_show_firewall(self): - name = "firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - name=name, - firewall_policy_id=fwp_id, - admin_state_up=ADMIN_STATE_UP) as firewall: - req = self.new_show_request('firewalls', - firewall['firewall']['id'], - fmt=self.fmt) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall'][k]) - - def test_list_firewalls(self): - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(name='fw1', tenant_id='tenant1', - firewall_policy_id=fwp_id, - description='fw') as fw1, \ - self.firewall(name='fw2', tenant_id='tenant2', - firewall_policy_id=fwp_id, - description='fw') as fw2, \ - self.firewall(name='fw3', tenant_id='tenant3', - firewall_policy_id=fwp_id, - description='fw') as fw3: - fwalls = [fw1, fw2, fw3] - self._test_list_resources('firewall', fwalls, - query_params='description=fw') - - def test_update_firewall(self): - name = "new_firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=ADMIN_STATE_UP) as firewall: - data = {'firewall': {'name': name}} - req = self.new_update_request('firewalls', data, - firewall['firewall']['id']) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall'][k]) - - def test_update_firewall_with_fwp(self): - ctx = context.Context('not_admin', 'tenant1') - with self.firewall_policy() as fwp1, \ - self.firewall_policy( - tenant_id='tenant1', shared=False) as fwp2, \ - self.firewall(firewall_policy_id=fwp1['firewall_policy']['id'], - context=ctx) as fw: - fw_id = fw['firewall']['id'] - fwp2_id = fwp2['firewall_policy']['id'] - data = {'firewall': {'firewall_policy_id': fwp2_id}} - req = self.new_update_request('firewalls', data, fw_id, - context=ctx) - res = req.get_response(self.ext_api) - self.assertEqual(200, res.status_int) - - def test_update_firewall_with_shared_fwp(self): - ctx = context.Context('not_admin', 'tenant1') - with self.firewall_policy() as fwp1, \ - self.firewall_policy(tenant_id='tenant2') as fwp2, \ - self.firewall(firewall_policy_id=fwp1['firewall_policy']['id'], - context=ctx) as fw: - fw_id = fw['firewall']['id'] - fwp2_id = fwp2['firewall_policy']['id'] - data = {'firewall': {'firewall_policy_id': fwp2_id}} - req = self.new_update_request('firewalls', data, fw_id, - context=ctx) - res = req.get_response(self.ext_api) - self.assertEqual(200, res.status_int) - - def test_update_firewall_with_admin_and_fwp_different_tenant(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp1, \ - self.firewall_policy( - tenant_id='tenant2', shared=False) as fwp2, \ - self.firewall(firewall_policy_id=fwp1['firewall_policy']['id'], - context=ctx) as fw: - fw_id = fw['firewall']['id'] - fwp2_id = fwp2['firewall_policy']['id'] - data = {'firewall': {'firewall_policy_id': fwp2_id}} - req = self.new_update_request('firewalls', data, fw_id, - context=ctx) - res = req.get_response(self.ext_api) - self.assertEqual(409, res.status_int) - - def test_update_firewall_fwp_not_found_on_different_tenant(self): - with self.firewall_policy(name='fwp1', tenant_id='tenant1', - do_delete=False) as fwp1, \ - self.firewall_policy(name='fwp2', shared=False, - tenant_id='tenant2') as fwp2: - - fwps = [fwp1, fwp2] - # create firewall using fwp1 exists the same tenant. - fwp1_id = fwps[0]['firewall_policy']['id'] - fwp2_id = fwps[1]['firewall_policy']['id'] - ctx = context.Context('not_admin', 'tenant1') - with self.firewall(firewall_policy_id=fwp1_id, - context=ctx) as firewall: - fw_id = firewall['firewall']['id'] - fw_db = self.plugin._get_firewall(ctx, fw_id) - fw_db['status'] = nl_constants.ACTIVE - # update firewall from fwp1 to fwp2(different tenant) - data = {'firewall': {'firewall_policy_id': fwp2_id}} - req = self.new_update_request('firewalls', data, fw_id, - context=ctx) - res = req.get_response(self.ext_api) - self.assertEqual(404, res.status_int) - - def test_delete_firewall(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id, - do_delete=False) as fw: - fw_id = fw['firewall']['id'] - req = self.new_delete_request('firewalls', fw_id) - res = req.get_response(self.ext_api) - self.assertEqual(204, res.status_int) - self.assertRaises(f_exc.FirewallNotFound, - self.plugin.get_firewall, - ctx, fw_id) - - def test_insert_rule_in_policy_with_prior_rules_added_via_update(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with self.firewall_rule(name='fwr1') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2, \ - self.firewall_rule(name='fwr3') as fwr3: - frs = [fwr1, fwr2, fwr3] - fr1 = frs[0:2] - fwr3 = frs[2] - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - fw_rule_ids = [r['firewall_rule']['id'] for r in fr1] - attrs['firewall_rules'] = fw_rule_ids[:] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - self._rule_action('insert', fwp_id, fw_rule_ids[0], - insert_before=fw_rule_ids[0], - insert_after=None, - expected_code=webob.exc.HTTPConflict.code, - expected_body=None) - fwr3_id = fwr3['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr3_id) - self._rule_action('insert', fwp_id, fwr3_id, - insert_before=fw_rule_ids[0], - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - - def test_insert_rule_in_policy_failures(self): - with self.firewall_rule(name='fwr1') as fr1: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - fr1_id = fr1['firewall_rule']['id'] - fw_rule_ids = [fr1_id] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - # test inserting with empty request body - self._rule_action('insert', fwp_id, '123', - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None, body_data={}) - # test inserting when firewall_rule_id is missing in - # request body - insert_data = {'insert_before': '123', - 'insert_after': '456'} - self._rule_action('insert', fwp_id, '123', - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None, - body_data=insert_data) - # test inserting when firewall_rule_id is None - insert_data = {'firewall_rule_id': None, - 'insert_before': '123', - 'insert_after': '456'} - self._rule_action('insert', fwp_id, '123', - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None, - body_data=insert_data) - # test inserting when firewall_policy_id is incorrect - self._rule_action('insert', '123', fr1_id, - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None) - # test inserting when firewall_policy_id is None - self._rule_action('insert', None, fr1_id, - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None) - - def test_insert_rule_for_previously_associated_rule(self): - with self.firewall_rule() as fwr: - fwr_id = fwr['firewall_rule']['id'] - fw_rule_ids = [fwr_id] - with self.firewall_policy(firewall_rules=fw_rule_ids): - with self.firewall_policy(name='firewall_policy2') as fwp: - fwp_id = fwp['firewall_policy']['id'] - insert_data = {'firewall_rule_id': fwr_id} - self._rule_action( - 'insert', fwp_id, fwr_id, insert_before=None, - insert_after=None, - expected_code=webob.exc.HTTPConflict.code, - expected_body=None, body_data=insert_data) - - def test_insert_rule_for_prev_associated_ref_rule(self): - with self.firewall_rule(name='fwr0') as fwr0, \ - self.firewall_rule(name='fwr1') as fwr1: - fwr = [fwr0, fwr1] - fwr0_id = fwr[0]['firewall_rule']['id'] - fwr1_id = fwr[1]['firewall_rule']['id'] - with self.firewall_policy(name='fwp0') as fwp0, \ - self.firewall_policy(name='fwp1', - firewall_rules=[fwr1_id]) as fwp1: - fwp = [fwp0, fwp1] - fwp0_id = fwp[0]['firewall_policy']['id'] - # test inserting before a rule which - # is associated with different policy - self._rule_action('insert', fwp0_id, fwr0_id, - insert_before=fwr1_id, - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None) - # test inserting after a rule which - # is associated with different policy - self._rule_action('insert', fwp0_id, fwr0_id, - insert_after=fwr1_id, - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None) - - def test_insert_rule_for_policy_of_other_tenant(self): - with self.firewall_rule(tenant_id='tenant-2', shared=False) as fwr: - fwr_id = fwr['firewall_rule']['id'] - with self.firewall_policy(name='firewall_policy') as fwp: - fwp_id = fwp['firewall_policy']['id'] - insert_data = {'firewall_rule_id': fwr_id} - self._rule_action( - 'insert', fwp_id, fwr_id, insert_before=None, - insert_after=None, - expected_code=webob.exc.HTTPConflict.code, - expected_body=None, body_data=insert_data) - - def test_insert_rule_in_policy(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with self.firewall_rule(name='fwr0') as fwr0, \ - self.firewall_rule(name='fwr1') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2, \ - self.firewall_rule(name='fwr3') as fwr3, \ - self.firewall_rule(name='fwr4') as fwr4, \ - self.firewall_rule(name='fwr5') as fwr5, \ - self.firewall_rule(name='fwr6') as fwr6: - fwr = [fwr0, fwr1, fwr2, fwr3, fwr4, fwr5, fwr6] - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - # test insert when rule list is empty - fwr0_id = fwr[0]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr0_id) - self._rule_action('insert', fwp_id, fwr0_id, - insert_before=None, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert at top of rule list, insert_before and - # insert_after not provided - fwr1_id = fwr[1]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr1_id) - insert_data = {'firewall_rule_id': fwr1_id} - self._rule_action('insert', fwp_id, fwr0_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs, body_data=insert_data) - # test insert at top of list above existing rule - fwr2_id = fwr[2]['firewall_rule']['id'] - attrs['firewall_rules'].insert(0, fwr2_id) - self._rule_action('insert', fwp_id, fwr2_id, - insert_before=fwr1_id, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert at bottom of list - fwr3_id = fwr[3]['firewall_rule']['id'] - attrs['firewall_rules'].append(fwr3_id) - self._rule_action('insert', fwp_id, fwr3_id, - insert_before=None, - insert_after=fwr0_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert in the middle of the list using - # insert_before - fwr4_id = fwr[4]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr4_id) - self._rule_action('insert', fwp_id, fwr4_id, - insert_before=fwr1_id, - insert_after=None, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert in the middle of the list using - # insert_after - fwr5_id = fwr[5]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr5_id) - self._rule_action('insert', fwp_id, fwr5_id, - insert_before=None, - insert_after=fwr2_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - # test insert when both insert_before and - # insert_after are set - fwr6_id = fwr[6]['firewall_rule']['id'] - attrs['firewall_rules'].insert(1, fwr6_id) - self._rule_action('insert', fwp_id, fwr6_id, - insert_before=fwr5_id, - insert_after=fwr5_id, - expected_code=webob.exc.HTTPOk.code, - expected_body=attrs) - - def test_remove_rule_and_not_associated(self): - with self.firewall_rule(name='fwr0') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2: - associated = fwr1['firewall_rule']['id'] - with self.firewall_policy( - name='firewall_policy2', firewall_rules=[associated]) as fwp: - fwp_id = fwp['firewall_policy']['id'] - not_associated = fwr2['firewall_rule']['id'] - msg = "Firewall rule {0} is not associated with " \ - "firewall policy {1}.".format(not_associated, fwp_id) - result = self._rule_action( - 'remove', fwp_id, not_associated, - insert_before=None, - insert_after=None, - expected_code=webob.exc.HTTPBadRequest.code, - body_data={'firewall_rule_id': not_associated}) - self.assertEqual(msg, result['NeutronError']['message']) - - def test_remove_rule_from_policy(self): - attrs = self._get_test_firewall_policy_attrs() - attrs['audited'] = False - attrs['firewall_list'] = [] - with self.firewall_rule(name='fwr1') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2, \ - self.firewall_rule(name='fwr3') as fwr3: - fr1 = [fwr1, fwr2, fwr3] - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['id'] = fwp_id - fw_rule_ids = [r['firewall_rule']['id'] for r in fr1] - attrs['firewall_rules'] = fw_rule_ids[:] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - # test removing a rule from a policy that does not exist - self._rule_action('remove', '123', fw_rule_ids[1], - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None) - # test removing a rule in the middle of the list - attrs['firewall_rules'].remove(fw_rule_ids[1]) - self._rule_action('remove', fwp_id, fw_rule_ids[1], - expected_body=attrs) - # test removing a rule at the top of the list - attrs['firewall_rules'].remove(fw_rule_ids[0]) - self._rule_action('remove', fwp_id, fw_rule_ids[0], - expected_body=attrs) - # test removing remaining rule in the list - attrs['firewall_rules'].remove(fw_rule_ids[2]) - self._rule_action('remove', fwp_id, fw_rule_ids[2], - expected_body=attrs) - # test removing rule that is not associated with the policy - self._rule_action('remove', fwp_id, fw_rule_ids[2], - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None) - - def test_remove_rule_from_policy_failures(self): - with self.firewall_rule(name='fwr1') as fr1: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - fw_rule_ids = [fr1['firewall_rule']['id']] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - # test removing rule that does not exist - self._rule_action('remove', fwp_id, '123', - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None) - # test removing rule with bad request - self._rule_action('remove', fwp_id, '123', - expected_code=webob.exc.HTTPBadRequest.code, - expected_body=None, body_data={}) - # test removing rule with firewall_rule_id set to None - self._rule_action('remove', fwp_id, '123', - expected_code=webob.exc.HTTPNotFound.code, - expected_body=None, - body_data={'firewall_rule_id': None}) - - def test_check_router_has_no_firewall_raises(self): - fw_plugin = mock.Mock() - directory.add_plugin('FIREWALL', fw_plugin) - fw_plugin.get_firewalls.return_value = [mock.ANY] - kwargs = { - 'context': mock.ANY, - 'router': {'id': 'foo_id', 'tenant_id': 'foo_tenant'} - } - self.assertRaises( - l3.RouterInUse, - fdb.migration_callback, - 'router', 'before_event', mock.ANY, - **kwargs) - - def test_check_router_has_no_firewall_passes(self): - with mock.patch.object(directory, 'get_plugin', return_value=None): - kwargs = {'context': mock.ANY, 'router': mock.ANY} - self.assertIsNone(fdb.migration_callback( - mock.ANY, mock.ANY, mock.ANY, **kwargs)) - - def test_show_firewall_rule_by_name(self): - with self.firewall_rule(name='firewall_Rule1') as fw_rule: - res = self._show('firewall_rules', - fw_rule['firewall_rule']['id']) - self.assertEqual('firewall_Rule1', res['firewall_rule']['name']) - - def test_show_firewall_policy_by_name(self): - with self.firewall_policy( - name='firewall_Policy1') as fw_policy: - res = self._show('firewall_policies', - fw_policy['firewall_policy']['id']) - self.assertEqual( - 'firewall_Policy1', res['firewall_policy']['name']) - - def test_show_firewall_by_name(self): - with self.firewall(name='fireWall1') as fw: - res = self._show('firewalls', fw['firewall']['id']) - self.assertEqual('fireWall1', res['firewall']['name']) - - def test_create_firewall_rule_with_invalid_action_type(self): - attrs = self._get_test_firewall_rule_attrs() - attrs['action'] = 123 - res = self._create_firewall_rule(self.fmt, **attrs) - self.assertEqual(400, res.status_int) diff --git a/neutron_fwaas/tests/unit/services/firewall/service_drivers/agents/drivers/linux/test_iptables_fwaas.py b/neutron_fwaas/tests/unit/services/firewall/service_drivers/agents/drivers/linux/test_iptables_fwaas.py deleted file mode 100644 index 3b5bb59a6..000000000 --- a/neutron_fwaas/tests/unit/services/firewall/service_drivers/agents/drivers/linux/test_iptables_fwaas.py +++ /dev/null @@ -1,412 +0,0 @@ -# Copyright 2013 Dell 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. - -import copy - -import mock -from neutron.tests import base -from neutron.tests.unit.api.v2 import test_base as test_api_v2 - -import neutron_fwaas.services.firewall.service_drivers.agents.drivers.linux.\ - iptables_fwaas as fwaas - - -_uuid = test_api_v2._uuid -FAKE_SRC_PREFIX = '10.0.0.0/24' -FAKE_DST_PREFIX = '20.0.0.0/24' -FAKE_PROTOCOL = 'tcp' -FAKE_SRC_PORT = 5000 -FAKE_DST_PORT = 22 -FAKE_FW_ID = 'fake-fw-uuid' -FW_LEGACY = 'legacy' - - -class IptablesFwaasTestCase(base.BaseTestCase): - def setUp(self): - super(IptablesFwaasTestCase, self).setUp() - self.conntrack_driver = mock.Mock() - self.conntrack_driver.initialize = mock.Mock() - self.conntrack_driver.delete_entries = mock.Mock() - self.conntrack_driver.flush_entries = mock.Mock() - self.iptables_cls_p = mock.patch( - 'neutron.agent.linux.iptables_manager.IptablesManager') - self.iptables_cls_p.start() - self.firewall = fwaas.IptablesFwaasDriver() - self.firewall.conntrack = self.conntrack_driver - - def _fake_rules_v4(self, fwid, apply_list): - rule_list = [] - rule1 = {'enabled': True, - 'action': 'allow', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '80', - 'source_ip_address': '10.24.4.2', - 'id': 'fake-fw-rule1'} - rule2 = {'enabled': True, - 'action': 'deny', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '22', - 'id': 'fake-fw-rule2'} - rule3 = {'enabled': True, - 'action': 'reject', - 'ip_version': 4, - 'protocol': 'tcp', - 'destination_port': '23', - 'id': 'fake-fw-rule3'} - ingress_chain = ('iv4%s' % fwid)[:11] - egress_chain = ('ov4%s' % fwid)[:11] - for router_info_inst in apply_list: - v4filter_inst = router_info_inst.iptables_manager.ipv4['filter'] - v4filter_inst.chains.append(ingress_chain) - v4filter_inst.chains.append(egress_chain) - rule_list.append(rule1) - rule_list.append(rule2) - rule_list.append(rule3) - return rule_list - - def _fake_firewall_no_rule(self): - rule_list = [] - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': True, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': rule_list} - return fw_inst - - def _fake_firewall(self, rule_list): - _rule_list = copy.deepcopy(rule_list) - for rule in _rule_list: - rule['position'] = str(_rule_list.index(rule)) - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': True, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': _rule_list} - return fw_inst - - def _fake_firewall_with_admin_down(self, rule_list): - fw_inst = {'id': FAKE_FW_ID, - 'admin_state_up': False, - 'tenant_id': 'tenant-uuid', - 'firewall_rule_list': rule_list} - return fw_inst - - def _fake_apply_list(self, router_count=1, distributed=False, - distributed_mode=None): - apply_list = [] - while router_count > 0: - iptables_inst = mock.Mock() - if distributed is not None: - router_inst = {'distributed': distributed} - else: - router_inst = {} - v4filter_inst = mock.Mock() - v6filter_inst = mock.Mock() - v4filter_inst.chains = [] - v6filter_inst.chains = [] - iptables_inst.ipv4 = {'filter': v4filter_inst} - iptables_inst.ipv6 = {'filter': v6filter_inst} - router_info_inst = mock.Mock() - router_info_inst.iptables_manager = iptables_inst - router_info_inst.snat_iptables_manager = iptables_inst - if distributed_mode == 'dvr': - router_info_inst.rtr_fip_connect = True - router_info_inst.router = router_inst - apply_list.append(router_info_inst) - router_count -= 1 - return apply_list - - def _setup_firewall_with_rules(self, func, router_count=1, - distributed=False, distributed_mode=None): - apply_list = self._fake_apply_list(router_count=router_count, - distributed=distributed, distributed_mode=distributed_mode) - rule_list = self._fake_rules_v4(FAKE_FW_ID, apply_list) - firewall = self._fake_firewall(rule_list) - if distributed: - if distributed_mode == 'dvr_snat': - if_prefix = 'sg-+' - if distributed_mode == 'dvr': - if_prefix = 'rfp-+' - else: - if_prefix = 'qr-+' - distributed_mode = 'legacy' - func(distributed_mode, apply_list, firewall) - invalid_rule = '-m state --state INVALID -j DROP' - est_rule = '-m state --state RELATED,ESTABLISHED -j ACCEPT' - rule1 = '-p tcp -s 10.24.4.2/32 -m tcp --dport 80 -j ACCEPT' - rule2 = '-p tcp -m tcp --dport 22 -j DROP' - rule3 = '-p tcp -m tcp --dport 23 -j REJECT' - ingress_chain = 'iv4%s' % firewall['id'] - egress_chain = 'ov4%s' % firewall['id'] - bname = fwaas.iptables_manager.binary_name - ipt_mgr_ichain = '%s-%s' % (bname, ingress_chain[:11]) - ipt_mgr_echain = '%s-%s' % (bname, egress_chain[:11]) - for router_info_inst in apply_list: - v4filter_inst = router_info_inst.iptables_manager.ipv4['filter'] - calls = [mock.call.remove_chain('iv4fake-fw-uuid'), - mock.call.remove_chain('ov4fake-fw-uuid'), - mock.call.remove_chain('fwaas-default-policy'), - mock.call.add_chain('fwaas-default-policy'), - mock.call.add_rule('fwaas-default-policy', '-j DROP'), - mock.call.add_chain(ingress_chain), - mock.call.add_rule(ingress_chain, invalid_rule), - mock.call.add_rule(ingress_chain, est_rule), - mock.call.add_chain(egress_chain), - mock.call.add_rule(egress_chain, invalid_rule), - mock.call.add_rule(egress_chain, est_rule), - mock.call.add_rule(ingress_chain, rule1), - mock.call.add_rule(egress_chain, rule1), - mock.call.add_rule(ingress_chain, rule2), - mock.call.add_rule(egress_chain, rule2), - mock.call.add_rule(ingress_chain, rule3), - mock.call.add_rule(egress_chain, rule3), - mock.call.add_rule('FORWARD', - '-o %s -j %s' % (if_prefix, - ipt_mgr_ichain)), - mock.call.add_rule('FORWARD', - '-i %s -j %s' % (if_prefix, - ipt_mgr_echain)), - mock.call.add_rule('FORWARD', - '-o %s -j %s-fwaas-defau' % (if_prefix, - bname)), - mock.call.add_rule('FORWARD', - '-i %s -j %s-fwaas-defau' % (if_prefix, - bname))] - v4filter_inst.assert_has_calls(calls) - - def test_create_firewall_no_rules(self): - apply_list = self._fake_apply_list() - firewall = self._fake_firewall_no_rule() - self.firewall.create_firewall('legacy', apply_list, firewall) - invalid_rule = '-m state --state INVALID -j DROP' - est_rule = '-m state --state RELATED,ESTABLISHED -j ACCEPT' - bname = fwaas.iptables_manager.binary_name - for ip_version in (4, 6): - ingress_chain = ('iv%s%s' % (ip_version, firewall['id'])) - egress_chain = ('ov%s%s' % (ip_version, firewall['id'])) - calls = [mock.call.remove_chain( - 'iv%sfake-fw-uuid' % ip_version), - mock.call.remove_chain( - 'ov%sfake-fw-uuid' % ip_version), - mock.call.remove_chain('fwaas-default-policy'), - mock.call.add_chain('fwaas-default-policy'), - mock.call.add_rule('fwaas-default-policy', '-j DROP'), - mock.call.add_chain(ingress_chain), - mock.call.add_rule(ingress_chain, invalid_rule), - mock.call.add_rule(ingress_chain, est_rule), - mock.call.add_chain(egress_chain), - mock.call.add_rule(egress_chain, invalid_rule), - mock.call.add_rule(egress_chain, est_rule), - mock.call.add_rule('FORWARD', - '-o qr-+ -j %s-fwaas-defau' % bname), - mock.call.add_rule('FORWARD', - '-i qr-+ -j %s-fwaas-defau' % bname)] - if ip_version == 4: - v4filter_inst = apply_list[0].iptables_manager.ipv4['filter'] - v4filter_inst.assert_has_calls(calls) - else: - v6filter_inst = apply_list[0].iptables_manager.ipv6['filter'] - v6filter_inst.assert_has_calls(calls) - - def test_create_firewall_with_rules(self): - self._setup_firewall_with_rules(self.firewall.create_firewall) - - def test_create_firewall_with_rules_without_distributed_attr(self): - self._setup_firewall_with_rules(self.firewall.create_firewall, - distributed=None) - - def test_create_firewall_with_rules_two_routers(self): - self._setup_firewall_with_rules(self.firewall.create_firewall, - router_count=2) - - def test_update_firewall_with_rules(self): - self._setup_firewall_with_rules(self.firewall.update_firewall) - - def test_update_firewall_with_rules_without_distributed_attr(self): - self._setup_firewall_with_rules(self.firewall.update_firewall, - distributed=None) - - def _test_delete_firewall(self, distributed=False): - apply_list = self._fake_apply_list(distributed=distributed) - firewall = self._fake_firewall_no_rule() - self.firewall.delete_firewall('legacy', apply_list, firewall) - ingress_chain = 'iv4%s' % firewall['id'] - egress_chain = 'ov4%s' % firewall['id'] - calls = [mock.call.remove_chain(ingress_chain), - mock.call.remove_chain(egress_chain), - mock.call.remove_chain('fwaas-default-policy')] - apply_list[0].iptables_manager.ipv4['filter'].assert_has_calls(calls) - - def test_delete_firewall(self): - self._test_delete_firewall() - - def test_delete_firewall_without_distributed_attr(self): - self._test_delete_firewall(distributed=None) - - def test_create_firewall_with_admin_down(self): - apply_list = self._fake_apply_list() - rule_list = self._fake_rules_v4(FAKE_FW_ID, apply_list) - firewall = self._fake_firewall_with_admin_down(rule_list) - self.firewall.create_firewall('legacy', apply_list, firewall) - calls = [mock.call.remove_chain('iv4fake-fw-uuid'), - mock.call.remove_chain('ov4fake-fw-uuid'), - mock.call.remove_chain('fwaas-default-policy'), - mock.call.add_chain('fwaas-default-policy'), - mock.call.add_rule('fwaas-default-policy', '-j DROP')] - apply_list[0].iptables_manager.ipv4['filter'].assert_has_calls(calls) - - def test_create_firewall_with_rules_dvr_snat(self): - self._setup_firewall_with_rules(self.firewall.create_firewall, - distributed=True, distributed_mode='dvr_snat') - - def test_update_firewall_with_rules_dvr_snat(self): - self._setup_firewall_with_rules(self.firewall.update_firewall, - distributed=True, distributed_mode='dvr_snat') - - def test_create_firewall_with_rules_dvr(self): - self._setup_firewall_with_rules(self.firewall.create_firewall, - distributed=True, distributed_mode='dvr') - - def test_update_firewall_with_rules_dvr(self): - self._setup_firewall_with_rules(self.firewall.update_firewall, - distributed=True, distributed_mode='dvr') - - def test_remove_conntrack_new_firewall(self): - apply_list = self._fake_apply_list() - firewall = self._fake_firewall_no_rule() - self.firewall.create_firewall(FW_LEGACY, apply_list, firewall) - for router_info_inst in apply_list: - namespace = router_info_inst.iptables_manager.namespace - calls = [mock.call(namespace)] - self.conntrack_driver.flush_entries.assert_has_calls(calls) - - def test_remove_conntrack_inserted_rule(self): - apply_list = self._fake_apply_list() - rule_list = self._fake_rules_v4(FAKE_FW_ID, apply_list) - firewall = self._fake_firewall(rule_list) - self.firewall.create_firewall(FW_LEGACY, apply_list, firewall) - self.firewall.pre_firewall = dict(firewall) - insert_rule = {'enabled': True, - 'action': 'deny', - 'ip_version': 4, - 'protocol': 'icmp', - 'id': 'fake-fw-rule'} - rule_list.insert(2, insert_rule) - firewall = self._fake_firewall(rule_list) - self.firewall.update_firewall(FW_LEGACY, apply_list, firewall) - rules_changed = [ - {'destination_port': '23', - 'position': '2', - 'protocol': 'tcp', - 'ip_version': 4, - 'enabled': True, - 'action': 'reject', - 'id': 'fake-fw-rule3'}, - {'destination_port': '23', - 'position': '3', - 'protocol': 'tcp', - 'ip_version': 4, - 'enabled': True, - 'action': 'reject', - 'id': 'fake-fw-rule3'} - ] - rules_inserted = [ - {'id': 'fake-fw-rule', - 'protocol': 'icmp', - 'ip_version': 4, - 'enabled': True, - 'action': 'deny', - 'position': '2'} - ] - for router_info_inst in apply_list: - namespace = router_info_inst.iptables_manager.namespace - self.conntrack_driver.delete_entries.assert_called_once_with( - rules_changed + rules_inserted, namespace - ) - - def test_remove_conntrack_removed_rule(self): - apply_list = self._fake_apply_list() - rule_list = self._fake_rules_v4(FAKE_FW_ID, apply_list) - firewall = self._fake_firewall(rule_list) - self.firewall.create_firewall(FW_LEGACY, apply_list, firewall) - self.firewall.pre_firewall = dict(firewall) - remove_rule = rule_list[1] - rule_list.remove(remove_rule) - firewall = self._fake_firewall(rule_list) - self.firewall.update_firewall(FW_LEGACY, apply_list, firewall) - rules_changed = [ - {'destination_port': '23', - 'position': '2', - 'protocol': 'tcp', - 'ip_version': 4, - 'enabled': True, - 'action': 'reject', - 'id': 'fake-fw-rule3'}, - {'destination_port': '23', - 'position': '1', - 'protocol': 'tcp', - 'ip_version': 4, - 'enabled': True, - 'action': 'reject', - 'id': 'fake-fw-rule3'} - ] - rules_removed = [ - {'enabled': True, - 'position': '1', - 'protocol': 'tcp', - 'id': 'fake-fw-rule2', - 'ip_version': 4, - 'action': 'deny', - 'destination_port': '22'} - ] - for router_info_inst in apply_list: - namespace = router_info_inst.iptables_manager.namespace - self.conntrack_driver.delete_entries.assert_called_once_with( - rules_changed + rules_removed, namespace - ) - - def test_remove_conntrack_changed_rule(self): - apply_list = self._fake_apply_list() - rule_list = self._fake_rules_v4(FAKE_FW_ID, apply_list) - firewall = self._fake_firewall(rule_list) - self.firewall.create_firewall(FW_LEGACY, apply_list, firewall) - income_rule = {'enabled': True, - 'action': 'deny', - 'ip_version': 4, - 'protocol': 'tcp', - 'id': 'fake-fw-rule3'} - rule_list[2] = income_rule - firewall = self._fake_firewall(rule_list) - self.firewall.update_firewall(FW_LEGACY, apply_list, firewall) - rules_changed = [ - {'id': 'fake-fw-rule3', - 'enabled': True, - 'action': 'reject', - 'position': '2', - 'destination_port': '23', - 'ip_version': 4, - 'protocol': 'tcp'}, - {'position': '2', - 'enabled': True, - 'action': 'deny', - 'id': 'fake-fw-rule3', - 'ip_version': 4, - 'protocol': 'tcp'} - ] - for router_info_inst in apply_list: - namespace = router_info_inst.iptables_manager.namespace - self.conntrack_driver.delete_entries.assert_called_once_with( - rules_changed, namespace - ) diff --git a/neutron_fwaas/tests/unit/services/firewall/service_drivers/agents/l3reference/test_firewall_l3_agent.py b/neutron_fwaas/tests/unit/services/firewall/service_drivers/agents/l3reference/test_firewall_l3_agent.py deleted file mode 100644 index 5e29d6aa8..000000000 --- a/neutron_fwaas/tests/unit/services/firewall/service_drivers/agents/l3reference/test_firewall_l3_agent.py +++ /dev/null @@ -1,361 +0,0 @@ -# Copyright (c) 2013 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. - -import mock -from neutron.agent.l3 import l3_agent_extension_api as l3_agent_api -from neutron.agent.l3 import router_info -from neutron.agent.linux import ip_lib -from neutron.conf.agent.l3 import config as l3_config -from neutron.conf import common as base_config -from neutron_lib import context -from oslo_config import cfg -from oslo_utils import uuidutils -import testtools - -from neutron_fwaas.common import fwaas_constants -from neutron_fwaas.services.firewall.service_drivers.agents \ - import firewall_agent_api -from neutron_fwaas.services.firewall.service_drivers.agents.l3reference \ - import firewall_l3_agent -from neutron_fwaas.tests import base -from neutron_fwaas.tests.unit.services.firewall.service_drivers.agents \ - import test_firewall_agent_api - - -class FWaasHelper(object): - def __init__(self, host): - pass - - -class FWaasAgent(firewall_l3_agent.FWaaSL3AgentExtension, FWaasHelper): - neutron_service_plugins = [] - - -def _setup_test_agent_class(service_plugins): - class FWaasTestAgent(firewall_l3_agent.FWaaSL3AgentExtension, - FWaasHelper): - neutron_service_plugins = service_plugins - - def __init__(self, conf): - self.event_observers = mock.Mock() - self.conf = conf - super(FWaasTestAgent, self).__init__("myhost", conf) - - return FWaasTestAgent - - -class TestFwaasL3AgentRpcCallback(base.BaseTestCase): - def setUp(self): - super(TestFwaasL3AgentRpcCallback, self).setUp() - - self.conf = cfg.ConfigOpts() - self.conf.register_opts(base_config.core_opts) - self.conf.register_opts(l3_config.OPTS) - self.conf.register_opts(firewall_agent_api.FWaaSOpts, 'fwaas') - self.api = FWaasAgent(host=None, conf=self.conf) - self.api.fwaas_driver = test_firewall_agent_api.NoopFwaasDriver() - self.adminContext = context.get_admin_context() - self.router_id = uuidutils.generate_uuid() - self.agent_conf = mock.Mock() - # For 'tenant_id' and 'project_id' keys - project_id = uuidutils.generate_uuid() - self.ri_kwargs = {'router': {'id': self.router_id, - 'tenant_id': project_id, - 'project_id': project_id}, - 'agent_conf': self.agent_conf, - 'interface_driver': mock.ANY, - 'use_ipv6': mock.ANY, - } - - def test_fw_config_match(self): - test_agent_class = _setup_test_agent_class([fwaas_constants.FIREWALL]) - cfg.CONF.set_override('enabled', True, 'fwaas') - with mock.patch('oslo_utils.importutils.import_object'): - test_agent_class(cfg.CONF) - - @testtools.skip('needs to be refactored for fwaas v2') - def test_fw_config_mismatch_plugin_enabled_agent_disabled(self): - test_agent_class = _setup_test_agent_class([fwaas_constants.FIREWALL]) - cfg.CONF.set_override('enabled', False, 'fwaas') - self.assertRaises(SystemExit, test_agent_class, cfg.CONF) - - def test_fw_plugin_list_unavailable(self): - test_agent_class = _setup_test_agent_class(None) - cfg.CONF.set_override('enabled', False, 'fwaas') - with mock.patch('oslo_utils.importutils.import_object'): - test_agent_class(cfg.CONF) - - def test_create_firewall(self): - fake_firewall = {'id': 0, 'tenant_id': 1, - 'admin_state_up': True, - 'add-router-ids': [1, 2]} - self.api.plugin_rpc = mock.Mock() - with mock.patch.object(self.api, '_get_router_info_list_for_tenant' - ) as mock_get_router_info_list_for_tenant, \ - mock.patch.object(self.api.fwaas_driver, 'create_firewall' - ) as mock_driver_create_firewall, \ - mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status' - ) as mock_set_firewall_status: - mock_driver_create_firewall.return_value = True - self.api.create_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - mock_get_router_info_list_for_tenant.assert_called_once_with( - fake_firewall['add-router-ids'], fake_firewall['tenant_id']) - - mock_set_firewall_status.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id'], - 'ACTIVE') - - def test_update_firewall_with_routers_added_and_deleted(self): - fake_firewall = {'id': 0, 'tenant_id': 1, - 'admin_state_up': True, - 'add-router-ids': [1, 2], - 'del-router-ids': [3, 4], - 'router_ids': [], - 'last-router': False} - - self.api.plugin_rpc = mock.Mock() - with mock.patch.object(self.api, '_get_router_info_list_for_tenant' - ) as mock_get_router_info_list_for_tenant, \ - mock.patch.object(self.api.fwaas_driver, 'update_firewall' - ) as mock_driver_delete_firewall, \ - mock.patch.object(self.api.fwaas_driver, 'delete_firewall' - ) as mock_driver_update_firewall, \ - mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status' - ) as mock_set_firewall_status: - - mock_driver_delete_firewall.return_value = True - mock_driver_update_firewall.return_value = True - - calls = [mock.call(fake_firewall['del-router-ids'], - fake_firewall['tenant_id']), - mock.call(fake_firewall['add-router-ids'], - fake_firewall['tenant_id'])] - - self.api.update_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - self.assertEqual( - mock_get_router_info_list_for_tenant.call_args_list, - calls) - - mock_set_firewall_status.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id'], - 'ACTIVE') - - def test_update_firewall_with_routers_added_and_admin_state_down(self): - fake_firewall = {'id': 0, 'tenant_id': 1, - 'admin_state_up': False, - 'add-router-ids': [1, 2], - 'del-router-ids': [], - 'router_ids': [], - 'last-router': False} - - self.api.plugin_rpc = mock.Mock() - with mock.patch.object(self.api, '_get_router_info_list_for_tenant' - ) as mock_get_router_info_list_for_tenant, \ - mock.patch.object(self.api.fwaas_driver, 'update_firewall' - ) as mock_driver_update_firewall, \ - mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status' - ) as mock_set_firewall_status: - - mock_driver_update_firewall.return_value = True - - self.api.update_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - mock_get_router_info_list_for_tenant.assert_called_once_with( - fake_firewall['add-router-ids'], fake_firewall['tenant_id']) - - mock_set_firewall_status.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id'], - 'DOWN') - - def test_update_firewall_with_all_routers_deleted(self): - fake_firewall = {'id': 0, 'tenant_id': 1, - 'admin_state_up': True, - 'add-router-ids': [], - 'del-router-ids': [3, 4], - 'last-router': True} - - self.api.plugin_rpc = mock.Mock() - with mock.patch.object(self.api, '_get_router_info_list_for_tenant' - ) as mock_get_router_info_list_for_tenant, \ - mock.patch.object(self.api.fwaas_driver, 'delete_firewall' - ) as mock_driver_delete_firewall, \ - mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status' - ) as mock_set_firewall_status: - - mock_driver_delete_firewall.return_value = True - - self.api.update_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - mock_get_router_info_list_for_tenant.assert_called_once_with( - fake_firewall['del-router-ids'], fake_firewall['tenant_id']) - - mock_set_firewall_status.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id'], - 'INACTIVE') - - def test_update_firewall_with_rtrs_and_no_rtrs_added_nor_deleted(self): - fake_firewall = {'id': 0, 'tenant_id': 1, - 'admin_state_up': True, - 'add-router-ids': [], - 'del-router-ids': [], - 'router_ids': [1, 2]} - self.api.plugin_rpc = mock.Mock() - with mock.patch.object(self.api.fwaas_driver, 'update_firewall' - ) as mock_driver_update_firewall, \ - mock.patch.object(self.api, '_get_router_info_list_for_tenant' - ) as mock_get_router_info_list_for_tenant, \ - mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status' - ) as mock_set_firewall_status: - - mock_driver_update_firewall.return_value = True - - self.api.update_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - mock_get_router_info_list_for_tenant.assert_called_once_with( - fake_firewall['router_ids'], fake_firewall['tenant_id']) - - mock_set_firewall_status.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id'], - 'ACTIVE') - - def test_update_firewall_with_no_rtrs_and_no_rtrs_added_nor_deleted(self): - fake_firewall = {'id': 0, 'tenant_id': 1, - 'admin_state_up': True, - 'add-router-ids': [], - 'del-router-ids': [], - 'router_ids': []} - self.api.plugin_rpc = mock.Mock() - with mock.patch.object(self.api.fwaas_driver, 'update_firewall' - ) as mock_driver_update_firewall, \ - mock.patch.object(self.api.fwplugin_rpc, 'set_firewall_status' - ) as mock_set_firewall_status: - - mock_driver_update_firewall.return_value = True - - self.api.update_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - mock_set_firewall_status.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id'], - 'INACTIVE') - - def test_delete_firewall(self): - fake_firewall = {'id': 0, 'tenant_id': 1, - 'admin_state_up': True, - 'add-router-ids': [], - 'del-router-ids': [3, 4], - 'last-router': True} - - self.api.plugin_rpc = mock.Mock() - with mock.patch.object(self.api, '_get_router_info_list_for_tenant' - ) as mock_get_router_info_list_for_tenant, \ - mock.patch.object(self.api.fwaas_driver, 'delete_firewall' - ) as mock_driver_delete_firewall, \ - mock.patch.object(self.api.fwplugin_rpc, 'firewall_deleted' - ) as mock_firewall_deleted: - - mock_driver_delete_firewall.return_value = True - self.api.delete_firewall( - context=mock.sentinel.context, - firewall=fake_firewall, host='host') - - mock_get_router_info_list_for_tenant.assert_called_once_with( - fake_firewall['del-router-ids'], fake_firewall['tenant_id']) - - mock_firewall_deleted.assert_called_once_with( - mock.sentinel.context, - fake_firewall['id']) - - def _prepare_router_data(self): - return router_info.RouterInfo(self.api, - self.router_id, - **self.ri_kwargs) - - def test_get_router_info_list_for_tenant(self): - ri = self._prepare_router_data() - router_info = {ri.router_id: ri} - self.api.router_info = router_info - - api_object = l3_agent_api.L3AgentExtensionAPI(router_info) - self.api.consume_api(api_object) - - routers = [ri.router] - router_ids = [router['id'] for router in routers] - - with mock.patch.object(ip_lib, - 'list_network_namespaces') as mock_list_netns: - mock_list_netns.return_value = [] - router_info_list = self.api._get_router_info_list_for_tenant( - router_ids, - ri.router['tenant_id']) - mock_list_netns.assert_called_once_with() - self.assertFalse(router_info_list) - - def _get_router_info_list_router_without_router_info_helper(self, - rtr_with_ri): - # ri.router with associated router_info (ri) - # rtr2 has no router_info - - ri = self._prepare_router_data() - rtr2 = {'id': uuidutils.generate_uuid(), - 'tenant_id': ri.router['tenant_id']} - - routers = [rtr2] - router_info = {} - ri_expected = [] - - if rtr_with_ri: - router_info[ri.router_id] = ri - routers.append(ri.router) - ri_expected.append(ri) - - self.api.router_info = router_info - router_ids = [router['id'] for router in routers] - - with mock.patch.object(ip_lib, - 'list_network_namespaces') as mock_list_netns: - mock_list_netns.return_value = [ri.ns_name] - api_object = l3_agent_api.L3AgentExtensionAPI(router_info) - self.api.consume_api(api_object) - router_info_list = self.api._get_router_info_list_for_tenant( - router_ids, - ri.router['tenant_id']) - self.assertEqual(ri_expected, router_info_list) - - def test_get_router_info_list_router_without_router_info(self): - self._get_router_info_list_router_without_router_info_helper( - rtr_with_ri=False) - - def test_get_router_info_list_two_routers_one_without_router_info(self): - self._get_router_info_list_router_without_router_info_helper( - rtr_with_ri=True) diff --git a/neutron_fwaas/tests/unit/services/firewall/test_fwaas_plugin.py b/neutron_fwaas/tests/unit/services/firewall/test_fwaas_plugin.py deleted file mode 100644 index 5b011416c..000000000 --- a/neutron_fwaas/tests/unit/services/firewall/test_fwaas_plugin.py +++ /dev/null @@ -1,786 +0,0 @@ -# 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. - -import mock -from neutron.api import extensions as api_ext -from neutron.common import config -from neutron.tests.common import helpers -from neutron.tests.unit.extensions import test_agent -from neutron.tests.unit.extensions import test_l3 as test_l3_plugin -from neutron_lib.api import attributes as attr -from neutron_lib.api.definitions import firewall as fwaas_def -from neutron_lib.api.definitions import firewallrouterinsertion -from neutron_lib import constants as nl_constants -from neutron_lib import context -from neutron_lib.exceptions import firewall_v1 as f_exc -from neutron_lib.plugins import constants as plugin_constants -from neutron_lib.plugins import directory -from neutron_lib.tests.unit import fake_notifier -from oslo_config import cfg -from oslo_utils import uuidutils -import six -from webob import exc - -from neutron_fwaas.db.firewall import firewall_db as fdb -import neutron_fwaas.extensions -from neutron_fwaas.extensions import firewall -from neutron_fwaas.services.firewall import fwaas_plugin -from neutron_fwaas.tests import base -from neutron_fwaas.tests.unit.db.firewall import ( - test_firewall_db as test_db_firewall) - -extensions_path = neutron_fwaas.extensions.__path__[0] - -FW_PLUGIN_KLASS = ( - "neutron_fwaas.services.firewall.fwaas_plugin.FirewallPlugin" -) - - -class FirewallTestExtensionManager(test_l3_plugin.L3TestExtensionManager): - - def get_resources(self): - res = super(FirewallTestExtensionManager, self).get_resources() - fwaas_def.RESOURCE_ATTRIBUTE_MAP['firewalls'].update( - firewallrouterinsertion.RESOURCE_ATTRIBUTE_MAP['firewalls']) - return res + firewall.Firewall.get_resources() - - def get_actions(self): - return [] - - def get_request_extensions(self): - return [] - - -class TestFirewallRouterInsertionBase( - test_db_firewall.FirewallPluginDbTestCase): - - def setUp(self, core_plugin=None, fw_plugin=None, ext_mgr=None): - self.agentapi_del_fw_p = mock.patch(test_db_firewall.DELETEFW_PATH, - create=True, new=test_db_firewall.FakeAgentApi().delete_firewall) - self.agentapi_del_fw_p.start() - - # the plugin without L3 support - plugin = 'neutron.tests.unit.extensions.test_l3.TestNoL3NatPlugin' - # the L3 service plugin - l3_plugin = ('neutron.tests.unit.extensions.test_l3.' - 'TestL3NatAgentSchedulingServicePlugin') - - cfg.CONF.set_override('api_extensions_path', extensions_path) - self.saved_attr_map = {} - for resource, attrs in six.iteritems(attr.RESOURCES): - self.saved_attr_map[resource] = attrs.copy() - if not fw_plugin: - fw_plugin = FW_PLUGIN_KLASS - service_plugins = {'l3_plugin_name': l3_plugin, - 'fw_plugin_name': fw_plugin} - - if not ext_mgr: - ext_mgr = FirewallTestExtensionManager() - super(test_db_firewall.FirewallPluginDbTestCase, self).setUp( - plugin=plugin, service_plugins=service_plugins, ext_mgr=ext_mgr) - - self.addCleanup(self.restore_attribute_map) - self.setup_notification_driver() - - self.l3_plugin = directory.get_plugin(plugin_constants.L3) - self.plugin = directory.get_plugin('FIREWALL') - self.callbacks = fwaas_plugin.FirewallCallbacks(self.plugin) - - def restore_attribute_map(self): - # Remove the fwaasrouterinsertion extension - fwaas_def.RESOURCE_ATTRIBUTE_MAP['firewalls'].pop('router_ids') - # Restore the original RESOURCE_ATTRIBUTE_MAP - attr.RESOURCES = self.saved_attr_map - - def _create_firewall(self, fmt, name, description, firewall_policy_id=None, - admin_state_up=True, expected_res_status=None, - **kwargs): - tenant_id = kwargs.get('tenant_id', self._tenant_id) - router_ids = kwargs.get('router_ids') - if firewall_policy_id is None: - res = self._create_firewall_policy(fmt, 'fwp', - description="firewall_policy", - shared=True, - firewall_rules=[], - audited=True) - firewall_policy = self.deserialize(fmt or self.fmt, res) - firewall_policy_id = firewall_policy["firewall_policy"]["id"] - data = {'firewall': {'name': name, - 'description': description, - 'firewall_policy_id': firewall_policy_id, - 'admin_state_up': admin_state_up, - 'tenant_id': tenant_id}} - if router_ids is not None: - data['firewall']['router_ids'] = router_ids - firewall_req = self.new_create_request('firewalls', data, fmt) - firewall_res = firewall_req.get_response(self.ext_api) - if expected_res_status: - self.assertEqual(expected_res_status, firewall_res.status_int) - return firewall_res - - -class TestFirewallCallbacks(TestFirewallRouterInsertionBase): - - def test_set_firewall_status(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP - ) as fw: - fw_id = fw['firewall']['id'] - res = self.callbacks.set_firewall_status(ctx, fw_id, - nl_constants.ACTIVE) - fw_db = self.plugin.get_firewall(ctx, fw_id) - self.assertEqual(nl_constants.ACTIVE, fw_db['status']) - self.assertTrue(res) - res = self.callbacks.set_firewall_status(ctx, fw_id, - nl_constants.ERROR) - fw_db = self.plugin.get_firewall(ctx, fw_id) - self.assertEqual(nl_constants.ERROR, fw_db['status']) - self.assertFalse(res) - - def test_set_firewall_status_pending_delete(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP - ) as fw: - fw_id = fw['firewall']['id'] - fw_db = self.plugin._get_firewall(ctx, fw_id) - fw_db['status'] = nl_constants.PENDING_DELETE - ctx.session.flush() - res = self.callbacks.set_firewall_status(ctx, fw_id, - nl_constants.ACTIVE) - fw_db = self.plugin.get_firewall(ctx, fw_id) - self.assertEqual(nl_constants.PENDING_DELETE, fw_db['status']) - self.assertFalse(res) - - def test_firewall_deleted(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - do_delete=False) as fw: - fw_id = fw['firewall']['id'] - with ctx.session.begin(subtransactions=True): - fw_db = self.plugin._get_firewall(ctx, fw_id) - fw_db['status'] = nl_constants.PENDING_DELETE - ctx.session.flush() - res = self.callbacks.firewall_deleted(ctx, fw_id) - self.assertTrue(res) - self.assertRaises(f_exc.FirewallNotFound, - self.plugin.get_firewall, - ctx, fw_id) - - def test_firewall_deleted_concurrently(self): - ctx = context.get_admin_context() - alt_ctx = context.get_admin_context() - - _get_firewall = self.plugin._get_firewall - - def getdelete(context, firewall_id): - fw_db = _get_firewall(context, firewall_id) - # NOTE(cby): Use a different session to simulate a concurrent del - self.plugin.delete_db_firewall_object(alt_ctx, firewall_id) - return fw_db - - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - do_delete=False - ) as fw: - fw_id = fw['firewall']['id'] - with ctx.session.begin(subtransactions=True): - fw_db = self.plugin._get_firewall(ctx, fw_id) - fw_db['status'] = nl_constants.PENDING_DELETE - ctx.session.flush() - - with mock.patch.object( - self.plugin, '_get_firewall', side_effect=getdelete - ): - observed = self.callbacks.firewall_deleted(ctx, fw_id) - self.assertTrue(observed) - - self.assertRaises(f_exc.FirewallNotFound, - self.plugin.get_firewall, - ctx, fw_id) - - def test_firewall_deleted_not_found(self): - ctx = context.get_admin_context() - observed = self.callbacks.firewall_deleted(ctx, 'notfound') - self.assertTrue(observed) - - def test_firewall_deleted_error(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - ) as fw: - fw_id = fw['firewall']['id'] - res = self.callbacks.firewall_deleted(ctx, fw_id) - self.assertFalse(res) - fw_db = self.plugin._get_firewall(ctx, fw_id) - self.assertEqual(nl_constants.ERROR, fw_db['status']) - - def test_get_firewall_for_tenant(self): - tenant_id = 'test-tenant' - ctx = context.Context('', tenant_id) - with self.firewall_rule(name='fwr1', tenant_id=tenant_id) as fwr1, \ - self.firewall_rule(name='fwr2', tenant_id=tenant_id) as fwr2, \ - self.firewall_rule(name='fwr3', tenant_id=tenant_id) as fwr3: - with self.firewall_policy(tenant_id=tenant_id) as fwp: - fwp_id = fwp['firewall_policy']['id'] - fr = [fwr1, fwr2, fwr3] - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - res = req.get_response(self.ext_api) - attrs = self._get_test_firewall_attrs() - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - firewall_policy_id=fwp_id, - tenant_id=tenant_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP) as fw: - fw_id = fw['firewall']['id'] - res = self.callbacks.get_firewalls_for_tenant(ctx) - fw_rules = ( - self.plugin._make_firewall_dict_with_rules(ctx, - fw_id) - ) - fw_rules['add-router-ids'] = [] - fw_rules['del-router-ids'] = [] - self.assertEqual(fw_rules, res[0]) - self._compare_firewall_rule_lists( - fwp_id, fr, res[0]['firewall_rule_list']) - - -class TestFirewallAgentApi(base.BaseTestCase): - def setUp(self): - super(TestFirewallAgentApi, self).setUp() - - self.api = fwaas_plugin.FirewallAgentApi('topic', 'host') - - def test_init(self): - self.assertEqual('topic', self.api.client.target.topic) - self.assertEqual('host', self.api.host) - - def _call_test_helper(self, method_name, host): - with mock.patch.object(self.api.client, 'cast') as rpc_mock, \ - mock.patch.object(self.api.client, 'prepare') as prepare_mock: - prepare_mock.return_value = self.api.client - getattr(self.api, method_name)(mock.sentinel.context, 'test', host) - - prepare_args = {'server': host} - prepare_mock.assert_called_once_with(**prepare_args) - - rpc_mock.assert_called_once_with(mock.sentinel.context, method_name, - firewall='test', host='host') - - def test_create_firewall(self): - self._call_test_helper('create_firewall', 'host') - - def test_update_firewall(self): - self._call_test_helper('update_firewall', 'host') - - def test_delete_firewall(self): - self._call_test_helper('delete_firewall', 'host') - - -class TestFirewallPluginBase(TestFirewallRouterInsertionBase, - test_l3_plugin.L3NatTestCaseMixin): - - def setUp(self): - super(TestFirewallPluginBase, self).setUp(fw_plugin=FW_PLUGIN_KLASS) - fake_notifier.reset() - - def test_create_firewall_routers_not_specified(self): - """neutron firewall-create test-policy """ - with self.router(name='router1', admin_state_up=True, - tenant_id=self._tenant_id): - with self.router(name='router2', admin_state_up=True, - tenant_id=self._tenant_id): - with self.firewall() as fw1: - self.assertEqual(nl_constants.PENDING_CREATE, - fw1['firewall']['status']) - - def test_create_firewall_routers_specified(self): - """neutron firewall-create test-policy --router-ids "r1 r2" """ - with self.router(name='router1', admin_state_up=True, - tenant_id=self._tenant_id) as router1: - with self.router(name='router2', admin_state_up=True, - tenant_id=self._tenant_id) as router2: - router_ids = [router1['router']['id'], router2['router']['id']] - with self.firewall(router_ids=router_ids) as fw1: - self.assertEqual(nl_constants.PENDING_CREATE, - fw1['firewall']['status']) - - def test_create_firewall_routers_present_empty_list_specified(self): - """neutron firewall-create test-policy --router-ids "" """ - with self.router(name='router1', admin_state_up=True, - tenant_id=self._tenant_id): - with self.router(name='router2', admin_state_up=True, - tenant_id=self._tenant_id): - router_ids = [] - with self.firewall(router_ids=router_ids) as fw1: - self.assertEqual(nl_constants.INACTIVE, - fw1['firewall']['status']) - - def test_create_firewall_no_routers_empty_list_specified(self): - """neutron firewall-create test-policy --router-ids "" """ - router_ids = [] - with self.firewall(router_ids=router_ids) as fw1: - self.assertEqual(nl_constants.INACTIVE, - fw1['firewall']['status']) - - def test_create_second_firewall_on_same_tenant(self): - """fw1 created with default routers, fw2 no routers on same tenant.""" - with self.router(name='router1', admin_state_up=True, - tenant_id=self._tenant_id): - with self.router(name='router2', admin_state_up=True, - tenant_id=self._tenant_id): - router_ids = [] - with self.firewall() as fw1: - with self.firewall(router_ids=router_ids) as fw2: - self.assertEqual(nl_constants.PENDING_CREATE, - fw1['firewall']['status']) - self.assertEqual(nl_constants.INACTIVE, - fw2['firewall']['status']) - - def test_create_firewall_admin_not_affected_by_other_tenant(self): - # Create fw with admin after creating fw with other tenant - with self.firewall(tenant_id='other-tenant') as fw1: - with self.firewall() as fw2: - self.assertEqual('other-tenant', fw1['firewall']['tenant_id']) - self.assertEqual(self._tenant_id, fw2['firewall']['tenant_id']) - - def test_update_firewall(self): - ctx = context.get_admin_context() - name = "new_firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.router(name='router1', admin_state_up=True, - tenant_id=self._tenant_id) as router1: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - router_ids=[router1['router']['id']] - ) as firewall: - fw_id = firewall['firewall']['id'] - res = self.callbacks.set_firewall_status(ctx, fw_id, - nl_constants.ACTIVE) - data = {'firewall': {'name': name}} - req = self.new_update_request('firewalls', data, fw_id) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs = self._replace_firewall_status(attrs, - nl_constants. - PENDING_CREATE, - nl_constants. - PENDING_UPDATE) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall'][k]) - - def test_update_firewall_fails_when_firewall_pending(self): - name = "new_firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.router(name='router1', admin_state_up=True, - tenant_id=self._tenant_id) as router1: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - router_ids=[router1['router']['id']] - ) as firewall: - fw_id = firewall['firewall']['id'] - data = {'firewall': {'name': name}} - req = self.new_update_request('firewalls', data, fw_id) - res = req.get_response(self.ext_api) - self.assertEqual(exc.HTTPConflict.code, res.status_int) - - def test_update_firewall_with_router_when_firewall_inactive(self): - name = "firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.router(name='router1', admin_state_up=True, - tenant_id=self._tenant_id) as router1: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - name=name, - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - router_ids=[] - ) as firewall: - fw_id = firewall['firewall']['id'] - data = { - 'firewall': {'router_ids': [router1['router']['id']]}} - req = self.new_update_request('firewalls', data, fw_id) - res = self.deserialize(self.fmt, - req.get_response(self.ext_api)) - attrs = self._replace_firewall_status(attrs, - nl_constants. - PENDING_CREATE, - nl_constants. - PENDING_UPDATE) - for k, v in six.iteritems(attrs): - self.assertEqual(v, res['firewall'][k]) - - def test_update_firewall_policy_fails_when_firewall_pending(self): - name = "new_firewall1" - attrs = self._get_test_firewall_attrs(name) - - with self.router(name='router1', admin_state_up=True, - tenant_id=self._tenant_id): - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP - ): - data = {'firewall_policy': {'name': name}} - req = self.new_update_request('firewall_policies', - data, fwp_id) - res = req.get_response(self.ext_api) - self.assertEqual(exc.HTTPConflict.code, res.status_int) - - def test_update_firewall_rule_fails_when_firewall_pending(self): - with self.router(name='router1', admin_state_up=True, - tenant_id=self._tenant_id): - with self.firewall_rule(name='fwr1') as fr: - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - fr_id = fr['firewall_rule']['id'] - fw_rule_ids = [fr_id] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP - ): - data = {'firewall_rule': {'protocol': 'udp'}} - req = self.new_update_request('firewall_rules', - data, fr_id) - res = req.get_response(self.ext_api) - self.assertEqual(exc.HTTPConflict.code, res.status_int) - - def test_delete_firewall_with_no_routers(self): - ctx = context.get_admin_context() - # stop the AgentRPC patch for this one to test pending states - self.agentapi_del_fw_p.stop() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - do_delete=False - ) as fw: - fw_id = fw['firewall']['id'] - req = self.new_delete_request('firewalls', fw_id) - res = req.get_response(self.ext_api) - self.assertEqual(exc.HTTPNoContent.code, res.status_int) - self.assertRaises(f_exc.FirewallNotFound, - self.plugin.get_firewall, - ctx, fw_id) - - def test_delete_firewall_after_agent_delete(self): - ctx = context.get_admin_context() - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id, - do_delete=False) as fw: - fw_id = fw['firewall']['id'] - req = self.new_delete_request('firewalls', fw_id) - res = req.get_response(self.ext_api) - self.assertEqual(exc.HTTPNoContent.code, res.status_int) - self.assertRaises(f_exc.FirewallNotFound, - self.plugin.get_firewall, - ctx, fw_id) - - def test_make_firewall_dict_with_in_place_rules(self): - ctx = context.get_admin_context() - with self.firewall_rule(name='fwr1') as fwr1, \ - self.firewall_rule(name='fwr2') as fwr2, \ - self.firewall_rule(name='fwr3') as fwr3: - with self.firewall_policy() as fwp: - fr = [fwr1, fwr2, fwr3] - fwp_id = fwp['firewall_policy']['id'] - fw_rule_ids = [r['firewall_rule']['id'] for r in fr] - data = {'firewall_policy': - {'firewall_rules': fw_rule_ids}} - req = self.new_update_request('firewall_policies', data, - fwp_id) - req.get_response(self.ext_api) - attrs = self._get_test_firewall_attrs() - attrs['firewall_policy_id'] = fwp_id - with self.firewall( - firewall_policy_id=fwp_id, - admin_state_up=test_db_firewall.ADMIN_STATE_UP, - router_ids=[] - ) as fw: - fw_id = fw['firewall']['id'] - fw_rules = ( - self.plugin._make_firewall_dict_with_rules(ctx, - fw_id) - ) - self.assertEqual(fw_id, fw_rules['id']) - self._compare_firewall_rule_lists( - fwp_id, fr, fw_rules['firewall_rule_list']) - - def test_make_firewall_dict_with_in_place_rules_no_policy(self): - ctx = context.get_admin_context() - with self.firewall() as fw: - fw_id = fw['firewall']['id'] - fw_rules = self.plugin._make_firewall_dict_with_rules(ctx, fw_id) - self.assertEqual([], fw_rules['firewall_rule_list']) - - def test_list_firewalls(self): - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(name='fw1', firewall_policy_id=fwp_id, - description='fw') as fwalls: - self._test_list_resources('firewall', [fwalls], - query_params='description=fw') - - def test_list_firewalls_with_filtering(self): - with self.router(name='my_router', admin_state_up=True, - tenant_id=self._tenant_id) as router: - router_id = router['router']['id'] - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(name='fw1', firewall_policy_id=fwp_id, - description='fw', - router_ids=[router_id]) as fwalls: - filter_pattern = None - fw = fwalls['firewall'] - for filter_pattern in fw: - query_params = 'fields=%s' % filter_pattern - expect = [{filter_pattern: fw[filter_pattern]}] - self._test_list_resources('firewall', expect, - query_params=query_params) - - def test_insert_rule(self): - ctx = context.get_admin_context() - with self.firewall_rule() as fwr: - fr_id = fwr['firewall_rule']['id'] - rule_info = {'firewall_rule_id': fr_id} - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id) as fw: - fw_id = fw['firewall']['id'] - self.plugin.insert_rule(ctx, fwp_id, rule_info) - fw_rules = self.plugin._make_firewall_dict_with_rules( - ctx, fw_id) - self.assertEqual(1, len(fw_rules['firewall_rule_list'])) - self.assertEqual(fr_id, - fw_rules['firewall_rule_list'][0]['id']) - - def test_insert_rule_notif(self): - ctx = context.get_admin_context() - with self.firewall_rule() as fwr: - fr_id = fwr['firewall_rule']['id'] - rule_info = {'firewall_rule_id': fr_id} - with self.firewall_policy() as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id): - self.plugin.insert_rule(ctx, fwp_id, rule_info) - notifications = fake_notifier.NOTIFICATIONS - expected_event_type = 'firewall_policy.update.insert_rule' - event_types = [event['event_type'] for event in notifications] - self.assertIn(expected_event_type, event_types) - - def test_remove_rule(self): - ctx = context.get_admin_context() - with self.firewall_rule() as fwr: - fr_id = fwr['firewall_rule']['id'] - rule_info = {'firewall_rule_id': fr_id} - with self.firewall_policy(firewall_rules=[fr_id]) as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id) as fw: - fw_id = fw['firewall']['id'] - self.plugin.remove_rule(ctx, fwp_id, rule_info) - fw_rules = self.plugin._make_firewall_dict_with_rules( - ctx, fw_id) - self.assertEqual([], fw_rules['firewall_rule_list']) - - def test_remove_rule_notif(self): - ctx = context.get_admin_context() - with self.firewall_rule() as fwr: - fr_id = fwr['firewall_rule']['id'] - rule_info = {'firewall_rule_id': fr_id} - with self.firewall_policy(firewall_rules=[fr_id]) as fwp: - fwp_id = fwp['firewall_policy']['id'] - with self.firewall(firewall_policy_id=fwp_id): - self.plugin.remove_rule(ctx, fwp_id, rule_info) - notifications = fake_notifier.NOTIFICATIONS - expected_event_type = 'firewall_policy.update.remove_rule' - event_types = [event['event_type'] for event in notifications] - self.assertIn(expected_event_type, event_types) - - def test_firewall_quota_lower(self): - """Test quota using overridden value.""" - cfg.CONF.set_override('quota_firewall', 3, group='QUOTAS') - with self.firewall(name='quota1'), \ - self.firewall(name='quota2'), \ - self.firewall(name='quota3'): - data = {'firewall': {'name': 'quota4', - 'firewall_policy_id': None, - 'tenant_id': self._tenant_id}} - req = self.new_create_request('firewalls', data, 'json') - res = req.get_response(self.ext_api) - self.assertIn('Quota exceeded', res.body.decode('utf-8')) - self.assertEqual(exc.HTTPConflict.code, res.status_int) - - def test_firewall_quota_default(self): - """Test quota using default value.""" - with self.firewall(name='quota1'), \ - self.firewall(name='quota2'), \ - self.firewall(name='quota3'), \ - self.firewall(name='quota4'), \ - self.firewall(name='quota5'), \ - self.firewall(name='quota6'), \ - self.firewall(name='quota7'), \ - self.firewall(name='quota8'), \ - self.firewall(name='quota9'), \ - self.firewall(name='quota10'): - data = {'firewall': {'name': 'quota11', - 'firewall_policy_id': None, - 'tenant_id': self._tenant_id}} - req = self.new_create_request('firewalls', data, 'json') - res = req.get_response(self.ext_api) - self.assertIn('Quota exceeded', res.body.decode('utf-8')) - self.assertEqual(exc.HTTPConflict.code, res.status_int) - - -class TestFirewallRouterPluginBase(test_db_firewall.FirewallPluginDbTestCase, - test_l3_plugin.L3NatTestCaseMixin, - test_agent.AgentDBTestMixIn): - - def setUp(self, core_plugin=None, fw_plugin=None, ext_mgr=None): - self.agentapi_del_fw_p = mock.patch(test_db_firewall.DELETEFW_PATH, - create=True, new=test_db_firewall.FakeAgentApi().delete_firewall) - self.agentapi_del_fw_p.start() - - self.client_mock = mock.MagicMock(name="mocked client") - mock.patch('neutron.common.rpc.get_client' - ).start().return_value = self.client_mock - - # the L3 routing with L3 agent scheduling service plugin - l3_plugin = ('neutron.tests.unit.extensions.test_l3.' - 'TestL3NatAgentSchedulingServicePlugin') - - cfg.CONF.set_override('api_extensions_path', extensions_path) - if not fw_plugin: - fw_plugin = FW_PLUGIN_KLASS - service_plugins = {'l3_plugin_name': l3_plugin, - 'fw_plugin_name': fw_plugin} - - fdb.Firewall_db_mixin.\ - supported_extension_aliases = ["fwaas", - "fwaasrouterinsertion"] - fdb.Firewall_db_mixin.path_prefix = fwaas_def.API_PREFIX - - super(test_db_firewall.FirewallPluginDbTestCase, self).setUp( - ext_mgr=ext_mgr, - service_plugins=service_plugins - ) - - if not ext_mgr: - ext_mgr = FirewallTestExtensionManager() - app = config.load_paste_app('extensions_test_app') - self.ext_api = api_ext.ExtensionMiddleware(app, ext_mgr=ext_mgr) - - self.l3_plugin = directory.get_plugin(plugin_constants.L3) - self.plugin = directory.get_plugin('FIREWALL') - - def test_get_firewall_tenant_ids_on_host_with_associated_router(self): - agent = helpers.register_l3_agent("host1") - tenant_id = uuidutils.generate_uuid() - ctxt = context.get_admin_context() - - with self.router(name='router1', admin_state_up=True, - tenant_id=tenant_id) as router1: - router_id = router1['router']['id'] - self.l3_plugin.add_router_to_l3_agent(ctxt, agent.id, - router_id) - with self.firewall(tenant_id=tenant_id, - router_ids=[router_id]): - tenant_ids = self.plugin.get_firewall_tenant_ids_on_host( - ctxt, 'host1') - self.assertEqual([tenant_id], tenant_ids) - - def test_get_firewall_tenant_ids_on_host_without_associated_router(self): - agent1 = helpers.register_l3_agent("host1") - helpers.register_l3_agent("host2") - tenant_id = uuidutils.generate_uuid() - ctxt = context.get_admin_context() - - with self.router(name='router1', admin_state_up=True, - tenant_id=tenant_id) as router1: - router_id = router1['router']['id'] - self.l3_plugin.add_router_to_l3_agent(ctxt, agent1.id, - router_id) - with self.firewall(tenant_id=tenant_id, - router_ids=[router_id]): - tenant_ids = self.plugin.get_firewall_tenant_ids_on_host( - ctxt, 'host_2') - self.assertEqual([], tenant_ids) - - def test_get_firewall_tenant_ids_on_host_with_routers(self): - agent1 = helpers.register_l3_agent("host1") - tenant_id1 = uuidutils.generate_uuid() - tenant_id2 = uuidutils.generate_uuid() - ctxt = context.get_admin_context() - - with self.router(name='router1', admin_state_up=True, - tenant_id=tenant_id1) as router1: - with self.router(name='router2', admin_state_up=True, - tenant_id=tenant_id2) as router2: - router_id1 = router1['router']['id'] - router_id2 = router2['router']['id'] - self.l3_plugin.add_router_to_l3_agent(ctxt, agent1.id, - router_id1) - self.l3_plugin.add_router_to_l3_agent(ctxt, agent1.id, - router_id2) - with self.firewall(tenant_id=tenant_id1, - router_ids=[router_id1]): - with self.firewall(tenant_id=tenant_id2, - router_ids=[router_id2]): - tenant_ids = (self.plugin - .get_firewall_tenant_ids_on_host( - ctxt, 'host1')) - self.assertItemsEqual([tenant_id1, tenant_id2], - tenant_ids) diff --git a/releasenotes/notes/remove_fwaas_v1-15c6e19484f46d1b.yaml b/releasenotes/notes/remove_fwaas_v1-15c6e19484f46d1b.yaml new file mode 100644 index 000000000..f634febcd --- /dev/null +++ b/releasenotes/notes/remove_fwaas_v1-15c6e19484f46d1b.yaml @@ -0,0 +1,7 @@ +--- +prelude: > + - FWaaS V1 is being removed from the neutron-fwaas repo. Because FWaaS V2 + has been available since the Newton release. +upgrade: + - The FWaaS V1 source code will not be available in neutron-fwaas repo from + Stein. FWaaS team will provide a migration script to upgrade. \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 117adc07f..1406c697b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,15 +32,9 @@ setup-hooks = [entry_points] firewall_drivers = - # These are for backwards compat with Juno firewall service provider - # configuration values - neutron.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver = neutron_fwaas.services.firewall.service_drivers.agents.drivers.linux.iptables_fwaas:IptablesFwaasDriver - iptables = neutron_fwaas.services.firewall.service_drivers.agents.drivers.linux.iptables_fwaas:IptablesFwaasDriver iptables_v2 = neutron_fwaas.services.firewall.service_drivers.agents.drivers.linux.iptables_fwaas_v2:IptablesFwaasDriver neutron.service_plugins = - firewall = neutron_fwaas.services.firewall.fwaas_plugin:FirewallPlugin firewall_v2 = neutron_fwaas.services.firewall.fwaas_plugin_v2:FirewallPluginV2 - neutron.services.firewall.fwaas_plugin.FirewallPlugin = neutron_fwaas.services.firewall.fwaas_plugin:FirewallPlugin neutron.db.alembic_migrations = neutron-fwaas = neutron_fwaas.db.migration:alembic_migrations @@ -59,7 +53,6 @@ neutron.agent.l2.firewall_drivers = noop = neutron_fwaas.services.firewall.service_drivers.agents.drivers.linux.l2.noop.noop_driver:NoopFirewallL2Driver ovs = neutron_fwaas.services.firewall.service_drivers.agents.drivers.linux.l2.openvswitch_firewall.firewall:OVSFirewallDriver neutron.agent.l3.extensions = - fwaas = neutron_fwaas.services.firewall.service_drivers.agents.l3reference.firewall_l3_agent:L3WithFWaaS fwaas_v2 = neutron_fwaas.services.firewall.service_drivers.agents.l3reference.firewall_l3_agent_v2:L3WithFWaaS fwaas_v2_log = neutron_fwaas.services.logapi.agents.l3.fwg_log:FWaaSL3LoggingExtension neutron.agent.l3.firewall_drivers =