Support for NVP advanced FwaaS service
The patch adds advanced FWaaS service support for NVP with
VCNS:
* NVP FWaaS is an advanced Service of NVP depending on NVP
advanced service router
- Once an advanced router id created, one corresponding
vshield edge will be deployed, and then we can configure
FW service on the vshield edge
* NVP FWaaS service plugin still uses FWaaS DB service logic,
while finally calling vShield Edge to support FWaaS service
- When firewall object is created, we will attach the
object to the advanced router with routedserviceinsertion_db
service
* on driver part, the driver will first convert the object
to VSM known object input, and then send a synchronous JSON
calling to VSM, and receive the result
Implements: blueprint nvp-fwaas-plugin
Change-Id: Id43af8821f5c553356e3cc870993eef99ef7def3
This commit is contained in:
@@ -0,0 +1,60 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
#
|
||||||
|
# Copyright 2013 OpenStack Foundation
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""nvp fwaas plugin
|
||||||
|
|
||||||
|
Revision ID: 3ed8f075e38a
|
||||||
|
Revises: 338d7508968c
|
||||||
|
Create Date: 2013-09-13 19:14:25.509033
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '3ed8f075e38a'
|
||||||
|
down_revision = '338d7508968c'
|
||||||
|
|
||||||
|
# Change to ['*'] if this migration applies to all plugins
|
||||||
|
|
||||||
|
migration_for_plugins = [
|
||||||
|
'neutron.plugins.nicira.NeutronServicePlugin.NvpAdvancedPlugin'
|
||||||
|
]
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
from neutron.db import migration
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(active_plugins=None, options=None):
|
||||||
|
if not migration.should_run(active_plugins, migration_for_plugins):
|
||||||
|
return
|
||||||
|
|
||||||
|
op.create_table(
|
||||||
|
'vcns_firewall_rule_bindings',
|
||||||
|
sa.Column('rule_id', sa.String(length=36), nullable=False),
|
||||||
|
sa.Column('edge_id', sa.String(length=36), nullable=False),
|
||||||
|
sa.Column('rule_vseid', sa.String(length=36), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['rule_id'], ['firewall_rules.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('rule_id', 'edge_id')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade(active_plugins=None, options=None):
|
||||||
|
if not migration.should_run(active_plugins, migration_for_plugins):
|
||||||
|
return
|
||||||
|
|
||||||
|
op.drop_table('vcns_firewall_rule_bindings')
|
||||||
@@ -65,13 +65,34 @@ class RoutedServiceInsertionDbMixin(object):
|
|||||||
context, resource['resource_id'], model)
|
context, resource['resource_id'], model)
|
||||||
resource[rsi.ROUTER_ID] = binding['router_id']
|
resource[rsi.ROUTER_ID] = binding['router_id']
|
||||||
|
|
||||||
def _get_resource_router_id_binding(self, context, resource_id, model):
|
def _get_resource_router_id_binding(self, context, model,
|
||||||
|
resource_id=None,
|
||||||
|
router_id=None):
|
||||||
query = self._model_query(context, ServiceRouterBinding)
|
query = self._model_query(context, ServiceRouterBinding)
|
||||||
query = query.filter(
|
query = query.filter(
|
||||||
ServiceRouterBinding.resource_id == resource_id,
|
|
||||||
ServiceRouterBinding.resource_type == model.__tablename__)
|
ServiceRouterBinding.resource_type == model.__tablename__)
|
||||||
|
if resource_id:
|
||||||
|
query = query.filter(
|
||||||
|
ServiceRouterBinding.resource_id == resource_id)
|
||||||
|
if router_id:
|
||||||
|
query = query.filter(
|
||||||
|
ServiceRouterBinding.router_id == router_id)
|
||||||
return query.first()
|
return query.first()
|
||||||
|
|
||||||
|
def _get_resource_router_id_bindings(self, context, model,
|
||||||
|
resource_ids=None,
|
||||||
|
router_ids=None):
|
||||||
|
query = self._model_query(context, ServiceRouterBinding)
|
||||||
|
query = query.filter(
|
||||||
|
ServiceRouterBinding.resource_type == model.__tablename__)
|
||||||
|
if resource_ids:
|
||||||
|
query = query.filter(
|
||||||
|
ServiceRouterBinding.resource_id.in_(resource_ids))
|
||||||
|
if router_ids:
|
||||||
|
query = query.filter(
|
||||||
|
ServiceRouterBinding.router_id.in_(router_ids))
|
||||||
|
return query.all()
|
||||||
|
|
||||||
def _make_resource_router_id_dict(self, resource_router_binding, model,
|
def _make_resource_router_id_dict(self, resource_router_binding, model,
|
||||||
fields=None):
|
fields=None):
|
||||||
resource = {'resource_id': resource_router_binding['resource_id'],
|
resource = {'resource_id': resource_router_binding['resource_id'],
|
||||||
@@ -82,6 +103,6 @@ class RoutedServiceInsertionDbMixin(object):
|
|||||||
def _delete_resource_router_id_binding(self, context, resource_id, model):
|
def _delete_resource_router_id_binding(self, context, resource_id, model):
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
binding = self._get_resource_router_id_binding(
|
binding = self._get_resource_router_id_binding(
|
||||||
context, resource_id, model)
|
context, model, resource_id=resource_id)
|
||||||
if binding:
|
if binding:
|
||||||
context.session.delete(binding)
|
context.session.delete(binding)
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ EXTENDED_ATTRIBUTES_2_0 = {
|
|||||||
'validate': {'type:uuid_or_none': None},
|
'validate': {'type:uuid_or_none': None},
|
||||||
'default': None, 'is_visible': True},
|
'default': None, 'is_visible': True},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'firewalls': {
|
||||||
|
ROUTER_ID: {'allow_post': True, 'allow_put': False,
|
||||||
|
'validate': {'type:uuid_or_none': None},
|
||||||
|
'default': None, 'is_visible': True},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
# Copyright 2013 VMware, Inc.
|
# Copyright 2013 VMware, Inc.
|
||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
@@ -18,13 +18,16 @@
|
|||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
from sqlalchemy.orm import exc as sa_exc
|
|
||||||
|
|
||||||
from neutron.common import exceptions as q_exc
|
from neutron.common import exceptions as q_exc
|
||||||
|
from neutron.db.firewall import firewall_db
|
||||||
from neutron.db import l3_db
|
from neutron.db import l3_db
|
||||||
|
from neutron.db import routedserviceinsertion_db as rsi_db
|
||||||
|
from neutron.extensions import firewall as fw_ext
|
||||||
from neutron.openstack.common import log as logging
|
from neutron.openstack.common import log as logging
|
||||||
from neutron.plugins.common import constants as service_constants
|
from neutron.plugins.common import constants as service_constants
|
||||||
from neutron.plugins.nicira.common import config # noqa
|
from neutron.plugins.nicira.common import config # noqa
|
||||||
|
from neutron.plugins.nicira.common import exceptions as nvp_exc
|
||||||
from neutron.plugins.nicira.dbexts import servicerouter as sr_db
|
from neutron.plugins.nicira.dbexts import servicerouter as sr_db
|
||||||
from neutron.plugins.nicira.dbexts import vcns_db
|
from neutron.plugins.nicira.dbexts import vcns_db
|
||||||
from neutron.plugins.nicira.dbexts import vcns_models
|
from neutron.plugins.nicira.dbexts import vcns_models
|
||||||
@@ -38,6 +41,7 @@ from neutron.plugins.nicira.vshield.common.constants import RouterStatus
|
|||||||
from neutron.plugins.nicira.vshield.common import exceptions
|
from neutron.plugins.nicira.vshield.common import exceptions
|
||||||
from neutron.plugins.nicira.vshield.tasks.constants import TaskStatus
|
from neutron.plugins.nicira.vshield.tasks.constants import TaskStatus
|
||||||
from neutron.plugins.nicira.vshield import vcns_driver
|
from neutron.plugins.nicira.vshield import vcns_driver
|
||||||
|
from sqlalchemy.orm import exc as sa_exc
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -66,11 +70,15 @@ ROUTER_STATUS_LEVEL = {
|
|||||||
|
|
||||||
|
|
||||||
class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
||||||
NeutronPlugin.NvpPluginV2):
|
NeutronPlugin.NvpPluginV2,
|
||||||
|
rsi_db.RoutedServiceInsertionDbMixin,
|
||||||
|
firewall_db.Firewall_db_mixin,
|
||||||
|
):
|
||||||
supported_extension_aliases = (
|
supported_extension_aliases = (
|
||||||
NeutronPlugin.NvpPluginV2.supported_extension_aliases + [
|
NeutronPlugin.NvpPluginV2.supported_extension_aliases + [
|
||||||
'service-router'
|
"service-router",
|
||||||
|
"routed-service-insertion",
|
||||||
|
"fwaas"
|
||||||
])
|
])
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -652,7 +660,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
|||||||
router = self._get_router(context, router_id)
|
router = self._get_router(context, router_id)
|
||||||
if router.enable_snat:
|
if router.enable_snat:
|
||||||
self._update_nat_rules(context, router)
|
self._update_nat_rules(context, router)
|
||||||
# TODO(fank): do rollback if error, or have a dedicated thread
|
# TODO(fank): do rollback on error, or have a dedicated thread
|
||||||
# do sync work (rollback, re-configure, or make router down)
|
# do sync work (rollback, re-configure, or make router down)
|
||||||
self._vcns_update_static_routes(context, router=router)
|
self._vcns_update_static_routes(context, router=router)
|
||||||
return info
|
return info
|
||||||
@@ -664,7 +672,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
|||||||
router = self._get_router(context, router_id)
|
router = self._get_router(context, router_id)
|
||||||
if router.enable_snat:
|
if router.enable_snat:
|
||||||
self._update_nat_rules(context, router)
|
self._update_nat_rules(context, router)
|
||||||
# TODO(fank): do rollback if error, or have a dedicated thread
|
# TODO(fank): do rollback on error, or have a dedicated thread
|
||||||
# do sync work (rollback, re-configure, or make router down)
|
# do sync work (rollback, re-configure, or make router down)
|
||||||
self._vcns_update_static_routes(context, router=router)
|
self._vcns_update_static_routes(context, router=router)
|
||||||
return info
|
return info
|
||||||
@@ -675,7 +683,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
|||||||
router_id = fip.get('router_id')
|
router_id = fip.get('router_id')
|
||||||
if router_id and self._is_advanced_service_router(context, router_id):
|
if router_id and self._is_advanced_service_router(context, router_id):
|
||||||
router = self._get_router(context, router_id)
|
router = self._get_router(context, router_id)
|
||||||
# TODO(fank): do rollback if error, or have a dedicated thread
|
# TODO(fank): do rollback on error, or have a dedicated thread
|
||||||
# do sync work (rollback, re-configure, or make router down)
|
# do sync work (rollback, re-configure, or make router down)
|
||||||
self._update_interface(context, router)
|
self._update_interface(context, router)
|
||||||
self._update_nat_rules(context, router)
|
self._update_nat_rules(context, router)
|
||||||
@@ -687,7 +695,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
|||||||
router_id = fip.get('router_id')
|
router_id = fip.get('router_id')
|
||||||
if router_id and self._is_advanced_service_router(context, router_id):
|
if router_id and self._is_advanced_service_router(context, router_id):
|
||||||
router = self._get_router(context, router_id)
|
router = self._get_router(context, router_id)
|
||||||
# TODO(fank): do rollback if error, or have a dedicated thread
|
# TODO(fank): do rollback on error, or have a dedicated thread
|
||||||
# do sync work (rollback, re-configure, or make router down)
|
# do sync work (rollback, re-configure, or make router down)
|
||||||
self._update_interface(context, router)
|
self._update_interface(context, router)
|
||||||
self._update_nat_rules(context, router)
|
self._update_nat_rules(context, router)
|
||||||
@@ -701,7 +709,7 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
|||||||
super(NvpAdvancedPlugin, self).delete_floatingip(context, id)
|
super(NvpAdvancedPlugin, self).delete_floatingip(context, id)
|
||||||
if router_id and self._is_advanced_service_router(context, router_id):
|
if router_id and self._is_advanced_service_router(context, router_id):
|
||||||
router = self._get_router(context, router_id)
|
router = self._get_router(context, router_id)
|
||||||
# TODO(fank): do rollback if error, or have a dedicated thread
|
# TODO(fank): do rollback on error, or have a dedicated thread
|
||||||
# do sync work (rollback, re-configure, or make router down)
|
# do sync work (rollback, re-configure, or make router down)
|
||||||
self._update_interface(context, router)
|
self._update_interface(context, router)
|
||||||
self._update_nat_rules(context, router)
|
self._update_nat_rules(context, router)
|
||||||
@@ -717,16 +725,291 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin,
|
|||||||
port_id)
|
port_id)
|
||||||
if router_id and self._is_advanced_service_router(context, router_id):
|
if router_id and self._is_advanced_service_router(context, router_id):
|
||||||
router = self._get_router(context, router_id)
|
router = self._get_router(context, router_id)
|
||||||
# TODO(fank): do rollback if error, or have a dedicated thread
|
# TODO(fank): do rollback on error, or have a dedicated thread
|
||||||
# do sync work (rollback, re-configure, or make router down)
|
# do sync work (rollback, re-configure, or make router down)
|
||||||
self._update_interface(context, router)
|
self._update_interface(context, router)
|
||||||
self._update_nat_rules(context, router)
|
self._update_nat_rules(context, router)
|
||||||
|
|
||||||
|
#
|
||||||
|
# FWaaS plugin implementation
|
||||||
|
#
|
||||||
|
def _firewall_set_status(
|
||||||
|
self, context, firewall_id, status, firewall=None):
|
||||||
|
with context.session.begin(subtransactions=True):
|
||||||
|
fw_db = self._get_firewall(context, firewall_id)
|
||||||
|
if status == service_constants.PENDING_UPDATE and (
|
||||||
|
fw_db.status == service_constants.PENDING_DELETE):
|
||||||
|
raise fw_ext.FirewallInPendingState(
|
||||||
|
firewall_id=firewall_id, pending_state=status)
|
||||||
|
else:
|
||||||
|
fw_db.status = status
|
||||||
|
if firewall:
|
||||||
|
firewall['status'] = status
|
||||||
|
|
||||||
|
def _ensure_firewall_update_allowed(self, context, firewall_id):
|
||||||
|
fwall = self.get_firewall(context, firewall_id)
|
||||||
|
if fwall['status'] in [service_constants.PENDING_CREATE,
|
||||||
|
service_constants.PENDING_UPDATE,
|
||||||
|
service_constants.PENDING_DELETE]:
|
||||||
|
raise fw_ext.FirewallInPendingState(firewall_id=firewall_id,
|
||||||
|
pending_state=fwall['status'])
|
||||||
|
|
||||||
|
def _ensure_firewall_policy_update_allowed(
|
||||||
|
self, context, firewall_policy_id):
|
||||||
|
firewall_policy = self.get_firewall_policy(context, firewall_policy_id)
|
||||||
|
for firewall_id in firewall_policy.get('firewall_list', []):
|
||||||
|
self._ensure_firewall_update_allowed(context, firewall_id)
|
||||||
|
|
||||||
|
def _ensure_update_or_delete_firewall_rule(
|
||||||
|
self, context, firewall_rule_id):
|
||||||
|
fw_rule = self.get_firewall_rule(context, firewall_rule_id)
|
||||||
|
if fw_rule.get('firewall_policy_id'):
|
||||||
|
self._ensure_firewall_policy_update_allowed(
|
||||||
|
context, fw_rule['firewall_policy_id'])
|
||||||
|
|
||||||
|
def _make_firewall_rule_list_by_policy_id(self, context, fw_policy_id):
|
||||||
|
if not fw_policy_id:
|
||||||
|
return None
|
||||||
|
firewall_policy_db = self._get_firewall_policy(context, fw_policy_id)
|
||||||
|
return [
|
||||||
|
self._make_firewall_rule_dict(fw_rule_db)
|
||||||
|
for fw_rule_db in firewall_policy_db['firewall_rules']
|
||||||
|
]
|
||||||
|
|
||||||
|
def _get_edge_id_by_vcns_edge_binding(self, context,
|
||||||
|
router_id):
|
||||||
|
#Get vcns_router_binding mapping between router and edge
|
||||||
|
router_binding = vcns_db.get_vcns_router_binding(
|
||||||
|
context.session, router_id)
|
||||||
|
return router_binding.edge_id
|
||||||
|
|
||||||
|
def _get_firewall_list_from_firewall_policy(self, context, policy_id):
|
||||||
|
firewall_policy_db = self._get_firewall_policy(context, policy_id)
|
||||||
|
return [
|
||||||
|
self._make_firewall_dict(fw_db)
|
||||||
|
for fw_db in firewall_policy_db['firewalls']
|
||||||
|
]
|
||||||
|
|
||||||
|
def _get_firewall_list_from_firewall_rule(self, context, rule_id):
|
||||||
|
rule = self._get_firewall_rule(context, rule_id)
|
||||||
|
if not rule.firewall_policy_id:
|
||||||
|
# The firewall rule is not associated with firewall policy yet
|
||||||
|
return None
|
||||||
|
|
||||||
|
return self._get_firewall_list_from_firewall_policy(
|
||||||
|
context, rule.firewall_policy_id)
|
||||||
|
|
||||||
|
def _vcns_update_firewall(self, context, fw, router_id=None, **kwargs):
|
||||||
|
edge_id = kwargs.get('edge_id')
|
||||||
|
if not edge_id:
|
||||||
|
edge_id = self._get_edge_id_by_vcns_edge_binding(
|
||||||
|
context, router_id)
|
||||||
|
firewall_rule_list = kwargs.get('firewall_rule_list')
|
||||||
|
if not firewall_rule_list:
|
||||||
|
firewall_rule_list = self._make_firewall_rule_list_by_policy_id(
|
||||||
|
context, fw['firewall_policy_id'])
|
||||||
|
fw_with_rules = fw
|
||||||
|
fw_with_rules['firewall_rule_list'] = firewall_rule_list
|
||||||
|
try:
|
||||||
|
self.vcns_driver.update_firewall(context, edge_id, fw_with_rules)
|
||||||
|
except exceptions.VcnsApiException as e:
|
||||||
|
self._firewall_set_status(
|
||||||
|
context, fw['id'], service_constants.ERROR)
|
||||||
|
msg = (_("Failed to create firewall on vShield Edge "
|
||||||
|
"bound on router %s") % router_id)
|
||||||
|
LOG.exception(msg)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
except exceptions.BadRequest as e:
|
||||||
|
self._firewall_set_status(
|
||||||
|
context, fw['id'], service_constants.ERROR)
|
||||||
|
LOG.exception(_("Bad Firewall request Input"))
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def _vcns_delete_firewall(self, context, router_id=None, **kwargs):
|
||||||
|
edge_id = kwargs.get('edge_id')
|
||||||
|
if not edge_id:
|
||||||
|
edge_id = self._get_edge_id_by_vcns_edge_binding(
|
||||||
|
context, router_id)
|
||||||
|
#TODO(linb):do rollback on error
|
||||||
|
self.vcns_driver.delete_firewall(context, edge_id)
|
||||||
|
|
||||||
|
def create_firewall(self, context, firewall):
|
||||||
|
LOG.debug(_("create_firewall() called"))
|
||||||
|
router_id = firewall['firewall'].get(vcns_const.ROUTER_ID)
|
||||||
|
if not router_id:
|
||||||
|
msg = _("router_id is not provided!")
|
||||||
|
LOG.error(msg)
|
||||||
|
raise q_exc.BadRequest(resource='router', msg=msg)
|
||||||
|
if not self._is_advanced_service_router(context, router_id):
|
||||||
|
msg = _("router_id:%s is not an advanced router!") % router_id
|
||||||
|
LOG.error(msg)
|
||||||
|
raise q_exc.BadRequest(resource='router', msg=msg)
|
||||||
|
if self._get_resource_router_id_binding(
|
||||||
|
context, firewall_db.Firewall, router_id=router_id):
|
||||||
|
msg = _("A firewall is already associated with the router")
|
||||||
|
LOG.error(msg)
|
||||||
|
raise nvp_exc.NvpServiceOverQuota(
|
||||||
|
overs='firewall', err_msg=msg)
|
||||||
|
|
||||||
|
fw = super(NvpAdvancedPlugin, self).create_firewall(context, firewall)
|
||||||
|
#Add router service insertion binding with firewall object
|
||||||
|
res = {
|
||||||
|
'id': fw['id'],
|
||||||
|
'router_id': router_id
|
||||||
|
}
|
||||||
|
self._process_create_resource_router_id(
|
||||||
|
context, res, firewall_db.Firewall)
|
||||||
|
#Since there is only one firewall per edge,
|
||||||
|
#here would be bulk configureation operation on firewall
|
||||||
|
self._vcns_update_firewall(context, fw, router_id)
|
||||||
|
self._firewall_set_status(
|
||||||
|
context, fw['id'], service_constants.ACTIVE, fw)
|
||||||
|
return fw
|
||||||
|
|
||||||
|
def update_firewall(self, context, id, firewall):
|
||||||
|
LOG.debug(_("update_firewall() called"))
|
||||||
|
self._ensure_firewall_update_allowed(context, id)
|
||||||
|
rule_list_pre = self._make_firewall_rule_list_by_policy_id(
|
||||||
|
context,
|
||||||
|
self.get_firewall(context, id)['firewall_policy_id'])
|
||||||
|
firewall['firewall']['status'] = service_constants.PENDING_UPDATE
|
||||||
|
fw = super(NvpAdvancedPlugin, self).update_firewall(
|
||||||
|
context, id, firewall)
|
||||||
|
rule_list_new = self._make_firewall_rule_list_by_policy_id(
|
||||||
|
context, fw['firewall_policy_id'])
|
||||||
|
if rule_list_pre == rule_list_new:
|
||||||
|
self._firewall_set_status(
|
||||||
|
context, fw['id'], service_constants.ACTIVE, fw)
|
||||||
|
return fw
|
||||||
|
else:
|
||||||
|
service_router_binding = self._get_resource_router_id_binding(
|
||||||
|
context, firewall_db.Firewall, resource_id=id)
|
||||||
|
self._vcns_update_firewall(
|
||||||
|
context, fw, service_router_binding.router_id)
|
||||||
|
self._firewall_set_status(
|
||||||
|
context, fw['id'], service_constants.ACTIVE, fw)
|
||||||
|
return fw
|
||||||
|
|
||||||
|
def delete_firewall(self, context, id):
|
||||||
|
LOG.debug(_("delete_firewall() called"))
|
||||||
|
self._firewall_set_status(
|
||||||
|
context, id, service_constants.PENDING_DELETE)
|
||||||
|
service_router_binding = self._get_resource_router_id_binding(
|
||||||
|
context, firewall_db.Firewall, resource_id=id)
|
||||||
|
self._vcns_delete_firewall(context, service_router_binding.router_id)
|
||||||
|
super(NvpAdvancedPlugin, self).delete_firewall(context, id)
|
||||||
|
self._delete_resource_router_id_binding(
|
||||||
|
context, id, firewall_db.Firewall)
|
||||||
|
|
||||||
|
def update_firewall_rule(self, context, id, firewall_rule):
|
||||||
|
LOG.debug(_("update_firewall_rule() called"))
|
||||||
|
self._ensure_update_or_delete_firewall_rule(context, id)
|
||||||
|
fwr_pre = self.get_firewall_rule(context, id)
|
||||||
|
fwr = super(NvpAdvancedPlugin, self).update_firewall_rule(
|
||||||
|
context, id, firewall_rule)
|
||||||
|
if fwr_pre == fwr:
|
||||||
|
return fwr
|
||||||
|
|
||||||
|
# check if this rule is associated with firewall
|
||||||
|
fw_list = self._get_firewall_list_from_firewall_rule(context, id)
|
||||||
|
if not fw_list:
|
||||||
|
return fwr
|
||||||
|
|
||||||
|
for fw in fw_list:
|
||||||
|
# get router service insertion binding with firewall id
|
||||||
|
service_router_binding = self._get_resource_router_id_binding(
|
||||||
|
context, firewall_db.Firewall, resource_id=fw['id'])
|
||||||
|
edge_id = self._get_edge_id_by_vcns_edge_binding(
|
||||||
|
context, service_router_binding.router_id)
|
||||||
|
|
||||||
|
#TODO(linb): do rollback on error
|
||||||
|
self.vcns_driver.update_firewall_rule(context, id, edge_id, fwr)
|
||||||
|
|
||||||
|
return fwr
|
||||||
|
|
||||||
|
def update_firewall_policy(self, context, id, firewall_policy):
|
||||||
|
LOG.debug(_("update_firewall_policy() called"))
|
||||||
|
self._ensure_firewall_policy_update_allowed(context, id)
|
||||||
|
firewall_rules_pre = self._make_firewall_rule_list_by_policy_id(
|
||||||
|
context, id)
|
||||||
|
fwp = super(NvpAdvancedPlugin, self).update_firewall_policy(
|
||||||
|
context, id, firewall_policy)
|
||||||
|
firewall_rules = self._make_firewall_rule_list_by_policy_id(
|
||||||
|
context, id)
|
||||||
|
if firewall_rules_pre == firewall_rules:
|
||||||
|
return fwp
|
||||||
|
|
||||||
|
# check if this policy is associated with firewall
|
||||||
|
fw_list = self._get_firewall_list_from_firewall_policy(context, id)
|
||||||
|
if not fw_list:
|
||||||
|
return fwp
|
||||||
|
|
||||||
|
for fw in fw_list:
|
||||||
|
# Get the router_service insertion binding with firewall id
|
||||||
|
# TODO(fank): optimized by using _get_resource_router_id_bindings
|
||||||
|
service_router_binding = self._get_resource_router_id_binding(
|
||||||
|
context, firewall_db.Firewall, resource_id=fw['id'])
|
||||||
|
self._vcns_update_firewall(
|
||||||
|
context, fw, service_router_binding.router_id)
|
||||||
|
return fwp
|
||||||
|
|
||||||
|
def insert_rule(self, context, id, rule_info):
|
||||||
|
LOG.debug(_("insert_rule() called"))
|
||||||
|
self._ensure_firewall_policy_update_allowed(context, id)
|
||||||
|
fwp = super(NvpAdvancedPlugin, self).insert_rule(
|
||||||
|
context, id, rule_info)
|
||||||
|
fwr = super(NvpAdvancedPlugin, self).get_firewall_rule(
|
||||||
|
context, rule_info['firewall_rule_id'])
|
||||||
|
|
||||||
|
# check if this policy is associated with firewall
|
||||||
|
fw_list = self._get_firewall_list_from_firewall_policy(context, id)
|
||||||
|
if not fw_list:
|
||||||
|
return fwp
|
||||||
|
for fw in fw_list:
|
||||||
|
# TODO(fank): optimized by using _get_resource_router_id_bindings
|
||||||
|
service_router_binding = self._get_resource_router_id_binding(
|
||||||
|
context, firewall_db.Firewall, resource_id=fw['id'])
|
||||||
|
edge_id = self._get_edge_id_by_vcns_edge_binding(
|
||||||
|
context, service_router_binding.router_id)
|
||||||
|
|
||||||
|
if rule_info.get('insert_before') or rule_info.get('insert_after'):
|
||||||
|
#if insert_before or insert_after is set, we would call
|
||||||
|
#VCNS insert_rule API
|
||||||
|
#TODO(linb): do rollback on error
|
||||||
|
self.vcns_driver.insert_rule(context, rule_info, edge_id, fwr)
|
||||||
|
else:
|
||||||
|
#Else we would call bulk configuration on the firewall
|
||||||
|
self._vcns_update_firewall(context, fw, edge_id=edge_id)
|
||||||
|
return fwp
|
||||||
|
|
||||||
|
def remove_rule(self, context, id, rule_info):
|
||||||
|
LOG.debug(_("remove_rule() called"))
|
||||||
|
self._ensure_firewall_policy_update_allowed(context, id)
|
||||||
|
fwp = super(NvpAdvancedPlugin, self).remove_rule(
|
||||||
|
context, id, rule_info)
|
||||||
|
fwr = super(NvpAdvancedPlugin, self).get_firewall_rule(
|
||||||
|
context, rule_info['firewall_rule_id'])
|
||||||
|
|
||||||
|
# check if this policy is associated with firewall
|
||||||
|
fw_list = self._get_firewall_list_from_firewall_policy(context, id)
|
||||||
|
if not fw_list:
|
||||||
|
return fwp
|
||||||
|
for fw in fw_list:
|
||||||
|
# TODO(fank): optimized by using _get_resource_router_id_bindings
|
||||||
|
service_router_binding = self._get_resource_router_id_binding(
|
||||||
|
context, firewall_db.Firewall, resource_id=fw['id'])
|
||||||
|
edge_id = self._get_edge_id_by_vcns_edge_binding(
|
||||||
|
context, service_router_binding.router_id)
|
||||||
|
#TODO(linb): do rollback on error
|
||||||
|
self.vcns_driver.delete_firewall_rule(
|
||||||
|
context, fwr['id'], edge_id)
|
||||||
|
return fwp
|
||||||
|
|
||||||
|
|
||||||
class VcnsCallbacks(object):
|
class VcnsCallbacks(object):
|
||||||
"""Edge callback implementation
|
"""Edge callback implementation Callback functions for
|
||||||
|
asynchronous tasks.
|
||||||
Callback functions for asynchronous tasks
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, plugin):
|
def __init__(self, plugin):
|
||||||
self.plugin = plugin
|
self.plugin = plugin
|
||||||
|
|||||||
@@ -62,3 +62,17 @@ class MaintenanceInProgress(NvpPluginException):
|
|||||||
message = _("The networking backend is currently in maintenance mode and "
|
message = _("The networking backend is currently in maintenance mode and "
|
||||||
"therefore unable to accept requests which modify its state. "
|
"therefore unable to accept requests which modify its state. "
|
||||||
"Please try later.")
|
"Please try later.")
|
||||||
|
|
||||||
|
|
||||||
|
class NvpServicePluginException(q_exc.NeutronException):
|
||||||
|
"""NVP Service Plugin exceptions."""
|
||||||
|
message = _("An unexpected error happened "
|
||||||
|
"in the NVP Service Plugin:%(err_msg)s")
|
||||||
|
|
||||||
|
|
||||||
|
class NvpServiceOverQuota(q_exc.Conflict):
|
||||||
|
message = _("Quota exceeded for Vcns resource: %(overs)s: %(err_msg)s")
|
||||||
|
|
||||||
|
|
||||||
|
class NvpVcnsDriverException(NvpServicePluginException):
|
||||||
|
message = _("Error happened in NVP VCNS Driver: %(err_msg)s")
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from sqlalchemy.orm import exc
|
||||||
|
|
||||||
|
from neutron.plugins.nicira.common import exceptions as nvp_exc
|
||||||
from neutron.plugins.nicira.dbexts import vcns_models
|
from neutron.plugins.nicira.dbexts import vcns_models
|
||||||
|
|
||||||
|
|
||||||
@@ -48,3 +51,47 @@ def delete_vcns_router_binding(session, router_id):
|
|||||||
binding = (session.query(vcns_models.VcnsRouterBinding).
|
binding = (session.query(vcns_models.VcnsRouterBinding).
|
||||||
filter_by(router_id=router_id).one())
|
filter_by(router_id=router_id).one())
|
||||||
session.delete(binding)
|
session.delete(binding)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Edge Firewall binding methods
|
||||||
|
def add_vcns_edge_firewallrule_binding(session, map_info):
|
||||||
|
with session.begin(subtransactions=True):
|
||||||
|
binding = vcns_models.VcnsEdgeFirewallRuleBinding(
|
||||||
|
rule_id=map_info['rule_id'],
|
||||||
|
rule_vseid=map_info['rule_vseid'],
|
||||||
|
edge_id=map_info['edge_id'])
|
||||||
|
session.add(binding)
|
||||||
|
return binding
|
||||||
|
|
||||||
|
|
||||||
|
def delete_vcns_edge_firewallrule_binding(session, id):
|
||||||
|
with session.begin(subtransactions=True):
|
||||||
|
if not (session.query(vcns_models.VcnsEdgeFirewallRuleBinding).
|
||||||
|
filter_by(rule_id=id).delete()):
|
||||||
|
msg = _("Rule Resource binding with id:%s not found!") % id
|
||||||
|
raise nvp_exc.NvpServicePluginException(err_msg=msg)
|
||||||
|
|
||||||
|
|
||||||
|
def get_vcns_edge_firewallrule_binding(session, id, edge_id):
|
||||||
|
with session.begin(subtransactions=True):
|
||||||
|
return (session.query(vcns_models.VcnsEdgeFirewallRuleBinding).
|
||||||
|
filter_by(rule_id=id, edge_id=edge_id).first())
|
||||||
|
|
||||||
|
|
||||||
|
def get_vcns_edge_firewallrule_binding_by_vseid(
|
||||||
|
session, edge_id, rule_vseid):
|
||||||
|
with session.begin(subtransactions=True):
|
||||||
|
try:
|
||||||
|
return (session.query(vcns_models.VcnsEdgeFirewallRuleBinding).
|
||||||
|
filter_by(edge_id=edge_id, rule_vseid=rule_vseid).one())
|
||||||
|
except exc.NoResultFound:
|
||||||
|
msg = _("Rule Resource binding not found!")
|
||||||
|
raise nvp_exc.NvpServicePluginException(err_msg=msg)
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup_vcns_edge_firewallrule_binding(session, edge_id):
|
||||||
|
with session.begin(subtransactions=True):
|
||||||
|
session.query(
|
||||||
|
vcns_models.VcnsEdgeFirewallRuleBinding).filter_by(
|
||||||
|
edge_id=edge_id).delete()
|
||||||
|
|||||||
@@ -36,3 +36,18 @@ class VcnsRouterBinding(model_base.BASEV2, models_v2.HasStatusDescription):
|
|||||||
nullable=True)
|
nullable=True)
|
||||||
lswitch_id = sa.Column(sa.String(36),
|
lswitch_id = sa.Column(sa.String(36),
|
||||||
nullable=False)
|
nullable=False)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# VCNS Edge FW mapping tables
|
||||||
|
#
|
||||||
|
class VcnsEdgeFirewallRuleBinding(model_base.BASEV2):
|
||||||
|
"""1:1 mapping between firewall rule and edge firewall rule_id."""
|
||||||
|
|
||||||
|
__tablename__ = 'vcns_firewall_rule_bindings'
|
||||||
|
|
||||||
|
rule_id = sa.Column(sa.String(36),
|
||||||
|
sa.ForeignKey("firewall_rules.id"),
|
||||||
|
primary_key=True)
|
||||||
|
edge_id = sa.Column(sa.String(36), primary_key=True)
|
||||||
|
rule_vseid = sa.Column(sa.String(36))
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
# Copyright 2013 VMware, Inc.
|
# Copyright 2013 VMware, Inc,
|
||||||
# All Rights Reserved
|
# All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
|||||||
@@ -29,6 +29,14 @@ class VcnsGeneralException(VcnsException):
|
|||||||
super(VcnsGeneralException, self).__init__()
|
super(VcnsGeneralException, self).__init__()
|
||||||
|
|
||||||
|
|
||||||
|
class VcnsBadRequest(exceptions.BadRequest):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class VcnsNotFound(exceptions.NotFound):
|
||||||
|
message = _('%(resource)s not found: %(msg)s')
|
||||||
|
|
||||||
|
|
||||||
class VcnsApiException(VcnsException):
|
class VcnsApiException(VcnsException):
|
||||||
message = _("An unknown exception %(status)s occurred: %(response)s.")
|
message = _("An unknown exception %(status)s occurred: %(response)s.")
|
||||||
|
|
||||||
|
|||||||
354
neutron/plugins/nicira/vshield/edge_firewall_driver.py
Normal file
354
neutron/plugins/nicira/vshield/edge_firewall_driver.py
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
#
|
||||||
|
# Copyright 2013 VMware, Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
# @author: Leon Cui, VMware
|
||||||
|
|
||||||
|
from neutron.db import db_base_plugin_v2
|
||||||
|
from neutron.openstack.common import excutils
|
||||||
|
from neutron.openstack.common import log as logging
|
||||||
|
from neutron.plugins.common import constants
|
||||||
|
from neutron.plugins.nicira.dbexts import vcns_db
|
||||||
|
from neutron.plugins.nicira.vshield.common import (
|
||||||
|
exceptions as vcns_exc)
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
VSE_FWAAS_ALLOW = "accept"
|
||||||
|
VSE_FWAAS_DENY = "deny"
|
||||||
|
|
||||||
|
|
||||||
|
class EdgeFirewallDriver(db_base_plugin_v2.NeutronDbPluginV2):
|
||||||
|
"""Implementation of driver APIs for
|
||||||
|
Edge Firewall feature configuration
|
||||||
|
"""
|
||||||
|
def _convert_firewall_action(self, action):
|
||||||
|
if action == constants.FWAAS_ALLOW:
|
||||||
|
return VSE_FWAAS_ALLOW
|
||||||
|
elif action == constants.FWAAS_DENY:
|
||||||
|
return VSE_FWAAS_DENY
|
||||||
|
else:
|
||||||
|
msg = _("Invalid action value %s in a firewall rule") % action
|
||||||
|
raise vcns_exc.BadRequest(resource='firewall_rule', msg=msg)
|
||||||
|
|
||||||
|
def _restore_firewall_action(self, action):
|
||||||
|
if action == VSE_FWAAS_ALLOW:
|
||||||
|
return constants.FWAAS_ALLOW
|
||||||
|
elif action == VSE_FWAAS_DENY:
|
||||||
|
return constants.FWAAS_DENY
|
||||||
|
else:
|
||||||
|
msg = (_("Invalid action value %s in "
|
||||||
|
"a vshield firewall rule") % action)
|
||||||
|
raise vcns_exc.BadRequest(resource='firewall_rule', msg=msg)
|
||||||
|
|
||||||
|
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)
|
||||||
|
else:
|
||||||
|
return '%d:%d' % (min_port, max_port)
|
||||||
|
|
||||||
|
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
|
||||||
|
return [int(min_port), int(max_port)]
|
||||||
|
|
||||||
|
def _convert_firewall_rule(self, context, rule, index=None):
|
||||||
|
vcns_rule = {
|
||||||
|
"name": rule['name'],
|
||||||
|
"description": rule['description'],
|
||||||
|
"action": self._convert_firewall_action(rule['action']),
|
||||||
|
"enabled": rule['enabled']}
|
||||||
|
if rule.get('source_ip_address'):
|
||||||
|
vcns_rule['source'] = {
|
||||||
|
"ipAddress": [rule['source_ip_address']]
|
||||||
|
}
|
||||||
|
if rule.get('destination_ip_address'):
|
||||||
|
vcns_rule['destination'] = {
|
||||||
|
"ipAddress": [rule['destination_ip_address']]
|
||||||
|
}
|
||||||
|
service = {}
|
||||||
|
if rule.get('source_port'):
|
||||||
|
min_port, max_port = self._get_min_max_ports_from_range(
|
||||||
|
rule['source_port'])
|
||||||
|
service['sourcePort'] = [i for i in range(min_port, max_port + 1)]
|
||||||
|
if rule.get('destination_port'):
|
||||||
|
min_port, max_port = self._get_min_max_ports_from_range(
|
||||||
|
rule['destination_port'])
|
||||||
|
service['port'] = [i for i in range(min_port, max_port + 1)]
|
||||||
|
if rule.get('protocol'):
|
||||||
|
service['protocol'] = rule['protocol']
|
||||||
|
if service:
|
||||||
|
vcns_rule['application'] = {
|
||||||
|
'service': [service]
|
||||||
|
}
|
||||||
|
if index:
|
||||||
|
vcns_rule['ruleTag'] = index
|
||||||
|
return vcns_rule
|
||||||
|
|
||||||
|
def _restore_firewall_rule(self, context, edge_id, response):
|
||||||
|
rule = response
|
||||||
|
rule_binding = vcns_db.get_vcns_edge_firewallrule_binding_by_vseid(
|
||||||
|
context.session, edge_id, rule['ruleId'])
|
||||||
|
service = rule['application']['service'][0]
|
||||||
|
src_port_range = self._get_port_range_from_min_max_ports(
|
||||||
|
service['sourcePort'][0], service['sourcePort'][-1])
|
||||||
|
dst_port_range = self._get_port_range_from_min_max_ports(
|
||||||
|
service['port'][0], service['port'][-1])
|
||||||
|
return {
|
||||||
|
'firewall_rule': {
|
||||||
|
'name': rule['name'],
|
||||||
|
'id': rule_binding['rule_id'],
|
||||||
|
'description': rule['description'],
|
||||||
|
'source_ip_address': rule['source']['ipAddress'][0],
|
||||||
|
'destination_ip_address': rule['destination']['ipAddress'][0],
|
||||||
|
'protocol': service['protocol'],
|
||||||
|
'destination_port': dst_port_range,
|
||||||
|
'source_port': src_port_range,
|
||||||
|
'action': self._restore_firewall_action(rule['action']),
|
||||||
|
'enabled': rule['enabled']}}
|
||||||
|
|
||||||
|
def _convert_firewall(self, context, firewall):
|
||||||
|
#bulk configuration on firewall and rescheduling the rule binding
|
||||||
|
ruleTag = 1
|
||||||
|
vcns_rules = []
|
||||||
|
for rule in firewall['firewall_rule_list']:
|
||||||
|
vcns_rule = self._convert_firewall_rule(context, rule, ruleTag)
|
||||||
|
vcns_rules.append(vcns_rule)
|
||||||
|
ruleTag += 1
|
||||||
|
return {
|
||||||
|
'featureType': "firewall_4.0",
|
||||||
|
'firewallRules': {
|
||||||
|
'firewallRules': vcns_rules}}
|
||||||
|
|
||||||
|
def _restore_firewall(self, context, edge_id, response):
|
||||||
|
res = {}
|
||||||
|
res['firewall_rule_list'] = []
|
||||||
|
for rule in response['firewallRules']['firewallRules']:
|
||||||
|
rule_binding = (
|
||||||
|
vcns_db.get_vcns_edge_firewallrule_binding_by_vseid(
|
||||||
|
context.session, edge_id, rule['ruleId']))
|
||||||
|
if rule_binding is None:
|
||||||
|
continue
|
||||||
|
service = rule['application']['service'][0]
|
||||||
|
src_port_range = self._get_port_range_from_min_max_ports(
|
||||||
|
service['sourcePort'][0], service['sourcePort'][-1])
|
||||||
|
dst_port_range = self._get_port_range_from_min_max_ports(
|
||||||
|
service['port'][0], service['port'][-1])
|
||||||
|
item = {
|
||||||
|
'firewall_rule': {
|
||||||
|
'name': rule['name'],
|
||||||
|
'id': rule_binding['rule_id'],
|
||||||
|
'description': rule['description'],
|
||||||
|
'source_ip_address': rule['source']['ipAddress'][0],
|
||||||
|
'destination_ip_address': rule[
|
||||||
|
'destination']['ipAddress'][0],
|
||||||
|
'protocol': service['protocol'],
|
||||||
|
'destination_port': dst_port_range,
|
||||||
|
'source_port': src_port_range,
|
||||||
|
'action': self._restore_firewall_action(rule['action']),
|
||||||
|
'enabled': rule['enabled']}}
|
||||||
|
res['firewall_rule_list'].append(item)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _create_rule_id_mapping(
|
||||||
|
self, context, edge_id, firewall, vcns_fw):
|
||||||
|
for rule in vcns_fw['firewallRules']['firewallRules']:
|
||||||
|
index = rule['ruleTag'] - 1
|
||||||
|
#TODO(linb):a simple filter of the retrived rules which may be
|
||||||
|
#created by other operations unintentionally
|
||||||
|
if index < len(firewall['firewall_rule_list']):
|
||||||
|
rule_vseid = rule['ruleId']
|
||||||
|
rule_id = firewall['firewall_rule_list'][index]['id']
|
||||||
|
map_info = {
|
||||||
|
'rule_id': rule_id,
|
||||||
|
'rule_vseid': rule_vseid,
|
||||||
|
'edge_id': edge_id
|
||||||
|
}
|
||||||
|
vcns_db.add_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, map_info)
|
||||||
|
|
||||||
|
def _get_firewall(self, context, edge_id):
|
||||||
|
try:
|
||||||
|
return self.vcns.get_firewall(edge_id)[1]
|
||||||
|
except vcns_exc.VcnsApiException as e:
|
||||||
|
LOG.exception(_("Failed to get firewall with edge "
|
||||||
|
"id: %s"), edge_id)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def _get_firewall_rule_next(self, context, edge_id, rule_vseid):
|
||||||
|
# Return the firewall rule below 'rule_vseid'
|
||||||
|
fw_cfg = self._get_firewall(context, edge_id)
|
||||||
|
for i in range(len(fw_cfg['firewallRules']['firewallRules'])):
|
||||||
|
rule_cur = fw_cfg['firewallRules']['firewallRules'][i]
|
||||||
|
if str(rule_cur['ruleId']) == rule_vseid:
|
||||||
|
if (i + 1) == len(fw_cfg['firewallRules']['firewallRules']):
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return fw_cfg['firewallRules']['firewallRules'][i + 1]
|
||||||
|
|
||||||
|
def get_firewall_rule(self, context, id, edge_id):
|
||||||
|
rule_map = vcns_db.get_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, id, edge_id)
|
||||||
|
if rule_map is None:
|
||||||
|
msg = _("No rule id:%s found in the edge_firewall_binding") % id
|
||||||
|
LOG.error(msg)
|
||||||
|
raise vcns_exc.VcnsNotFound(
|
||||||
|
resource='vcns_firewall_rule_bindings', msg=msg)
|
||||||
|
vcns_rule_id = rule_map.rule_vseid
|
||||||
|
try:
|
||||||
|
response = self.vcns.get_firewall_rule(
|
||||||
|
edge_id, vcns_rule_id)[1]
|
||||||
|
except vcns_exc.VcnsApiException as e:
|
||||||
|
LOG.exception(_("Failed to get firewall rule: %(rule_id)s "
|
||||||
|
"with edge_id: %(edge_id)s"), {
|
||||||
|
'rule_id': id,
|
||||||
|
'edge_id': edge_id})
|
||||||
|
raise e
|
||||||
|
return self._restore_firewall_rule(context, edge_id, response)
|
||||||
|
|
||||||
|
def get_firewall(self, context, edge_id):
|
||||||
|
response = self._get_firewall(context, edge_id)
|
||||||
|
return self._restore_firewall(context, edge_id, response)
|
||||||
|
|
||||||
|
def update_firewall(self, context, edge_id, firewall):
|
||||||
|
fw_req = self._convert_firewall(context, firewall)
|
||||||
|
try:
|
||||||
|
self.vcns.update_firewall(edge_id, fw_req)
|
||||||
|
except vcns_exc.VcnsApiException as e:
|
||||||
|
LOG.exception(_("Failed to update firewall "
|
||||||
|
"with edge_id: %s"), edge_id)
|
||||||
|
raise e
|
||||||
|
fw_res = self._get_firewall(context, edge_id)
|
||||||
|
vcns_db.cleanup_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, edge_id)
|
||||||
|
self._create_rule_id_mapping(context, edge_id, firewall, fw_res)
|
||||||
|
|
||||||
|
def delete_firewall(self, context, edge_id):
|
||||||
|
try:
|
||||||
|
self.vcns.delete_firewall(edge_id)
|
||||||
|
except vcns_exc.VcnsApiException as e:
|
||||||
|
LOG.exception(_("Failed to delete firewall "
|
||||||
|
"with edge_id:%s"), edge_id)
|
||||||
|
raise e
|
||||||
|
vcns_db.cleanup_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, edge_id)
|
||||||
|
|
||||||
|
def update_firewall_rule(self, context, id, edge_id, firewall_rule):
|
||||||
|
rule_map = vcns_db.get_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, id, edge_id)
|
||||||
|
vcns_rule_id = rule_map.rule_vseid
|
||||||
|
fwr_req = self._convert_firewall_rule(context, firewall_rule)
|
||||||
|
try:
|
||||||
|
self.vcns.update_firewall_rule(edge_id, vcns_rule_id, fwr_req)
|
||||||
|
except vcns_exc.VcnsApiException:
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
LOG.exception(_("Failed to update firewall rule: %(rule_id)s "
|
||||||
|
"with edge_id: %(edge_id)s"),
|
||||||
|
{'rule_id': id,
|
||||||
|
'edge_id': edge_id})
|
||||||
|
|
||||||
|
def delete_firewall_rule(self, context, id, edge_id):
|
||||||
|
rule_map = vcns_db.get_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, id, edge_id)
|
||||||
|
vcns_rule_id = rule_map.rule_vseid
|
||||||
|
try:
|
||||||
|
self.vcns.delete_firewall_rule(edge_id, vcns_rule_id)
|
||||||
|
except vcns_exc.VcnsApiException:
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
LOG.exception(_("Failed to delete firewall rule: %(rule_id)s "
|
||||||
|
"with edge_id: %(edge_id)s"),
|
||||||
|
{'rule_id': id,
|
||||||
|
'edge_id': edge_id})
|
||||||
|
vcns_db.delete_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, id)
|
||||||
|
|
||||||
|
def _add_rule_above(self, context, ref_rule_id, edge_id, firewall_rule):
|
||||||
|
rule_map = vcns_db.get_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, ref_rule_id, edge_id)
|
||||||
|
ref_vcns_rule_id = rule_map.rule_vseid
|
||||||
|
fwr_req = self._convert_firewall_rule(context, firewall_rule)
|
||||||
|
try:
|
||||||
|
header = self.vcns.add_firewall_rule_above(
|
||||||
|
edge_id, ref_vcns_rule_id, fwr_req)[0]
|
||||||
|
except vcns_exc.VcnsApiException:
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
LOG.exception(_("Failed to add firewall rule above: "
|
||||||
|
"%(rule_id)s with edge_id: %(edge_id)s"),
|
||||||
|
{'rule_id': ref_vcns_rule_id,
|
||||||
|
'edge_id': edge_id})
|
||||||
|
|
||||||
|
objuri = header['location']
|
||||||
|
fwr_vseid = objuri[objuri.rfind("/") + 1:]
|
||||||
|
map_info = {
|
||||||
|
'rule_id': firewall_rule['id'],
|
||||||
|
'rule_vseid': fwr_vseid,
|
||||||
|
'edge_id': edge_id}
|
||||||
|
vcns_db.add_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, map_info)
|
||||||
|
|
||||||
|
def _add_rule_below(self, context, ref_rule_id, edge_id, firewall_rule):
|
||||||
|
rule_map = vcns_db.get_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, ref_rule_id, edge_id)
|
||||||
|
ref_vcns_rule_id = rule_map.rule_vseid
|
||||||
|
fwr_vse_next = self._get_firewall_rule_next(
|
||||||
|
context, edge_id, ref_vcns_rule_id)
|
||||||
|
fwr_req = self._convert_firewall_rule(context, firewall_rule)
|
||||||
|
if fwr_vse_next:
|
||||||
|
ref_vcns_rule_id = fwr_vse_next['ruleId']
|
||||||
|
try:
|
||||||
|
header = self.vcns.add_firewall_rule_above(
|
||||||
|
edge_id, int(ref_vcns_rule_id), fwr_req)[0]
|
||||||
|
except vcns_exc.VcnsApiException:
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
LOG.exception(_("Failed to add firewall rule above: "
|
||||||
|
"%(rule_id)s with edge_id: %(edge_id)s"),
|
||||||
|
{'rule_id': ref_vcns_rule_id,
|
||||||
|
'edge_id': edge_id})
|
||||||
|
else:
|
||||||
|
# append the rule at the bottom
|
||||||
|
try:
|
||||||
|
header = self.vcns.add_firewall_rule(
|
||||||
|
edge_id, fwr_req)[0]
|
||||||
|
except vcns_exc.VcnsApiException:
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
LOG.exception(_("Failed to append a firewall rule"
|
||||||
|
"with edge_id: %s"), edge_id)
|
||||||
|
|
||||||
|
objuri = header['location']
|
||||||
|
fwr_vseid = objuri[objuri.rfind("/") + 1:]
|
||||||
|
map_info = {
|
||||||
|
'rule_id': firewall_rule['id'],
|
||||||
|
'rule_vseid': fwr_vseid,
|
||||||
|
'edge_id': edge_id
|
||||||
|
}
|
||||||
|
vcns_db.add_vcns_edge_firewallrule_binding(
|
||||||
|
context.session, map_info)
|
||||||
|
|
||||||
|
def insert_rule(self, context, rule_info, edge_id, fwr):
|
||||||
|
if rule_info.get('insert_before'):
|
||||||
|
self._add_rule_above(
|
||||||
|
context, rule_info['insert_before'], edge_id, fwr)
|
||||||
|
elif rule_info.get('insert_after'):
|
||||||
|
self._add_rule_below(
|
||||||
|
context, rule_info['insert_after'], edge_id, fwr)
|
||||||
|
else:
|
||||||
|
msg = _("Can't execute insert rule operation "
|
||||||
|
"without reference rule_id")
|
||||||
|
raise vcns_exc.BadRequest(resource='firewall_rule', msg=msg)
|
||||||
@@ -28,6 +28,10 @@ HTTP_DELETE = "DELETE"
|
|||||||
HTTP_PUT = "PUT"
|
HTTP_PUT = "PUT"
|
||||||
URI_PREFIX = "/api/4.0/edges"
|
URI_PREFIX = "/api/4.0/edges"
|
||||||
|
|
||||||
|
#FwaaS constants
|
||||||
|
FIREWALL_SERVICE = "firewall/config"
|
||||||
|
FIREWALL_RULE_RESOURCE = "rules"
|
||||||
|
|
||||||
|
|
||||||
class Vcns(object):
|
class Vcns(object):
|
||||||
|
|
||||||
@@ -106,3 +110,69 @@ class Vcns(object):
|
|||||||
def delete_lswitch(self, lswitch_id):
|
def delete_lswitch(self, lswitch_id):
|
||||||
uri = "/api/ws.v1/lswitch/%s" % lswitch_id
|
uri = "/api/ws.v1/lswitch/%s" % lswitch_id
|
||||||
return self.do_request(HTTP_DELETE, uri)
|
return self.do_request(HTTP_DELETE, uri)
|
||||||
|
|
||||||
|
def update_firewall(self, edge_id, fw_req):
|
||||||
|
uri = self._build_uri_path(
|
||||||
|
edge_id, FIREWALL_SERVICE)
|
||||||
|
return self.do_request(HTTP_PUT, uri, fw_req)
|
||||||
|
|
||||||
|
def delete_firewall(self, edge_id):
|
||||||
|
uri = self._build_uri_path(
|
||||||
|
edge_id, FIREWALL_SERVICE, None)
|
||||||
|
return self.do_request(HTTP_DELETE, uri)
|
||||||
|
|
||||||
|
def update_firewall_rule(self, edge_id, vcns_rule_id, fwr_req):
|
||||||
|
uri = self._build_uri_path(
|
||||||
|
edge_id, FIREWALL_SERVICE,
|
||||||
|
FIREWALL_RULE_RESOURCE,
|
||||||
|
vcns_rule_id)
|
||||||
|
return self.do_request(HTTP_PUT, uri, fwr_req)
|
||||||
|
|
||||||
|
def delete_firewall_rule(self, edge_id, vcns_rule_id):
|
||||||
|
uri = self._build_uri_path(
|
||||||
|
edge_id, FIREWALL_SERVICE,
|
||||||
|
FIREWALL_RULE_RESOURCE,
|
||||||
|
vcns_rule_id)
|
||||||
|
return self.do_request(HTTP_DELETE, uri)
|
||||||
|
|
||||||
|
def add_firewall_rule_above(self, edge_id, ref_vcns_rule_id, fwr_req):
|
||||||
|
uri = self._build_uri_path(
|
||||||
|
edge_id, FIREWALL_SERVICE,
|
||||||
|
FIREWALL_RULE_RESOURCE)
|
||||||
|
uri += "?aboveRuleId=" + ref_vcns_rule_id
|
||||||
|
return self.do_request(HTTP_POST, uri, fwr_req)
|
||||||
|
|
||||||
|
def add_firewall_rule(self, edge_id, fwr_req):
|
||||||
|
uri = self._build_uri_path(
|
||||||
|
edge_id, FIREWALL_SERVICE,
|
||||||
|
FIREWALL_RULE_RESOURCE)
|
||||||
|
return self.do_request(HTTP_POST, uri, fwr_req)
|
||||||
|
|
||||||
|
def get_firewall(self, edge_id):
|
||||||
|
uri = self._build_uri_path(edge_id, FIREWALL_SERVICE)
|
||||||
|
return self.do_request(HTTP_GET, uri, decode=True)
|
||||||
|
|
||||||
|
def get_firewall_rule(self, edge_id, vcns_rule_id):
|
||||||
|
uri = self._build_uri_path(
|
||||||
|
edge_id, FIREWALL_SERVICE,
|
||||||
|
FIREWALL_RULE_RESOURCE,
|
||||||
|
vcns_rule_id)
|
||||||
|
return self.do_request(HTTP_GET, uri, decode=True)
|
||||||
|
|
||||||
|
def _build_uri_path(self, edge_id,
|
||||||
|
service,
|
||||||
|
resource=None,
|
||||||
|
resource_id=None,
|
||||||
|
parent_resource_id=None,
|
||||||
|
fields=None,
|
||||||
|
relations=None,
|
||||||
|
filters=None,
|
||||||
|
types=None,
|
||||||
|
is_attachment=False):
|
||||||
|
uri_prefix = "%s/%s/%s" % (URI_PREFIX, edge_id, service)
|
||||||
|
if resource:
|
||||||
|
res_path = resource + (resource_id and "/%s" % resource_id or '')
|
||||||
|
uri_path = "%s/%s" % (uri_prefix, res_path)
|
||||||
|
else:
|
||||||
|
uri_path = uri_prefix
|
||||||
|
return uri_path
|
||||||
|
|||||||
@@ -20,11 +20,13 @@ from oslo.config import cfg
|
|||||||
|
|
||||||
from neutron.plugins.nicira.common import config # noqa
|
from neutron.plugins.nicira.common import config # noqa
|
||||||
from neutron.plugins.nicira.vshield import edge_appliance_driver
|
from neutron.plugins.nicira.vshield import edge_appliance_driver
|
||||||
|
from neutron.plugins.nicira.vshield import edge_firewall_driver
|
||||||
from neutron.plugins.nicira.vshield.tasks import tasks
|
from neutron.plugins.nicira.vshield.tasks import tasks
|
||||||
from neutron.plugins.nicira.vshield import vcns
|
from neutron.plugins.nicira.vshield import vcns
|
||||||
|
|
||||||
|
|
||||||
class VcnsDriver(edge_appliance_driver.EdgeApplianceDriver):
|
class VcnsDriver(edge_appliance_driver.EdgeApplianceDriver,
|
||||||
|
edge_firewall_driver.EdgeFirewallDriver):
|
||||||
def __init__(self, callbacks):
|
def __init__(self, callbacks):
|
||||||
super(VcnsDriver, self).__init__()
|
super(VcnsDriver, self).__init__()
|
||||||
|
|
||||||
@@ -40,5 +42,4 @@ class VcnsDriver(edge_appliance_driver.EdgeApplianceDriver):
|
|||||||
interval = cfg.CONF.vcns.task_status_check_interval
|
interval = cfg.CONF.vcns.task_status_check_interval
|
||||||
self.task_manager = tasks.TaskManager(interval)
|
self.task_manager = tasks.TaskManager(interval)
|
||||||
self.task_manager.start()
|
self.task_manager.start()
|
||||||
|
|
||||||
self.vcns = vcns.Vcns(self.vcns_uri, self.vcns_user, self.vcns_passwd)
|
self.vcns = vcns.Vcns(self.vcns_uri, self.vcns_user, self.vcns_passwd)
|
||||||
|
|||||||
@@ -58,23 +58,25 @@ class FirewallPluginDbTestCase(test_db_plugin.NeutronDbPluginV2TestCase):
|
|||||||
for k in firewall.RESOURCE_ATTRIBUTE_MAP.keys()
|
for k in firewall.RESOURCE_ATTRIBUTE_MAP.keys()
|
||||||
)
|
)
|
||||||
|
|
||||||
def setUp(self, core_plugin=None, fw_plugin=None):
|
def setUp(self, core_plugin=None, fw_plugin=None, ext_mgr=None):
|
||||||
if not fw_plugin:
|
if not fw_plugin:
|
||||||
fw_plugin = DB_FW_PLUGIN_KLASS
|
fw_plugin = DB_FW_PLUGIN_KLASS
|
||||||
service_plugins = {'fw_plugin_name': fw_plugin}
|
service_plugins = {'fw_plugin_name': fw_plugin}
|
||||||
|
|
||||||
fdb.Firewall_db_mixin.supported_extension_aliases = ["fwaas"]
|
fdb.Firewall_db_mixin.supported_extension_aliases = ["fwaas"]
|
||||||
super(FirewallPluginDbTestCase, self).setUp(
|
super(FirewallPluginDbTestCase, self).setUp(
|
||||||
|
ext_mgr=ext_mgr,
|
||||||
service_plugins=service_plugins
|
service_plugins=service_plugins
|
||||||
)
|
)
|
||||||
|
|
||||||
self.plugin = importutils.import_object(fw_plugin)
|
if not ext_mgr:
|
||||||
ext_mgr = api_ext.PluginAwareExtensionManager(
|
self.plugin = importutils.import_object(fw_plugin)
|
||||||
extensions_path,
|
ext_mgr = api_ext.PluginAwareExtensionManager(
|
||||||
{constants.FIREWALL: self.plugin}
|
extensions_path,
|
||||||
)
|
{constants.FIREWALL: self.plugin}
|
||||||
app = config.load_paste_app('extensions_test_app')
|
)
|
||||||
self.ext_api = api_ext.ExtensionMiddleware(app, ext_mgr=ext_mgr)
|
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,
|
def _test_list_resources(self, resource, items,
|
||||||
neutron_context=None,
|
neutron_context=None,
|
||||||
|
|||||||
@@ -22,13 +22,18 @@ from neutron.plugins.nicira import extensions
|
|||||||
import neutron.plugins.nicira.NeutronPlugin as plugin
|
import neutron.plugins.nicira.NeutronPlugin as plugin
|
||||||
import neutron.plugins.nicira.NeutronServicePlugin as service_plugin
|
import neutron.plugins.nicira.NeutronServicePlugin as service_plugin
|
||||||
import neutron.plugins.nicira.NvpApiClient as nvpapi
|
import neutron.plugins.nicira.NvpApiClient as nvpapi
|
||||||
|
from neutron.plugins.nicira.vshield.common import (
|
||||||
|
VcnsApiClient as vcnsapi)
|
||||||
from neutron.plugins.nicira.vshield import vcns
|
from neutron.plugins.nicira.vshield import vcns
|
||||||
|
import neutron.plugins.nicira.vshield.vcns_driver as vcnsdriver
|
||||||
|
|
||||||
nvp_plugin = plugin.NvpPluginV2
|
nvp_plugin = plugin.NvpPluginV2
|
||||||
nvp_service_plugin = service_plugin.NvpAdvancedPlugin
|
nvp_service_plugin = service_plugin.NvpAdvancedPlugin
|
||||||
api_helper = nvpapi.NVPApiHelper
|
api_helper = nvpapi.NVPApiHelper
|
||||||
nvp_client = client.NvpApiClientEventlet
|
nvp_client = client.NvpApiClientEventlet
|
||||||
vcns_class = vcns.Vcns
|
vcns_class = vcns.Vcns
|
||||||
|
vcns_driver = vcnsdriver.VcnsDriver
|
||||||
|
vcns_api_helper = vcnsapi.VcnsApiHelper
|
||||||
|
|
||||||
STUBS_PATH = os.path.join(os.path.dirname(__file__), 'etc')
|
STUBS_PATH = os.path.join(os.path.dirname(__file__), 'etc')
|
||||||
NVPEXT_PATH = os.path.dirname(extensions.__file__)
|
NVPEXT_PATH = os.path.dirname(extensions.__file__)
|
||||||
@@ -38,6 +43,9 @@ SERVICE_PLUGIN_NAME = '%s.%s' % (nvp_service_plugin.__module__,
|
|||||||
nvp_service_plugin.__name__)
|
nvp_service_plugin.__name__)
|
||||||
CLIENT_NAME = '%s.%s' % (nvp_client.__module__, nvp_client.__name__)
|
CLIENT_NAME = '%s.%s' % (nvp_client.__module__, nvp_client.__name__)
|
||||||
VCNS_NAME = '%s.%s' % (vcns_class.__module__, vcns_class.__name__)
|
VCNS_NAME = '%s.%s' % (vcns_class.__module__, vcns_class.__name__)
|
||||||
|
VCNS_DRIVER_NAME = '%s.%s' % (vcns_driver.__module__, vcns_driver.__name__)
|
||||||
|
VCNSAPI_NAME = '%s.%s' % (vcns_api_helper.__module__,
|
||||||
|
vcns_api_helper.__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_fake_conf(filename):
|
def get_fake_conf(filename):
|
||||||
|
|||||||
@@ -61,15 +61,17 @@ class ServiceRouterTestExtensionManager(object):
|
|||||||
|
|
||||||
class NvpRouterTestCase(test_nicira_plugin.TestNiciraL3NatTestCase):
|
class NvpRouterTestCase(test_nicira_plugin.TestNiciraL3NatTestCase):
|
||||||
|
|
||||||
def setUp(self, plugin=None, ext_mgr=None):
|
def setUp(self, plugin=None, ext_mgr=None, service_plugins=None):
|
||||||
plugin = plugin or SERVICE_PLUGIN_NAME
|
plugin = plugin or SERVICE_PLUGIN_NAME
|
||||||
super(NvpRouterTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr)
|
super(NvpRouterTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr,
|
||||||
|
service_plugins=service_plugins)
|
||||||
|
|
||||||
|
|
||||||
class ServiceRouterTestCase(NvpRouterTestCase):
|
class ServiceRouterTest(test_nicira_plugin.NiciraL3NatTest):
|
||||||
|
|
||||||
def vcns_patch(self):
|
def vcns_patch(self):
|
||||||
instance = self.mock_vcns.start()
|
instance = self.mock_vcns.start()
|
||||||
|
self.vcns_instance = instance
|
||||||
instance.return_value.deploy_edge.side_effect = self.fc2.deploy_edge
|
instance.return_value.deploy_edge.side_effect = self.fc2.deploy_edge
|
||||||
instance.return_value.get_edge_id.side_effect = self.fc2.get_edge_id
|
instance.return_value.get_edge_id.side_effect = self.fc2.get_edge_id
|
||||||
instance.return_value.get_edge_deploy_status.side_effect = (
|
instance.return_value.get_edge_deploy_status.side_effect = (
|
||||||
@@ -93,7 +95,7 @@ class ServiceRouterTestCase(NvpRouterTestCase):
|
|||||||
instance.return_value.delete_lswitch.side_effect = (
|
instance.return_value.delete_lswitch.side_effect = (
|
||||||
self.fc2.delete_lswitch)
|
self.fc2.delete_lswitch)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self, ext_mgr=None, service_plugins=None):
|
||||||
cfg.CONF.set_override('api_extensions_path', NVPEXT_PATH)
|
cfg.CONF.set_override('api_extensions_path', NVPEXT_PATH)
|
||||||
cfg.CONF.set_override('task_status_check_interval', 100, group="vcns")
|
cfg.CONF.set_override('task_status_check_interval', 100, group="vcns")
|
||||||
|
|
||||||
@@ -103,8 +105,11 @@ class ServiceRouterTestCase(NvpRouterTestCase):
|
|||||||
self.mock_vcns = mock.patch(VCNS_NAME, autospec=True)
|
self.mock_vcns = mock.patch(VCNS_NAME, autospec=True)
|
||||||
self.vcns_patch()
|
self.vcns_patch()
|
||||||
|
|
||||||
super(ServiceRouterTestCase, self).setUp(
|
ext_mgr = ext_mgr or ServiceRouterTestExtensionManager()
|
||||||
ext_mgr=ServiceRouterTestExtensionManager())
|
super(ServiceRouterTest, self).setUp(
|
||||||
|
plugin=SERVICE_PLUGIN_NAME,
|
||||||
|
service_plugins=service_plugins,
|
||||||
|
ext_mgr=ext_mgr)
|
||||||
|
|
||||||
self.fc2.set_fake_nvpapi(self.fc)
|
self.fc2.set_fake_nvpapi(self.fc)
|
||||||
self.addCleanup(self.fc2.reset_all)
|
self.addCleanup(self.fc2.reset_all)
|
||||||
@@ -122,7 +127,7 @@ class ServiceRouterTestCase(NvpRouterTestCase):
|
|||||||
raise Exception(_("Tasks not completed"))
|
raise Exception(_("Tasks not completed"))
|
||||||
manager.stop()
|
manager.stop()
|
||||||
|
|
||||||
super(ServiceRouterTestCase, self).tearDown()
|
super(ServiceRouterTest, self).tearDown()
|
||||||
|
|
||||||
def _create_router(self, fmt, tenant_id, name=None,
|
def _create_router(self, fmt, tenant_id, name=None,
|
||||||
admin_state_up=None, set_context=False,
|
admin_state_up=None, set_context=False,
|
||||||
@@ -145,6 +150,9 @@ class ServiceRouterTestCase(NvpRouterTestCase):
|
|||||||
|
|
||||||
return router_req.get_response(self.ext_api)
|
return router_req.get_response(self.ext_api)
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceRouterTestCase(ServiceRouterTest, NvpRouterTestCase):
|
||||||
|
|
||||||
def test_router_create(self):
|
def test_router_create(self):
|
||||||
name = 'router1'
|
name = 'router1'
|
||||||
tenant_id = _uuid()
|
tenant_id = _uuid()
|
||||||
|
|||||||
564
neutron/tests/unit/nicira/test_fwaas_plugin.py
Normal file
564
neutron/tests/unit/nicira/test_fwaas_plugin.py
Normal file
@@ -0,0 +1,564 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2013 VMware, 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 copy
|
||||||
|
import webob.exc
|
||||||
|
|
||||||
|
from neutron.api.v2 import attributes
|
||||||
|
from neutron import context
|
||||||
|
from neutron.extensions import firewall
|
||||||
|
from neutron import manager
|
||||||
|
from neutron.openstack.common import uuidutils
|
||||||
|
from neutron.plugins.common import constants as const
|
||||||
|
from neutron.tests.unit.db.firewall import test_db_firewall
|
||||||
|
from neutron.tests.unit.nicira import test_edge_router
|
||||||
|
|
||||||
|
_uuid = uuidutils.generate_uuid
|
||||||
|
|
||||||
|
FW_PLUGIN_CLASS = (
|
||||||
|
"neutron.plugins.nicira.NeutronServicePlugin.NvpAdvancedPlugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class FirewallTestExtensionManager(
|
||||||
|
test_edge_router.ServiceRouterTestExtensionManager):
|
||||||
|
|
||||||
|
def get_resources(self):
|
||||||
|
# If l3 resources have been loaded and updated by main API
|
||||||
|
# router, update the map in the l3 extension so it will load
|
||||||
|
# the same attributes as the API router
|
||||||
|
resources = super(FirewallTestExtensionManager, self).get_resources()
|
||||||
|
firewall_attr_map = copy.deepcopy(firewall.RESOURCE_ATTRIBUTE_MAP)
|
||||||
|
for res in firewall.RESOURCE_ATTRIBUTE_MAP.keys():
|
||||||
|
attr_info = attributes.RESOURCE_ATTRIBUTE_MAP.get(res)
|
||||||
|
if attr_info:
|
||||||
|
firewall.RESOURCE_ATTRIBUTE_MAP[res] = attr_info
|
||||||
|
fw_resources = firewall.Firewall.get_resources()
|
||||||
|
# restore the original resources once the controllers are created
|
||||||
|
firewall.RESOURCE_ATTRIBUTE_MAP = firewall_attr_map
|
||||||
|
|
||||||
|
resources.extend(fw_resources)
|
||||||
|
|
||||||
|
return resources
|
||||||
|
|
||||||
|
def get_actions(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def get_request_extensions(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
class FirewallPluginTestCase(test_db_firewall.FirewallPluginDbTestCase,
|
||||||
|
test_edge_router.ServiceRouterTest):
|
||||||
|
|
||||||
|
def vcns_firewall_patch(self):
|
||||||
|
self.vcns_instance.return_value.update_firewall.side_effect = (
|
||||||
|
self.fc2.update_firewall)
|
||||||
|
self.vcns_instance.return_value.delete_firewall.side_effect = (
|
||||||
|
self.fc2.delete_firewall)
|
||||||
|
self.vcns_instance.return_value.update_firewall_rule.side_effect = (
|
||||||
|
self.fc2.update_firewall_rule)
|
||||||
|
self.vcns_instance.return_value.delete_firewall_rule.side_effect = (
|
||||||
|
self.fc2.delete_firewall_rule)
|
||||||
|
self.vcns_instance.return_value.add_firewall_rule_above.side_effect = (
|
||||||
|
self.fc2.add_firewall_rule_above)
|
||||||
|
self.vcns_instance.return_value.add_firewall_rule.side_effect = (
|
||||||
|
self.fc2.add_firewall_rule)
|
||||||
|
self.vcns_instance.return_value.get_firewall.side_effect = (
|
||||||
|
self.fc2.get_firewall)
|
||||||
|
self.vcns_instance.return_value.get_firewall_rule.side_effect = (
|
||||||
|
self.fc2.get_firewall_rule)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
# Save the global RESOURCE_ATTRIBUTE_MAP
|
||||||
|
self.saved_attr_map = {}
|
||||||
|
for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems():
|
||||||
|
self.saved_attr_map[resource] = attrs.copy()
|
||||||
|
|
||||||
|
super(FirewallPluginTestCase, self).setUp(
|
||||||
|
ext_mgr=FirewallTestExtensionManager(),
|
||||||
|
fw_plugin=FW_PLUGIN_CLASS)
|
||||||
|
self.vcns_firewall_patch()
|
||||||
|
self.plugin = manager.NeutronManager.get_plugin()
|
||||||
|
self.router_id = None
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(FirewallPluginTestCase, self).tearDown()
|
||||||
|
# Restore the global RESOURCE_ATTRIBUTE_MAP
|
||||||
|
attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map
|
||||||
|
self.ext_api = None
|
||||||
|
self.plugin = None
|
||||||
|
|
||||||
|
def _fake_router_edge_mapping(self):
|
||||||
|
req = self._create_router(self.fmt, self._tenant_id)
|
||||||
|
res = self.deserialize(self.fmt, req)
|
||||||
|
self.router_id = res['router']['id']
|
||||||
|
|
||||||
|
def _create_firewall(self, fmt, name, description, firewall_policy_id,
|
||||||
|
admin_state_up=True, expected_res_status=None,
|
||||||
|
**kwargs):
|
||||||
|
data = {'firewall': {'name': name,
|
||||||
|
'description': description,
|
||||||
|
'firewall_policy_id': firewall_policy_id,
|
||||||
|
'router_id': self.router_id,
|
||||||
|
'admin_state_up': admin_state_up,
|
||||||
|
'tenant_id': self._tenant_id}}
|
||||||
|
|
||||||
|
firewall_req = self.new_create_request('firewalls', data, fmt)
|
||||||
|
firewall_res = firewall_req.get_response(self.ext_api)
|
||||||
|
if expected_res_status:
|
||||||
|
self.assertEqual(firewall_res.status_int, expected_res_status)
|
||||||
|
|
||||||
|
return firewall_res
|
||||||
|
|
||||||
|
def test_create_firewall(self):
|
||||||
|
self._fake_router_edge_mapping()
|
||||||
|
|
||||||
|
name = "new_fw"
|
||||||
|
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,
|
||||||
|
router_id=self.router_id,
|
||||||
|
admin_state_up=
|
||||||
|
test_db_firewall.ADMIN_STATE_UP,
|
||||||
|
expected_res_status=201) as fw:
|
||||||
|
attrs = self._replace_firewall_status(
|
||||||
|
attrs, const.PENDING_CREATE, const.ACTIVE)
|
||||||
|
for k, v in attrs.iteritems():
|
||||||
|
self.assertEqual(fw['firewall'][k], v)
|
||||||
|
|
||||||
|
def test_update_firewall(self):
|
||||||
|
self._fake_router_edge_mapping()
|
||||||
|
|
||||||
|
name = "new_fw"
|
||||||
|
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, router_id=self.router_id,
|
||||||
|
admin_state_up=test_db_firewall.ADMIN_STATE_UP) as fw:
|
||||||
|
fw_id = fw['firewall']['id']
|
||||||
|
new_data = {'firewall': {'name': name}}
|
||||||
|
req = self.new_update_request('firewalls', new_data, fw_id)
|
||||||
|
res = req.get_response(self.ext_api)
|
||||||
|
self.assertEqual(res.status_int, 200)
|
||||||
|
res_json = self.deserialize(
|
||||||
|
self.fmt, res)
|
||||||
|
attrs = self._replace_firewall_status(
|
||||||
|
attrs, const.PENDING_CREATE, const.ACTIVE)
|
||||||
|
for k, v in attrs.iteritems():
|
||||||
|
self.assertEqual(res_json['firewall'][k], v)
|
||||||
|
|
||||||
|
def test_delete_firewall(self):
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
self._fake_router_edge_mapping()
|
||||||
|
|
||||||
|
with self.firewall_policy() as fwp:
|
||||||
|
fwp_id = fwp['firewall_policy']['id']
|
||||||
|
with self.firewall(
|
||||||
|
firewall_policy_id=fwp_id,
|
||||||
|
router_id=self.router_id,
|
||||||
|
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
|
||||||
|
no_delete=True) as fw:
|
||||||
|
fw_id = fw['firewall']['id']
|
||||||
|
with ctx.session.begin(subtransactions=True):
|
||||||
|
req = self.new_delete_request('firewalls', fw_id)
|
||||||
|
res = req.get_response(self.ext_api)
|
||||||
|
self.assertEqual(res.status_int, 204)
|
||||||
|
self.assertRaises(
|
||||||
|
firewall.FirewallNotFound,
|
||||||
|
self.plugin.get_firewall, ctx, fw_id)
|
||||||
|
|
||||||
|
def test_create_firewall_with_rules(self):
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
self._fake_router_edge_mapping()
|
||||||
|
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr1'),
|
||||||
|
self.firewall_rule(name='fwr2'),
|
||||||
|
self.firewall_rule(name='fwr3')) as fr:
|
||||||
|
with self.firewall_policy() as fwp:
|
||||||
|
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, router_id=self.router_id,
|
||||||
|
admin_state_up=test_db_firewall.ADMIN_STATE_UP) as fw:
|
||||||
|
rule_list = (
|
||||||
|
self.plugin._make_firewall_rule_list_by_policy_id(
|
||||||
|
ctx, fw['firewall']['firewall_policy_id']))
|
||||||
|
self._compare_firewall_rule_lists(
|
||||||
|
fwp_id, fr, rule_list)
|
||||||
|
|
||||||
|
def test_update_firewall_policy_with_no_firewall(self):
|
||||||
|
name = "new_firewall_policy1"
|
||||||
|
attrs = self._get_test_firewall_policy_attrs(name)
|
||||||
|
|
||||||
|
with self.firewall_policy(shared=test_db_firewall.SHARED,
|
||||||
|
firewall_rules=None,
|
||||||
|
audited=test_db_firewall.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 attrs.iteritems():
|
||||||
|
self.assertEqual(res['firewall_policy'][k], v)
|
||||||
|
|
||||||
|
def test_update_firewall_policy_with_firewall(self):
|
||||||
|
self._fake_router_edge_mapping()
|
||||||
|
|
||||||
|
name = "new_firewall_policy1"
|
||||||
|
attrs = self._get_test_firewall_policy_attrs(name)
|
||||||
|
|
||||||
|
with self.firewall_policy(shared=test_db_firewall.SHARED,
|
||||||
|
firewall_rules=None,
|
||||||
|
audited=test_db_firewall.AUDITED) as fwp:
|
||||||
|
fwp_id = fwp['firewall_policy']['id']
|
||||||
|
with self.firewall(firewall_policy_id=fwp_id,
|
||||||
|
router_id=self.router_id,
|
||||||
|
admin_state_up=
|
||||||
|
test_db_firewall.ADMIN_STATE_UP):
|
||||||
|
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 attrs.iteritems():
|
||||||
|
self.assertEqual(res['firewall_policy'][k], v)
|
||||||
|
|
||||||
|
def test_update_firewall_rule_with_no_firewall(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,
|
||||||
|
'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 attrs.iteritems():
|
||||||
|
self.assertEqual(res['firewall_rule'][k], v)
|
||||||
|
|
||||||
|
attrs['source_port'] = '10000'
|
||||||
|
attrs['destination_port'] = '80'
|
||||||
|
with self.firewall_rule() as fwr:
|
||||||
|
data = {'firewall_rule': {'name': name,
|
||||||
|
'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 attrs.iteritems():
|
||||||
|
self.assertEqual(res['firewall_rule'][k], v)
|
||||||
|
|
||||||
|
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 attrs.iteritems():
|
||||||
|
self.assertEqual(res['firewall_rule'][k], v)
|
||||||
|
|
||||||
|
def test_update_firewall_rule_with_firewall(self):
|
||||||
|
self._fake_router_edge_mapping()
|
||||||
|
|
||||||
|
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
|
||||||
|
with self.firewall(firewall_policy_id=fwp_id,
|
||||||
|
router_id=self.router_id,
|
||||||
|
admin_state_up=
|
||||||
|
test_db_firewall.ADMIN_STATE_UP):
|
||||||
|
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 attrs.iteritems():
|
||||||
|
self.assertEqual(res['firewall_rule'][k], v)
|
||||||
|
|
||||||
|
def test_insert_rule_with_no_firewall(self):
|
||||||
|
attrs = self._get_test_firewall_policy_attrs()
|
||||||
|
attrs['audited'] = False
|
||||||
|
attrs['firewall_list'] = []
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr0'),
|
||||||
|
self.firewall_rule(name='fwr1'),
|
||||||
|
self.firewall_rule(name='fwr2'),
|
||||||
|
self.firewall_rule(name='fwr3'),
|
||||||
|
self.firewall_rule(name='fwr4'),
|
||||||
|
self.firewall_rule(name='fwr5'),
|
||||||
|
self.firewall_rule(name='fwr6')) as fwr:
|
||||||
|
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_insert_rule_with_firewall(self):
|
||||||
|
self._fake_router_edge_mapping()
|
||||||
|
|
||||||
|
attrs = self._get_test_firewall_policy_attrs()
|
||||||
|
attrs['audited'] = False
|
||||||
|
attrs['firewall_list'] = []
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr0'),
|
||||||
|
self.firewall_rule(name='fwr1'),
|
||||||
|
self.firewall_rule(name='fwr2'),
|
||||||
|
self.firewall_rule(name='fwr3'),
|
||||||
|
self.firewall_rule(name='fwr4'),
|
||||||
|
self.firewall_rule(name='fwr5'),
|
||||||
|
self.firewall_rule(name='fwr6')) as fwr:
|
||||||
|
with self.firewall_policy() as fwp:
|
||||||
|
fwp_id = fwp['firewall_policy']['id']
|
||||||
|
attrs['id'] = fwp_id
|
||||||
|
with self.firewall(router_id=self.router_id,
|
||||||
|
firewall_policy_id=fwp_id) as fw:
|
||||||
|
# test insert when rule list is empty
|
||||||
|
fwr0_id = fwr[0]['firewall_rule']['id']
|
||||||
|
attrs['firewall_rules'].insert(0, fwr0_id)
|
||||||
|
attrs['firewall_list'].insert(0, fw['firewall']['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_with_no_firewall(self):
|
||||||
|
attrs = self._get_test_firewall_policy_attrs()
|
||||||
|
attrs['audited'] = False
|
||||||
|
attrs['firewall_list'] = []
|
||||||
|
with self.firewall_policy() as fwp:
|
||||||
|
fwp_id = fwp['firewall_policy']['id']
|
||||||
|
attrs['id'] = fwp_id
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr1'),
|
||||||
|
self.firewall_rule(name='fwr2'),
|
||||||
|
self.firewall_rule(name='fwr3')) as fr1:
|
||||||
|
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_with_firewall(self):
|
||||||
|
self._fake_router_edge_mapping()
|
||||||
|
|
||||||
|
attrs = self._get_test_firewall_policy_attrs()
|
||||||
|
attrs['audited'] = False
|
||||||
|
attrs['firewall_list'] = []
|
||||||
|
with self.firewall_policy() as fwp:
|
||||||
|
fwp_id = fwp['firewall_policy']['id']
|
||||||
|
attrs['id'] = fwp_id
|
||||||
|
with self.firewall(router_id=self.router_id,
|
||||||
|
firewall_policy_id=fwp_id) as fw:
|
||||||
|
attrs['firewall_list'].insert(0, fw['firewall']['id'])
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr1'),
|
||||||
|
self.firewall_rule(name='fwr2'),
|
||||||
|
self.firewall_rule(name='fwr3')) as fr1:
|
||||||
|
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)
|
||||||
@@ -474,13 +474,13 @@ class TestNiciraL3ExtensionManager(object):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
class TestNiciraL3NatTestCase(test_l3_plugin.L3NatDBIntTestCase,
|
class NiciraL3NatTest(test_l3_plugin.L3BaseForIntTests,
|
||||||
NiciraPluginV2TestCase):
|
NiciraPluginV2TestCase):
|
||||||
|
|
||||||
def _restore_l3_attribute_map(self):
|
def _restore_l3_attribute_map(self):
|
||||||
l3.RESOURCE_ATTRIBUTE_MAP = self._l3_attribute_map_bk
|
l3.RESOURCE_ATTRIBUTE_MAP = self._l3_attribute_map_bk
|
||||||
|
|
||||||
def setUp(self, plugin=None, ext_mgr=None):
|
def setUp(self, plugin=None, ext_mgr=None, service_plugins=None):
|
||||||
self._l3_attribute_map_bk = {}
|
self._l3_attribute_map_bk = {}
|
||||||
for item in l3.RESOURCE_ATTRIBUTE_MAP:
|
for item in l3.RESOURCE_ATTRIBUTE_MAP:
|
||||||
self._l3_attribute_map_bk[item] = (
|
self._l3_attribute_map_bk[item] = (
|
||||||
@@ -488,16 +488,18 @@ class TestNiciraL3NatTestCase(test_l3_plugin.L3NatDBIntTestCase,
|
|||||||
cfg.CONF.set_override('api_extensions_path', NVPEXT_PATH)
|
cfg.CONF.set_override('api_extensions_path', NVPEXT_PATH)
|
||||||
self.addCleanup(self._restore_l3_attribute_map)
|
self.addCleanup(self._restore_l3_attribute_map)
|
||||||
ext_mgr = ext_mgr or TestNiciraL3ExtensionManager()
|
ext_mgr = ext_mgr or TestNiciraL3ExtensionManager()
|
||||||
super(TestNiciraL3NatTestCase, self).setUp(
|
super(NiciraL3NatTest, self).setUp(
|
||||||
plugin=plugin, ext_mgr=ext_mgr)
|
plugin=plugin, ext_mgr=ext_mgr, service_plugins=service_plugins)
|
||||||
plugin_instance = NeutronManager.get_plugin()
|
plugin_instance = NeutronManager.get_plugin()
|
||||||
self._plugin_name = "%s.%s" % (
|
self._plugin_name = "%s.%s" % (
|
||||||
plugin_instance.__module__,
|
plugin_instance.__module__,
|
||||||
plugin_instance.__class__.__name__)
|
plugin_instance.__class__.__name__)
|
||||||
self._plugin_class = plugin_instance.__class__
|
self._plugin_class = plugin_instance.__class__
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
super(TestNiciraL3NatTestCase, self).tearDown()
|
class TestNiciraL3NatTestCase(NiciraL3NatTest,
|
||||||
|
test_l3_plugin.L3NatDBIntTestCase,
|
||||||
|
NiciraPluginV2TestCase):
|
||||||
|
|
||||||
def _create_l3_ext_network(self, vlan_id=None):
|
def _create_l3_ext_network(self, vlan_id=None):
|
||||||
name = 'l3_ext_net'
|
name = 'l3_ext_net'
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 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.
|
|
||||||
@@ -20,10 +20,20 @@ import copy
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from neutron.openstack.common import uuidutils
|
from neutron.openstack.common import uuidutils
|
||||||
|
from neutron.plugins.nicira.vshield.common import exceptions
|
||||||
|
|
||||||
|
|
||||||
class FakeVcns(object):
|
class FakeVcns(object):
|
||||||
|
|
||||||
|
errors = {
|
||||||
|
303: exceptions.ResourceRedirect,
|
||||||
|
400: exceptions.RequestBad,
|
||||||
|
403: exceptions.Forbidden,
|
||||||
|
404: exceptions.ResourceNotFound,
|
||||||
|
415: exceptions.MediaTypeUnsupport,
|
||||||
|
503: exceptions.ServiceUnavailable
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, unique_router_name=True):
|
def __init__(self, unique_router_name=True):
|
||||||
self._jobs = {}
|
self._jobs = {}
|
||||||
self._job_idx = 0
|
self._job_idx = 0
|
||||||
@@ -32,6 +42,12 @@ class FakeVcns(object):
|
|||||||
self._lswitches = {}
|
self._lswitches = {}
|
||||||
self._unique_router_name = unique_router_name
|
self._unique_router_name = unique_router_name
|
||||||
self._fake_nvpapi = None
|
self._fake_nvpapi = None
|
||||||
|
self.fake_firewall_dict = {}
|
||||||
|
self.temp_firewall = {
|
||||||
|
"firewallRules": {
|
||||||
|
"firewallRules": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def set_fake_nvpapi(self, fake_nvpapi):
|
def set_fake_nvpapi(self, fake_nvpapi):
|
||||||
self._fake_nvpapi = fake_nvpapi
|
self._fake_nvpapi = fake_nvpapi
|
||||||
@@ -243,7 +259,123 @@ class FakeVcns(object):
|
|||||||
response = ''
|
response = ''
|
||||||
return (header, response)
|
return (header, response)
|
||||||
|
|
||||||
|
def update_firewall(self, edge_id, fw_req):
|
||||||
|
self.fake_firewall_dict[edge_id] = fw_req
|
||||||
|
rules = self.fake_firewall_dict[edge_id][
|
||||||
|
'firewallRules']['firewallRules']
|
||||||
|
index = 10
|
||||||
|
for rule in rules:
|
||||||
|
rule['ruleId'] = index
|
||||||
|
index += 10
|
||||||
|
header = {'status': 204}
|
||||||
|
response = ""
|
||||||
|
return self.return_helper(header, response)
|
||||||
|
|
||||||
|
def delete_firewall(self, edge_id):
|
||||||
|
header = {'status': 404}
|
||||||
|
if edge_id in self.fake_firewall_dict:
|
||||||
|
header = {'status': 204}
|
||||||
|
del self.fake_firewall_dict[edge_id]
|
||||||
|
response = ""
|
||||||
|
return self.return_helper(header, response)
|
||||||
|
|
||||||
|
def update_firewall_rule(self, edge_id, vcns_rule_id, fwr_req):
|
||||||
|
if edge_id not in self.fake_firewall_dict:
|
||||||
|
raise Exception(_("Edge %s does not exist") % edge_id)
|
||||||
|
header = {'status': 404}
|
||||||
|
rules = self.fake_firewall_dict[edge_id][
|
||||||
|
'firewallRules']['firewallRules']
|
||||||
|
for rule in rules:
|
||||||
|
if rule['ruleId'] == int(vcns_rule_id):
|
||||||
|
header['status'] = 204
|
||||||
|
rule.update(fwr_req)
|
||||||
|
break
|
||||||
|
response = ""
|
||||||
|
return self.return_helper(header, response)
|
||||||
|
|
||||||
|
def delete_firewall_rule(self, edge_id, vcns_rule_id):
|
||||||
|
if edge_id not in self.fake_firewall_dict:
|
||||||
|
raise Exception(_("Edge %s does not exist") % edge_id)
|
||||||
|
header = {'status': 404}
|
||||||
|
rules = self.fake_firewall_dict[edge_id][
|
||||||
|
'firewallRules']['firewallRules']
|
||||||
|
for index in range(len(rules)):
|
||||||
|
if rules[index]['ruleId'] == int(vcns_rule_id):
|
||||||
|
header['status'] = 204
|
||||||
|
del rules[index]
|
||||||
|
break
|
||||||
|
response = ""
|
||||||
|
return self.return_helper(header, response)
|
||||||
|
|
||||||
|
def add_firewall_rule_above(self, edge_id, ref_vcns_rule_id, fwr_req):
|
||||||
|
if edge_id not in self.fake_firewall_dict:
|
||||||
|
raise Exception(_("Edge %s does not exist") % edge_id)
|
||||||
|
header = {'status': 404}
|
||||||
|
rules = self.fake_firewall_dict[edge_id][
|
||||||
|
'firewallRules']['firewallRules']
|
||||||
|
pre = 0
|
||||||
|
for index in range(len(rules)):
|
||||||
|
if rules[index]['ruleId'] == int(ref_vcns_rule_id):
|
||||||
|
rules.insert(index, fwr_req)
|
||||||
|
rules[index]['ruleId'] = (int(ref_vcns_rule_id) + pre) / 2
|
||||||
|
header = {
|
||||||
|
'status': 204,
|
||||||
|
'location': "https://host/api/4.0/edges/edge_id/firewall"
|
||||||
|
"/config/rules/%s" % rules[index]['ruleId']}
|
||||||
|
break
|
||||||
|
pre = int(rules[index]['ruleId'])
|
||||||
|
response = ""
|
||||||
|
return self.return_helper(header, response)
|
||||||
|
|
||||||
|
def add_firewall_rule(self, edge_id, fwr_req):
|
||||||
|
if edge_id not in self.fake_firewall_dict:
|
||||||
|
self.fake_firewall_dict[edge_id] = self.temp_firewall
|
||||||
|
rules = self.fake_firewall_dict[edge_id][
|
||||||
|
'firewallRules']['firewallRules']
|
||||||
|
rules.append(fwr_req)
|
||||||
|
index = len(rules)
|
||||||
|
rules[index - 1]['ruleId'] = index * 10
|
||||||
|
header = {
|
||||||
|
'status': 204,
|
||||||
|
'location': "https://host/api/4.0/edges/edge_id/firewall"
|
||||||
|
"/config/rules/%s" % rules[index - 1]['ruleId']}
|
||||||
|
response = ""
|
||||||
|
return self.return_helper(header, response)
|
||||||
|
|
||||||
|
def get_firewall(self, edge_id):
|
||||||
|
if edge_id not in self.fake_firewall_dict:
|
||||||
|
self.fake_firewall_dict[edge_id] = self.temp_firewall
|
||||||
|
header = {'status': 204}
|
||||||
|
response = self.fake_firewall_dict[edge_id]
|
||||||
|
return self.return_helper(header, response)
|
||||||
|
|
||||||
|
def get_firewall_rule(self, edge_id, vcns_rule_id):
|
||||||
|
if edge_id not in self.fake_firewall_dict:
|
||||||
|
raise Exception(_("Edge %s does not exist") % edge_id)
|
||||||
|
header = {'status': 404}
|
||||||
|
response = ""
|
||||||
|
rules = self.fake_firewall_dict[edge_id][
|
||||||
|
'firewallRules']['firewallRules']
|
||||||
|
for rule in rules:
|
||||||
|
if rule['ruleId'] == int(vcns_rule_id):
|
||||||
|
header['status'] = 204
|
||||||
|
response = rule
|
||||||
|
break
|
||||||
|
return self.return_helper(header, response)
|
||||||
|
|
||||||
|
def return_helper(self, header, response):
|
||||||
|
status = int(header['status'])
|
||||||
|
if 200 <= status <= 300:
|
||||||
|
return (header, response)
|
||||||
|
if status in self.errors:
|
||||||
|
cls = self.errors[status]
|
||||||
|
else:
|
||||||
|
cls = exceptions.VcnsApiException
|
||||||
|
raise cls(
|
||||||
|
status=status, header=header, uri='fake_url', response=response)
|
||||||
|
|
||||||
def reset_all(self):
|
def reset_all(self):
|
||||||
self._jobs.clear()
|
self._jobs.clear()
|
||||||
self._edges.clear()
|
self._edges.clear()
|
||||||
self._lswitches.clear()
|
self._lswitches.clear()
|
||||||
|
self.fake_firewall_dict = {}
|
||||||
|
|||||||
381
neutron/tests/unit/nicira/vshield/test_firewall_driver.py
Normal file
381
neutron/tests/unit/nicira/vshield/test_firewall_driver.py
Normal file
@@ -0,0 +1,381 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
#
|
||||||
|
# Copyright 2013 VMware, Inc
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
# @author: linb, VMware
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
import mock
|
||||||
|
import webob.exc
|
||||||
|
|
||||||
|
from neutron.common import config as n_config
|
||||||
|
from neutron import context
|
||||||
|
from neutron.db.firewall import firewall_db
|
||||||
|
from neutron.openstack.common import uuidutils
|
||||||
|
from neutron.plugins.nicira.vshield.common import exceptions as vcns_exc
|
||||||
|
from neutron.plugins.nicira.vshield import vcns_driver
|
||||||
|
from neutron.tests.unit.db.firewall import test_db_firewall
|
||||||
|
from neutron.tests.unit.nicira import get_fake_conf
|
||||||
|
from neutron.tests.unit.nicira import VCNS_NAME
|
||||||
|
from neutron.tests.unit.nicira.vshield import fake_vcns
|
||||||
|
|
||||||
|
|
||||||
|
_uuid = uuidutils.generate_uuid
|
||||||
|
|
||||||
|
VSE_ID = 'edge-1'
|
||||||
|
ROUTER_ID = '42f95450-5cc9-44e4-a744-1320e592a9d5'
|
||||||
|
|
||||||
|
VCNS_CONFIG_FILE = get_fake_conf("vcns.ini.test")
|
||||||
|
|
||||||
|
|
||||||
|
class VcnsDriverTestCase(test_db_firewall.FirewallPluginDbTestCase,
|
||||||
|
firewall_db.Firewall_db_mixin):
|
||||||
|
|
||||||
|
def vcns_firewall_patch(self):
|
||||||
|
instance = self.mock_vcns.start()
|
||||||
|
instance.return_value.update_firewall.side_effect = (
|
||||||
|
self.fc2.update_firewall)
|
||||||
|
instance.return_value.delete_firewall.side_effect = (
|
||||||
|
self.fc2.delete_firewall)
|
||||||
|
instance.return_value.update_firewall_rule.side_effect = (
|
||||||
|
self.fc2.update_firewall_rule)
|
||||||
|
instance.return_value.delete_firewall_rule.side_effect = (
|
||||||
|
self.fc2.delete_firewall_rule)
|
||||||
|
instance.return_value.add_firewall_rule_above.side_effect = (
|
||||||
|
self.fc2.add_firewall_rule_above)
|
||||||
|
instance.return_value.add_firewall_rule.side_effect = (
|
||||||
|
self.fc2.add_firewall_rule)
|
||||||
|
instance.return_value.get_firewall.side_effect = (
|
||||||
|
self.fc2.get_firewall)
|
||||||
|
instance.return_value.get_firewall_rule.side_effect = (
|
||||||
|
self.fc2.get_firewall_rule)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
|
||||||
|
n_config.parse(['--config-file', VCNS_CONFIG_FILE])
|
||||||
|
# mock vcns
|
||||||
|
self.fc2 = fake_vcns.FakeVcns(unique_router_name=False)
|
||||||
|
self.mock_vcns = mock.patch(VCNS_NAME, autospec=True)
|
||||||
|
self.vcns_firewall_patch()
|
||||||
|
|
||||||
|
self.nvp_service_plugin_callback = mock.Mock()
|
||||||
|
self.driver = vcns_driver.VcnsDriver(self.nvp_service_plugin_callback)
|
||||||
|
|
||||||
|
super(VcnsDriverTestCase, self).setUp()
|
||||||
|
self.addCleanup(self.fc2.reset_all)
|
||||||
|
self.addCleanup(self.mock_vcns.stop)
|
||||||
|
|
||||||
|
self.tenant_id = _uuid()
|
||||||
|
self.subnet_id = _uuid()
|
||||||
|
|
||||||
|
|
||||||
|
class TestEdgeFwDriver(VcnsDriverTestCase):
|
||||||
|
|
||||||
|
def _make_firewall_dict_with_rules(self, context, firewall_id):
|
||||||
|
fw = self.get_firewall(context, firewall_id)
|
||||||
|
fw_policy_id = fw['firewall_policy_id']
|
||||||
|
if fw_policy_id:
|
||||||
|
firewall_policy_db = self._get_firewall_policy(
|
||||||
|
context, fw_policy_id)
|
||||||
|
fw['firewall_rule_list'] = [
|
||||||
|
self._make_firewall_rule_dict(fw_rule_db)
|
||||||
|
for fw_rule_db in firewall_policy_db['firewall_rules']
|
||||||
|
]
|
||||||
|
|
||||||
|
return fw
|
||||||
|
|
||||||
|
def _compare_firewall_rule_lists(self, firewall_policy_id,
|
||||||
|
list1, list2):
|
||||||
|
for r1, r2 in zip(list1, list2):
|
||||||
|
rule = r1['firewall_rule']
|
||||||
|
rule['firewall_policy_id'] = firewall_policy_id
|
||||||
|
for k in rule:
|
||||||
|
self.assertEqual(rule[k], r2[k])
|
||||||
|
|
||||||
|
def test_create_and_get_firewall(self):
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
name = 'firewall'
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr1',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr2',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr3',
|
||||||
|
no_delete=True)) as fr:
|
||||||
|
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
|
||||||
|
with self.firewall_policy(firewall_rules=fw_rule_ids,
|
||||||
|
no_delete=True) as fwp:
|
||||||
|
fwp_id = fwp['firewall_policy']['id']
|
||||||
|
with self.firewall(name=name,
|
||||||
|
firewall_policy_id=fwp_id) as firewall:
|
||||||
|
fw_create = firewall['firewall']
|
||||||
|
fw_expect = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
self.driver.update_firewall(ctx, VSE_ID, fw_expect)
|
||||||
|
fw_get = self.driver.get_firewall(ctx, VSE_ID)
|
||||||
|
self._compare_firewall_rule_lists(
|
||||||
|
fwp_id, fw_get['firewall_rule_list'],
|
||||||
|
fw_expect['firewall_rule_list'])
|
||||||
|
|
||||||
|
def test_update_firewall_with_rules(self):
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
name = 'new_firewall'
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr1',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr2',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr3',
|
||||||
|
no_delete=True)) as fr:
|
||||||
|
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
|
||||||
|
with self.firewall_policy(firewall_rules=fw_rule_ids,
|
||||||
|
no_delete=True) as fwp:
|
||||||
|
fwp_id = fwp['firewall_policy']['id']
|
||||||
|
with self.firewall(name=name,
|
||||||
|
firewall_policy_id=fwp_id) as firewall:
|
||||||
|
fw_create = firewall['firewall']
|
||||||
|
fw_create = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
self.driver.update_firewall(ctx, VSE_ID, fw_create)
|
||||||
|
|
||||||
|
data = {'firewall_rule': {'name': name,
|
||||||
|
'source_port': '10:20',
|
||||||
|
'destination_port': '30:40'}}
|
||||||
|
self.new_update_request('firewall_rules', data,
|
||||||
|
fr[0]['firewall_rule']['id'])
|
||||||
|
fw_expect = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
self.driver.update_firewall(ctx, VSE_ID, fw_expect)
|
||||||
|
|
||||||
|
fw_get = self.driver.get_firewall(
|
||||||
|
ctx, VSE_ID)
|
||||||
|
self._compare_firewall_rule_lists(
|
||||||
|
fwp_id, fw_get['firewall_rule_list'],
|
||||||
|
fw_expect['firewall_rule_list'])
|
||||||
|
|
||||||
|
def test_delete_firewall(self):
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
name = 'firewall'
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr1',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr2',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr3',
|
||||||
|
no_delete=True)) as fr:
|
||||||
|
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
|
||||||
|
with self.firewall_policy(firewall_rules=fw_rule_ids,
|
||||||
|
no_delete=True) as fwp:
|
||||||
|
fwp_id = fwp['firewall_policy']['id']
|
||||||
|
with self.firewall(name=name,
|
||||||
|
firewall_policy_id=fwp_id) as firewall:
|
||||||
|
fw_create = firewall['firewall']
|
||||||
|
fw_expect = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
self.driver.update_firewall(ctx, VSE_ID, fw_expect)
|
||||||
|
self.driver.delete_firewall(ctx, VSE_ID)
|
||||||
|
fw_get = self.driver.get_firewall(
|
||||||
|
ctx, VSE_ID)
|
||||||
|
self.assertFalse(fw_get['firewall_rule_list'])
|
||||||
|
|
||||||
|
def test_update_firewall_rule(self):
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
name = 'new_firewall'
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr1',
|
||||||
|
no_delete=True)) as fr:
|
||||||
|
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
|
||||||
|
with self.firewall_policy(firewall_rules=fw_rule_ids,
|
||||||
|
no_delete=True) as fwp:
|
||||||
|
fwp_id = fwp['firewall_policy']['id']
|
||||||
|
with self.firewall(name=name,
|
||||||
|
firewall_policy_id=fwp_id) as firewall:
|
||||||
|
fw_create = firewall['firewall']
|
||||||
|
fw_create = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
self.driver.update_firewall(ctx, VSE_ID, fw_create)
|
||||||
|
|
||||||
|
data = {'firewall_rule': {'name': name,
|
||||||
|
'source_port': '10:20',
|
||||||
|
'destination_port': '30:40'}}
|
||||||
|
req = self.new_update_request(
|
||||||
|
'firewall_rules', data,
|
||||||
|
fr[0]['firewall_rule']['id'])
|
||||||
|
res = self.deserialize(self.fmt,
|
||||||
|
req.get_response(self.ext_api))
|
||||||
|
rule_expect = res['firewall_rule']
|
||||||
|
rule_expect['edge_id'] = VSE_ID
|
||||||
|
self.driver.update_firewall_rule(
|
||||||
|
ctx, rule_expect['id'], VSE_ID, rule_expect)
|
||||||
|
rule_get = self.driver.get_firewall_rule(
|
||||||
|
ctx, rule_expect['id'], VSE_ID)
|
||||||
|
for k, v in rule_get['firewall_rule'].items():
|
||||||
|
self.assertEqual(rule_expect[k], v)
|
||||||
|
|
||||||
|
def test_delete_firewall_rule(self):
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
name = 'new_firewall'
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr1',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr2',
|
||||||
|
no_delete=True)) as fr:
|
||||||
|
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
|
||||||
|
with self.firewall_policy(firewall_rules=fw_rule_ids,
|
||||||
|
no_delete=True) as fwp:
|
||||||
|
fwp_id = fwp['firewall_policy']['id']
|
||||||
|
with self.firewall(name=name,
|
||||||
|
firewall_policy_id=fwp_id) as firewall:
|
||||||
|
fw_create = firewall['firewall']
|
||||||
|
fw_create = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
self.driver.update_firewall(ctx, VSE_ID, fw_create)
|
||||||
|
|
||||||
|
fr[0]['firewall_rule']['edge_id'] = VSE_ID
|
||||||
|
self.driver.delete_firewall_rule(
|
||||||
|
ctx, fr[0]['firewall_rule']['id'],
|
||||||
|
VSE_ID)
|
||||||
|
self.assertRaises(vcns_exc.VcnsNotFound,
|
||||||
|
self.driver.get_firewall_rule,
|
||||||
|
ctx, fr[0]['firewall_rule']['id'],
|
||||||
|
VSE_ID)
|
||||||
|
|
||||||
|
def test_insert_rule(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) as firewall:
|
||||||
|
fw_create = firewall['firewall']
|
||||||
|
fw_create = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
self.driver.update_firewall(ctx, VSE_ID, fw_create)
|
||||||
|
with contextlib.nested(self.firewall_rule(name='fwr0',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr1',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr2',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr3',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr4',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(name='fwr5',
|
||||||
|
no_delete=True),
|
||||||
|
self.firewall_rule(
|
||||||
|
name='fwr6',
|
||||||
|
no_delete=True)) as fwr:
|
||||||
|
# test insert when rule list is empty
|
||||||
|
fwr0_id = fwr[0]['firewall_rule']['id']
|
||||||
|
self._rule_action('insert', fwp_id, fwr0_id,
|
||||||
|
insert_before=None,
|
||||||
|
insert_after=None,
|
||||||
|
expected_code=webob.exc.HTTPOk.code)
|
||||||
|
fw_update = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
self.driver.update_firewall(ctx, VSE_ID, fw_update)
|
||||||
|
# test insert at top of list above existing rule
|
||||||
|
fwr1_id = fwr[1]['firewall_rule']['id']
|
||||||
|
self._rule_action('insert', fwp_id, fwr1_id,
|
||||||
|
insert_before=fwr0_id,
|
||||||
|
insert_after=None,
|
||||||
|
expected_code=webob.exc.HTTPOk.code)
|
||||||
|
|
||||||
|
fw_expect = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
|
||||||
|
rule_info = {'firewall_rule_id': fwr1_id,
|
||||||
|
'insert_before': fwr0_id,
|
||||||
|
'insert_after': None}
|
||||||
|
rule = fwr[1]['firewall_rule']
|
||||||
|
self.driver.insert_rule(ctx, rule_info, VSE_ID, rule)
|
||||||
|
fw_get = self.driver.get_firewall(
|
||||||
|
ctx, VSE_ID)
|
||||||
|
self._compare_firewall_rule_lists(
|
||||||
|
fwp_id, fw_get['firewall_rule_list'],
|
||||||
|
fw_expect['firewall_rule_list'])
|
||||||
|
# test insert at bottom of list
|
||||||
|
fwr2_id = fwr[2]['firewall_rule']['id']
|
||||||
|
self._rule_action('insert', fwp_id, fwr2_id,
|
||||||
|
insert_before=None,
|
||||||
|
insert_after=fwr0_id,
|
||||||
|
expected_code=webob.exc.HTTPOk.code)
|
||||||
|
fw_expect = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
|
||||||
|
rule_info = {'firewall_rule_id': fwr2_id,
|
||||||
|
'insert_before': None,
|
||||||
|
'insert_after': fwr0_id}
|
||||||
|
rule = fwr[2]['firewall_rule']
|
||||||
|
self.driver.insert_rule(ctx, rule_info, VSE_ID, rule)
|
||||||
|
fw_get = self.driver.get_firewall(
|
||||||
|
ctx, VSE_ID)
|
||||||
|
self._compare_firewall_rule_lists(
|
||||||
|
fwp_id, fw_get['firewall_rule_list'],
|
||||||
|
fw_expect['firewall_rule_list'])
|
||||||
|
# test insert in the middle of the list using
|
||||||
|
# insert_before
|
||||||
|
fwr3_id = fwr[3]['firewall_rule']['id']
|
||||||
|
self._rule_action('insert', fwp_id, fwr3_id,
|
||||||
|
insert_before=fwr2_id,
|
||||||
|
insert_after=None,
|
||||||
|
expected_code=webob.exc.HTTPOk.code)
|
||||||
|
fw_expect = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
|
||||||
|
rule_info = {'firewall_rule_id': fwr3_id,
|
||||||
|
'insert_before': fwr2_id,
|
||||||
|
'insert_after': None}
|
||||||
|
rule = fwr[3]['firewall_rule']
|
||||||
|
self.driver.insert_rule(ctx, rule_info, VSE_ID, rule)
|
||||||
|
fw_get = self.driver.get_firewall(
|
||||||
|
ctx, VSE_ID)
|
||||||
|
self._compare_firewall_rule_lists(
|
||||||
|
fwp_id, fw_get['firewall_rule_list'],
|
||||||
|
fw_expect['firewall_rule_list'])
|
||||||
|
# test insert in the middle of the list using
|
||||||
|
# insert_after
|
||||||
|
fwr4_id = fwr[4]['firewall_rule']['id']
|
||||||
|
self._rule_action('insert', fwp_id, fwr4_id,
|
||||||
|
insert_before=None,
|
||||||
|
insert_after=fwr3_id,
|
||||||
|
expected_code=webob.exc.HTTPOk.code)
|
||||||
|
fw_expect = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
|
||||||
|
rule_info = {'firewall_rule_id': fwr4_id,
|
||||||
|
'insert_before': None,
|
||||||
|
'insert_after': fwr3_id}
|
||||||
|
rule = fwr[4]['firewall_rule']
|
||||||
|
self.driver.insert_rule(ctx, rule_info, VSE_ID, rule)
|
||||||
|
fw_get = self.driver.get_firewall(
|
||||||
|
ctx, VSE_ID)
|
||||||
|
self._compare_firewall_rule_lists(
|
||||||
|
fwp_id, fw_get['firewall_rule_list'],
|
||||||
|
fw_expect['firewall_rule_list'])
|
||||||
|
# test insert when both insert_before and
|
||||||
|
# insert_after are set
|
||||||
|
fwr5_id = fwr[5]['firewall_rule']['id']
|
||||||
|
self._rule_action('insert', fwp_id, fwr5_id,
|
||||||
|
insert_before=fwr4_id,
|
||||||
|
insert_after=fwr4_id,
|
||||||
|
expected_code=webob.exc.HTTPOk.code)
|
||||||
|
fw_expect = self._make_firewall_dict_with_rules(
|
||||||
|
ctx, fw_create['id'])
|
||||||
|
|
||||||
|
rule_info = {'firewall_rule_id': fwr5_id,
|
||||||
|
'insert_before': fwr4_id,
|
||||||
|
'insert_after': fwr4_id}
|
||||||
|
rule = fwr[5]['firewall_rule']
|
||||||
|
self.driver.insert_rule(ctx, rule_info, VSE_ID, rule)
|
||||||
|
fw_get = self.driver.get_firewall(
|
||||||
|
ctx, VSE_ID)
|
||||||
|
self._compare_firewall_rule_lists(
|
||||||
|
fwp_id, fw_get['firewall_rule_list'],
|
||||||
|
fw_expect['firewall_rule_list'])
|
||||||
@@ -1653,14 +1653,15 @@ class L3AgentDbTestCaseBase(L3NatTestCaseMixin):
|
|||||||
|
|
||||||
class L3BaseForIntTests(test_db_plugin.NeutronDbPluginV2TestCase):
|
class L3BaseForIntTests(test_db_plugin.NeutronDbPluginV2TestCase):
|
||||||
|
|
||||||
def setUp(self, plugin=None, ext_mgr=None):
|
def setUp(self, plugin=None, ext_mgr=None, service_plugins=None):
|
||||||
test_config['plugin_name_v2'] = (
|
test_config['plugin_name_v2'] = (
|
||||||
'neutron.tests.unit.test_l3_plugin.TestL3NatIntPlugin')
|
'neutron.tests.unit.test_l3_plugin.TestL3NatIntPlugin')
|
||||||
# for these tests we need to enable overlapping ips
|
# for these tests we need to enable overlapping ips
|
||||||
cfg.CONF.set_default('allow_overlapping_ips', True)
|
cfg.CONF.set_default('allow_overlapping_ips', True)
|
||||||
ext_mgr = ext_mgr or L3TestExtensionManager()
|
ext_mgr = ext_mgr or L3TestExtensionManager()
|
||||||
test_config['extension_manager'] = ext_mgr
|
test_config['extension_manager'] = ext_mgr
|
||||||
super(L3BaseForIntTests, self).setUp(plugin=plugin, ext_mgr=ext_mgr)
|
super(L3BaseForIntTests, self).setUp(plugin=plugin, ext_mgr=ext_mgr,
|
||||||
|
service_plugins=service_plugins)
|
||||||
|
|
||||||
# Set to None to reload the drivers
|
# Set to None to reload the drivers
|
||||||
notifier_api._drivers = None
|
notifier_api._drivers = None
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ class RouterServiceInsertionTestPlugin(
|
|||||||
db_base_plugin_v2.NeutronDbPluginV2):
|
db_base_plugin_v2.NeutronDbPluginV2):
|
||||||
|
|
||||||
supported_extension_aliases = [
|
supported_extension_aliases = [
|
||||||
"router", "router-service-type",
|
"router", "router-service-type", "routed-service-insertion",
|
||||||
"routed-service-insertion", "service-type", "lbaas"
|
"service-type", "lbaas"
|
||||||
]
|
]
|
||||||
|
|
||||||
def create_router(self, context, router):
|
def create_router(self, context, router):
|
||||||
@@ -104,7 +104,7 @@ class RouterServiceInsertionTestPlugin(
|
|||||||
o = method(context, id, fields)
|
o = method(context, id, fields)
|
||||||
if fields is None or rsi.ROUTER_ID in fields:
|
if fields is None or rsi.ROUTER_ID in fields:
|
||||||
rsbind = self._get_resource_router_id_binding(
|
rsbind = self._get_resource_router_id_binding(
|
||||||
context, id, model)
|
context, model, id)
|
||||||
if rsbind:
|
if rsbind:
|
||||||
o[rsi.ROUTER_ID] = rsbind['router_id']
|
o[rsi.ROUTER_ID] = rsbind['router_id']
|
||||||
return o
|
return o
|
||||||
@@ -116,7 +116,7 @@ class RouterServiceInsertionTestPlugin(
|
|||||||
method_name)
|
method_name)
|
||||||
method(context, id)
|
method(context, id)
|
||||||
self._delete_resource_router_id_binding(context, id, model)
|
self._delete_resource_router_id_binding(context, id, model)
|
||||||
if self._get_resource_router_id_binding(context, id, model):
|
if self._get_resource_router_id_binding(context, model, id):
|
||||||
raise Exception("{0}-router binding is not deleted".format(res))
|
raise Exception("{0}-router binding is not deleted".format(res))
|
||||||
|
|
||||||
def create_pool(self, context, pool):
|
def create_pool(self, context, pool):
|
||||||
|
|||||||
Reference in New Issue
Block a user