Remove NSX 'service' plugin
Following the spin-off for Neutron advanced services, this plugin has become non-functional. This patch removes the plugin, the service drivers, the database models which kept tracking of resource associations, exceptions, and obviously unit tests. As there were some extensions which were leveraged only by this plugin, they are being removed as well. In particular, one of these extensions, 'routed-service-insertion' was in the neutron.extensions package rather than neutron.plugins.vmware package. This was for historical reasons. As no other plugin is using this extension, it is being removed as well with this patch. By removing this plugin vmware the temporary skips applied to neutron unit tests can be lifted. This patch does this. Closes-Bug: #1403585 Change-Id: I0717f955b0f787c2951cb9db44ea5decc5d3dff0
This commit is contained in:
parent
a8234739a2
commit
5981b9c116
|
@ -0,0 +1,89 @@
|
|||
# Copyright 2014 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.
|
||||
#
|
||||
|
||||
"""scrap_nsx_adv_svcs_models
|
||||
|
||||
Revision ID: 57086602ca0a
|
||||
Revises: 28c0ffb8ebbd
|
||||
Create Date: 2014-12-17 22:33:30.465392
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '57086602ca0a'
|
||||
down_revision = '28c0ffb8ebbd'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.drop_table('vcns_edge_pool_bindings')
|
||||
op.drop_table('vcns_firewall_rule_bindings')
|
||||
op.drop_table('vcns_edge_monitor_bindings')
|
||||
op.drop_table('vcns_edge_vip_bindings')
|
||||
op.drop_table(u'routerservicetypebindings')
|
||||
op.drop_table(u'servicerouterbindings')
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.create_table(
|
||||
'servicerouterbindings',
|
||||
sa.Column('resource_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('resource_type', sa.String(length=36), nullable=False),
|
||||
sa.Column('router_id', sa.String(length=36), nullable=False),
|
||||
sa.ForeignKeyConstraint(['router_id'], [u'routers.id'],
|
||||
name='servicerouterbindings_ibfk_1'),
|
||||
sa.PrimaryKeyConstraint('resource_id', 'resource_type'))
|
||||
op.create_table(
|
||||
'routerservicetypebindings',
|
||||
sa.Column('router_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('service_type_id', sa.String(length=36), nullable=False),
|
||||
sa.ForeignKeyConstraint(['router_id'], ['routers.id'],
|
||||
name='routerservicetypebindings_ibfk_1'),
|
||||
sa.PrimaryKeyConstraint(u'router_id'))
|
||||
op.create_table(
|
||||
'vcns_edge_vip_bindings',
|
||||
sa.Column('vip_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('edge_id', sa.String(length=36), nullable=True),
|
||||
sa.Column('vip_vseid', sa.String(length=36), nullable=True),
|
||||
sa.Column('app_profileid', sa.String(length=36), nullable=True),
|
||||
sa.ForeignKeyConstraint(['vip_id'], ['vips.id'],
|
||||
name='vcns_edge_vip_bindings_ibfk_1'),
|
||||
sa.PrimaryKeyConstraint('vip_id'))
|
||||
op.create_table(
|
||||
'vcns_edge_monitor_bindings',
|
||||
sa.Column('monitor_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('edge_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('monitor_vseid', sa.String(length=36), nullable=True),
|
||||
sa.ForeignKeyConstraint(['monitor_id'], ['healthmonitors.id'],
|
||||
name='vcns_edge_monitor_bindings_ibfk_1'),
|
||||
sa.PrimaryKeyConstraint('monitor_id', 'edge_id'))
|
||||
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'],
|
||||
name='vcns_firewall_rule_bindings_ibfk_1'),
|
||||
sa.PrimaryKeyConstraint('rule_id', u'edge_id'))
|
||||
op.create_table(
|
||||
'vcns_edge_pool_bindings',
|
||||
sa.Column('pool_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('edge_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('pool_vseid', sa.String(length=36), nullable=True),
|
||||
sa.ForeignKeyConstraint(['pool_id'], ['pools.id'],
|
||||
name='vcns_edge_pool_bindings_ibfk_1'),
|
||||
sa.PrimaryKeyConstraint('pool_id', 'edge_id'))
|
|
@ -1 +1 @@
|
|||
28c0ffb8ebbd
|
||||
57086602ca0a
|
||||
|
|
|
@ -40,8 +40,6 @@ from neutron.db import models_v2 # noqa
|
|||
from neutron.db import portbindings_db # noqa
|
||||
from neutron.db import portsecurity_db # noqa
|
||||
from neutron.db import quota_db # noqa
|
||||
from neutron.db import routedserviceinsertion_db # noqa
|
||||
from neutron.db import routerservicetype_db # noqa
|
||||
from neutron.db import securitygroups_db # noqa
|
||||
from neutron.db import servicetype_db # noqa
|
||||
from neutron.plugins.bigswitch.db import consistency_db # noqa
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
# 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 sqlalchemy as sa
|
||||
from sqlalchemy import event
|
||||
|
||||
from neutron.common import exceptions as qexception
|
||||
from neutron.db import model_base
|
||||
from neutron.extensions import routedserviceinsertion as rsi
|
||||
|
||||
|
||||
class ServiceRouterBinding(model_base.BASEV2):
|
||||
resource_id = sa.Column(sa.String(36),
|
||||
primary_key=True)
|
||||
resource_type = sa.Column(sa.String(36),
|
||||
primary_key=True)
|
||||
router_id = sa.Column(sa.String(36),
|
||||
sa.ForeignKey('routers.id'),
|
||||
nullable=False)
|
||||
|
||||
|
||||
class AttributeException(qexception.NeutronException):
|
||||
message = _("Resource type '%(resource_type)s' is longer "
|
||||
"than %(maxlen)d characters")
|
||||
|
||||
|
||||
@event.listens_for(ServiceRouterBinding.resource_type, 'set', retval=True)
|
||||
def validate_resource_type(target, value, oldvalue, initiator):
|
||||
"""Make sure the resource type fit the resource_type column."""
|
||||
maxlen = ServiceRouterBinding.resource_type.property.columns[0].type.length
|
||||
if len(value) > maxlen:
|
||||
raise AttributeException(resource_type=value, maxlen=maxlen)
|
||||
return value
|
||||
|
||||
|
||||
class RoutedServiceInsertionDbMixin(object):
|
||||
"""Mixin class to add router service insertion."""
|
||||
|
||||
def _process_create_resource_router_id(self, context, resource, model):
|
||||
with context.session.begin(subtransactions=True):
|
||||
db = ServiceRouterBinding(
|
||||
resource_id=resource['id'],
|
||||
resource_type=model.__tablename__,
|
||||
router_id=resource[rsi.ROUTER_ID])
|
||||
context.session.add(db)
|
||||
return self._make_resource_router_id_dict(db, model)
|
||||
|
||||
def _extend_resource_router_id_dict(self, context, resource, model):
|
||||
binding = self._get_resource_router_id_binding(
|
||||
context, resource['resource_id'], model)
|
||||
resource[rsi.ROUTER_ID] = binding['router_id']
|
||||
|
||||
def _get_resource_router_id_binding(self, context, model,
|
||||
resource_id=None,
|
||||
router_id=None):
|
||||
query = self._model_query(context, ServiceRouterBinding)
|
||||
query = query.filter(
|
||||
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()
|
||||
|
||||
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,
|
||||
fields=None):
|
||||
resource = {'resource_id': resource_router_binding['resource_id'],
|
||||
'resource_type': model.__tablename__,
|
||||
rsi.ROUTER_ID: resource_router_binding[rsi.ROUTER_ID]}
|
||||
return self._fields(resource, fields)
|
||||
|
||||
def _delete_resource_router_id_binding(self, context, resource_id, model):
|
||||
with context.session.begin(subtransactions=True):
|
||||
binding = self._get_resource_router_id_binding(
|
||||
context, model, resource_id=resource_id)
|
||||
if binding:
|
||||
context.session.delete(binding)
|
|
@ -1,55 +0,0 @@
|
|||
# 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 sqlalchemy as sa
|
||||
|
||||
from neutron.db import model_base
|
||||
from neutron.extensions import routerservicetype as rst
|
||||
|
||||
|
||||
class RouterServiceTypeBinding(model_base.BASEV2):
|
||||
router_id = sa.Column(sa.String(36),
|
||||
sa.ForeignKey('routers.id', ondelete="CASCADE"),
|
||||
primary_key=True)
|
||||
service_type_id = sa.Column(sa.String(36),
|
||||
nullable=False)
|
||||
|
||||
|
||||
class RouterServiceTypeDbMixin(object):
|
||||
"""Mixin class to add router service type."""
|
||||
|
||||
def _process_create_router_service_type_id(self, context, router):
|
||||
with context.session.begin(subtransactions=True):
|
||||
db = RouterServiceTypeBinding(
|
||||
router_id=router['id'],
|
||||
service_type_id=router[rst.SERVICE_TYPE_ID])
|
||||
context.session.add(db)
|
||||
return self._make_router_service_type_id_dict(db)
|
||||
|
||||
def _extend_router_service_type_id_dict(self, context, router):
|
||||
rsbind = self._get_router_service_type_id_binding(
|
||||
context, router['id'])
|
||||
if rsbind:
|
||||
router[rst.SERVICE_TYPE_ID] = rsbind['service_type_id']
|
||||
|
||||
def _get_router_service_type_id_binding(self, context, router_id):
|
||||
query = self._model_query(context, RouterServiceTypeBinding)
|
||||
query = query.filter(
|
||||
RouterServiceTypeBinding.router_id == router_id)
|
||||
return query.first()
|
||||
|
||||
def _make_router_service_type_id_dict(self, router_service_type):
|
||||
res = {'router_id': router_service_type['router_id'],
|
||||
'service_type_id': router_service_type[rst.SERVICE_TYPE_ID]}
|
||||
return self._fields(res, None)
|
|
@ -1,69 +0,0 @@
|
|||
# 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.
|
||||
|
||||
|
||||
ROUTER_ID = 'router_id'
|
||||
EXTENDED_ATTRIBUTES_2_0 = {
|
||||
'vips': {
|
||||
ROUTER_ID: {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:uuid_or_none': None},
|
||||
'default': None, 'is_visible': True},
|
||||
},
|
||||
'pools': {
|
||||
ROUTER_ID: {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:uuid_or_none': None},
|
||||
'default': None, 'is_visible': True},
|
||||
},
|
||||
'health_monitors': {
|
||||
ROUTER_ID: {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:uuid_or_none': None},
|
||||
'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},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Routedserviceinsertion(object):
|
||||
"""Extension class supporting routed service type."""
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return "Routed Service Insertion"
|
||||
|
||||
@classmethod
|
||||
def get_alias(cls):
|
||||
return "routed-service-insertion"
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return "Provides routed service type"
|
||||
|
||||
@classmethod
|
||||
def get_namespace(cls):
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
return "2013-01-29T00:00:00-00:00"
|
||||
|
||||
def get_extended_resources(self, version):
|
||||
if version == "2.0":
|
||||
return EXTENDED_ATTRIBUTES_2_0
|
||||
else:
|
||||
return {}
|
|
@ -76,20 +76,6 @@ class ServiceOverQuota(n_exc.Conflict):
|
|||
message = _("Quota exceeded for Vcns resource: %(overs)s: %(err_msg)s")
|
||||
|
||||
|
||||
class RouterInUseByLBService(n_exc.InUse):
|
||||
message = _("Router %(router_id)s is in use by Loadbalancer Service "
|
||||
"%(vip_id)s")
|
||||
|
||||
|
||||
class RouterInUseByFWService(n_exc.InUse):
|
||||
message = _("Router %(router_id)s is in use by firewall Service "
|
||||
"%(firewall_id)s")
|
||||
|
||||
|
||||
class VcnsDriverException(NsxPluginException):
|
||||
message = _("Error happened in NSX VCNS Driver: %(err_msg)s")
|
||||
|
||||
|
||||
class ServiceClusterUnavailable(NsxPluginException):
|
||||
message = _("Service cluster: '%(cluster_id)s' is unavailable. Please, "
|
||||
"check NSX setup and/or configuration")
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
# 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.
|
||||
#
|
||||
|
||||
from neutron.db import l3_dvr_db
|
||||
from neutron.plugins.vmware.extensions import servicerouter
|
||||
|
||||
|
||||
class ServiceRouter_mixin(l3_dvr_db.L3_NAT_with_dvr_db_mixin):
|
||||
"""Mixin class to enable service router support."""
|
||||
|
||||
extra_attributes = (
|
||||
l3_dvr_db.L3_NAT_with_dvr_db_mixin.extra_attributes + [{
|
||||
'name': servicerouter.SERVICE_ROUTER,
|
||||
'default': False
|
||||
}])
|
|
@ -14,13 +14,8 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from sqlalchemy.orm import exc
|
||||
|
||||
from neutron.openstack.common import log as logging
|
||||
from neutron.plugins.vmware.common import exceptions as nsx_exc
|
||||
from neutron.plugins.vmware.dbexts import vcns_models
|
||||
from neutron.plugins.vmware.vshield.common import (
|
||||
exceptions as vcns_exc)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -55,148 +50,3 @@ def delete_vcns_router_binding(session, router_id):
|
|||
binding = (session.query(vcns_models.VcnsRouterBinding).
|
||||
filter_by(router_id=router_id).one())
|
||||
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, edge_id):
|
||||
with session.begin(subtransactions=True):
|
||||
if not (session.query(vcns_models.VcnsEdgeFirewallRuleBinding).
|
||||
filter_by(rule_id=id, edge_id=edge_id).delete()):
|
||||
msg = _("Rule Resource binding with id:%s not found!") % id
|
||||
raise nsx_exc.NsxPluginException(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 nsx_exc.NsxPluginException(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()
|
||||
|
||||
|
||||
def add_vcns_edge_vip_binding(session, map_info):
|
||||
with session.begin(subtransactions=True):
|
||||
binding = vcns_models.VcnsEdgeVipBinding(
|
||||
vip_id=map_info['vip_id'],
|
||||
edge_id=map_info['edge_id'],
|
||||
vip_vseid=map_info['vip_vseid'],
|
||||
app_profileid=map_info['app_profileid'])
|
||||
session.add(binding)
|
||||
|
||||
return binding
|
||||
|
||||
|
||||
def get_vcns_edge_vip_binding(session, id):
|
||||
with session.begin(subtransactions=True):
|
||||
try:
|
||||
qry = session.query(vcns_models.VcnsEdgeVipBinding)
|
||||
return qry.filter_by(vip_id=id).one()
|
||||
except exc.NoResultFound:
|
||||
msg = _("VIP Resource binding with id:%s not found!") % id
|
||||
LOG.exception(msg)
|
||||
raise vcns_exc.VcnsNotFound(
|
||||
resource='router_service_binding', msg=msg)
|
||||
|
||||
|
||||
def delete_vcns_edge_vip_binding(session, id):
|
||||
with session.begin(subtransactions=True):
|
||||
qry = session.query(vcns_models.VcnsEdgeVipBinding)
|
||||
if not qry.filter_by(vip_id=id).delete():
|
||||
msg = _("VIP Resource binding with id:%s not found!") % id
|
||||
LOG.exception(msg)
|
||||
raise nsx_exc.NsxPluginException(err_msg=msg)
|
||||
|
||||
|
||||
def add_vcns_edge_pool_binding(session, map_info):
|
||||
with session.begin(subtransactions=True):
|
||||
binding = vcns_models.VcnsEdgePoolBinding(
|
||||
pool_id=map_info['pool_id'],
|
||||
edge_id=map_info['edge_id'],
|
||||
pool_vseid=map_info['pool_vseid'])
|
||||
session.add(binding)
|
||||
|
||||
return binding
|
||||
|
||||
|
||||
def get_vcns_edge_pool_binding(session, id, edge_id):
|
||||
with session.begin(subtransactions=True):
|
||||
return (session.query(vcns_models.VcnsEdgePoolBinding).
|
||||
filter_by(pool_id=id, edge_id=edge_id).first())
|
||||
|
||||
|
||||
def get_vcns_edge_pool_binding_by_vseid(session, edge_id, pool_vseid):
|
||||
with session.begin(subtransactions=True):
|
||||
try:
|
||||
qry = session.query(vcns_models.VcnsEdgePoolBinding)
|
||||
binding = qry.filter_by(edge_id=edge_id,
|
||||
pool_vseid=pool_vseid).one()
|
||||
except exc.NoResultFound:
|
||||
msg = (_("Pool Resource binding with edge_id:%(edge_id)s "
|
||||
"pool_vseid:%(pool_vseid)s not found!") %
|
||||
{'edge_id': edge_id, 'pool_vseid': pool_vseid})
|
||||
LOG.exception(msg)
|
||||
raise nsx_exc.NsxPluginException(err_msg=msg)
|
||||
return binding
|
||||
|
||||
|
||||
def delete_vcns_edge_pool_binding(session, id, edge_id):
|
||||
with session.begin(subtransactions=True):
|
||||
qry = session.query(vcns_models.VcnsEdgePoolBinding)
|
||||
if not qry.filter_by(pool_id=id, edge_id=edge_id).delete():
|
||||
msg = _("Pool Resource binding with id:%s not found!") % id
|
||||
LOG.exception(msg)
|
||||
raise nsx_exc.NsxPluginException(err_msg=msg)
|
||||
|
||||
|
||||
def add_vcns_edge_monitor_binding(session, map_info):
|
||||
with session.begin(subtransactions=True):
|
||||
binding = vcns_models.VcnsEdgeMonitorBinding(
|
||||
monitor_id=map_info['monitor_id'],
|
||||
edge_id=map_info['edge_id'],
|
||||
monitor_vseid=map_info['monitor_vseid'])
|
||||
session.add(binding)
|
||||
|
||||
return binding
|
||||
|
||||
|
||||
def get_vcns_edge_monitor_binding(session, id, edge_id):
|
||||
with session.begin(subtransactions=True):
|
||||
return (session.query(vcns_models.VcnsEdgeMonitorBinding).
|
||||
filter_by(monitor_id=id, edge_id=edge_id).first())
|
||||
|
||||
|
||||
def delete_vcns_edge_monitor_binding(session, id, edge_id):
|
||||
with session.begin(subtransactions=True):
|
||||
qry = session.query(vcns_models.VcnsEdgeMonitorBinding)
|
||||
if not qry.filter_by(monitor_id=id, edge_id=edge_id).delete():
|
||||
msg = _("Monitor Resource binding with id:%s not found!") % id
|
||||
LOG.exception(msg)
|
||||
raise nsx_exc.NsxPluginException(err_msg=msg)
|
||||
|
|
|
@ -35,60 +35,3 @@ class VcnsRouterBinding(model_base.BASEV2, models_v2.HasStatusDescription):
|
|||
nullable=True)
|
||||
lswitch_id = sa.Column(sa.String(36),
|
||||
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),
|
||||
# TODO(dougw) unbreak this link
|
||||
#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))
|
||||
|
||||
|
||||
class VcnsEdgePoolBinding(model_base.BASEV2):
|
||||
"""Represents the mapping between neutron pool and Edge pool."""
|
||||
|
||||
__tablename__ = 'vcns_edge_pool_bindings'
|
||||
|
||||
pool_id = sa.Column(sa.String(36),
|
||||
# TODO(dougw) unbreak this link
|
||||
#sa.ForeignKey("pools.id", ondelete="CASCADE"),
|
||||
primary_key=True)
|
||||
edge_id = sa.Column(sa.String(36), primary_key=True)
|
||||
pool_vseid = sa.Column(sa.String(36))
|
||||
|
||||
|
||||
class VcnsEdgeVipBinding(model_base.BASEV2):
|
||||
"""Represents the mapping between neutron vip and Edge vip."""
|
||||
|
||||
__tablename__ = 'vcns_edge_vip_bindings'
|
||||
|
||||
vip_id = sa.Column(sa.String(36),
|
||||
# TODO(dougw) unbreak this link
|
||||
#sa.ForeignKey("vips.id", ondelete="CASCADE"),
|
||||
primary_key=True)
|
||||
edge_id = sa.Column(sa.String(36))
|
||||
vip_vseid = sa.Column(sa.String(36))
|
||||
app_profileid = sa.Column(sa.String(36))
|
||||
|
||||
|
||||
class VcnsEdgeMonitorBinding(model_base.BASEV2):
|
||||
"""Represents the mapping between neutron monitor and Edge monitor."""
|
||||
|
||||
__tablename__ = 'vcns_edge_monitor_bindings'
|
||||
|
||||
monitor_id = sa.Column(sa.String(36),
|
||||
# TODO(dougw) unbreak this link
|
||||
#sa.ForeignKey("healthmonitors.id",
|
||||
# ondelete="CASCADE"),
|
||||
primary_key=True)
|
||||
edge_id = sa.Column(sa.String(36), primary_key=True)
|
||||
monitor_vseid = sa.Column(sa.String(36))
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
# 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.
|
||||
#
|
||||
|
||||
from neutron.api import extensions
|
||||
from neutron.api.v2 import attributes
|
||||
|
||||
|
||||
SERVICE_ROUTER = 'service_router'
|
||||
EXTENDED_ATTRIBUTES_2_0 = {
|
||||
'routers': {
|
||||
SERVICE_ROUTER: {'allow_post': True, 'allow_put': False,
|
||||
'convert_to': attributes.convert_to_boolean,
|
||||
'default': False, 'is_visible': True},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Servicerouter(extensions.ExtensionDescriptor):
|
||||
"""Extension class supporting advanced service router."""
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return "Service Router"
|
||||
|
||||
@classmethod
|
||||
def get_alias(cls):
|
||||
return "service-router"
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return "Provides service router."
|
||||
|
||||
@classmethod
|
||||
def get_namespace(cls):
|
||||
return "http://docs.openstack.org/ext/service-router/api/v1.0"
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
return "2013-08-08T00:00:00-00:00"
|
||||
|
||||
def get_extended_resources(self, version):
|
||||
if version == "2.0":
|
||||
return EXTENDED_ATTRIBUTES_2_0
|
||||
else:
|
||||
return {}
|
|
@ -16,7 +16,5 @@
|
|||
#
|
||||
|
||||
from neutron.plugins.vmware.plugins import base
|
||||
from neutron.plugins.vmware.plugins import service
|
||||
|
||||
NsxPlugin = base.NsxPluginV2
|
||||
NsxServicePlugin = service.NsxAdvancedPlugin
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,352 +0,0 @@
|
|||
# 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.
|
||||
|
||||
from oslo.utils import excutils
|
||||
|
||||
from neutron.db import db_base_plugin_v2
|
||||
from neutron.i18n import _LE
|
||||
from neutron.openstack.common import log as logging
|
||||
from neutron.plugins.common import constants
|
||||
from neutron.plugins.vmware.dbexts import vcns_db
|
||||
from neutron.plugins.vmware.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.VcnsBadRequest(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.VcnsBadRequest(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:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to get firewall with edge "
|
||||
"id: %s"), edge_id)
|
||||
|
||||
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:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to get firewall rule: %(rule_id)s "
|
||||
"with edge_id: %(edge_id)s"), {
|
||||
'rule_id': id,
|
||||
'edge_id': edge_id})
|
||||
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:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to update firewall "
|
||||
"with edge_id: %s"), edge_id)
|
||||
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:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to delete firewall "
|
||||
"with edge_id:%s"), edge_id)
|
||||
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(_LE("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(_LE("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, edge_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(_LE("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(_LE("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(_LE("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.VcnsBadRequest(resource='firewall_rule', msg=msg)
|
|
@ -1,153 +0,0 @@
|
|||
# Copyright 2014 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.
|
||||
|
||||
from oslo.utils import excutils
|
||||
|
||||
from neutron.i18n import _LE, _LW
|
||||
from neutron.openstack.common import log as logging
|
||||
from neutron.plugins.vmware.vshield.common import (
|
||||
exceptions as vcns_exc)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
ENCRYPTION_ALGORITHM_MAP = {
|
||||
'3des': '3des',
|
||||
'aes-128': 'aes',
|
||||
'aes-256': 'aes256'
|
||||
}
|
||||
|
||||
PFS_MAP = {
|
||||
'group2': 'dh2',
|
||||
'group5': 'dh5'}
|
||||
|
||||
TRANSFORM_PROTOCOL_ALLOWED = ('esp',)
|
||||
|
||||
ENCAPSULATION_MODE_ALLOWED = ('tunnel',)
|
||||
|
||||
|
||||
class EdgeIPsecVpnDriver():
|
||||
|
||||
"""Driver APIs for Edge IPsec VPN bulk configuration."""
|
||||
|
||||
def _check_ikepolicy_ipsecpolicy_allowed(self, ikepolicy, ipsecpolicy):
|
||||
"""Check whether ikepolicy and ipsecpolicy are allowed on vshield edge.
|
||||
|
||||
Some IPsec VPN configurations and features are configured by default or
|
||||
not supported on vshield edge.
|
||||
|
||||
"""
|
||||
# Check validation of IKEPolicy.
|
||||
if ikepolicy['ike_version'] != 'v1':
|
||||
msg = _("Unsupported ike_version: %s! Only 'v1' ike version is "
|
||||
"supported on vshield Edge!"
|
||||
) % ikepolicy['ike_version']
|
||||
LOG.warning(msg)
|
||||
raise vcns_exc.VcnsBadRequest(resource='ikepolicy',
|
||||
msg=msg)
|
||||
|
||||
# In VSE, Phase 1 and Phase 2 share the same encryption_algorithm
|
||||
# and authentication algorithms setting. At present, just record the
|
||||
# discrepancy error in log and take ipsecpolicy to do configuration.
|
||||
if (ikepolicy['auth_algorithm'] != ipsecpolicy['auth_algorithm'] or
|
||||
ikepolicy['encryption_algorithm'] != ipsecpolicy[
|
||||
'encryption_algorithm'] or
|
||||
ikepolicy['pfs'] != ipsecpolicy['pfs']):
|
||||
LOG.warning(_LW(
|
||||
"IKEPolicy and IPsecPolicy should have consistent "
|
||||
"auth_algorithm, encryption_algorithm and pfs for VSE!"))
|
||||
|
||||
# Check whether encryption_algorithm is allowed.
|
||||
encryption_algorithm = ENCRYPTION_ALGORITHM_MAP.get(
|
||||
ipsecpolicy.get('encryption_algorithm'), None)
|
||||
if not encryption_algorithm:
|
||||
msg = _("Unsupported encryption_algorithm: %s! '3des', "
|
||||
"'aes-128' and 'aes-256' are supported on VSE right now."
|
||||
) % ipsecpolicy['encryption_algorithm']
|
||||
LOG.warning(msg)
|
||||
raise vcns_exc.VcnsBadRequest(resource='ipsecpolicy',
|
||||
msg=msg)
|
||||
|
||||
# Check whether pfs is allowed.
|
||||
if not PFS_MAP.get(ipsecpolicy['pfs']):
|
||||
msg = _("Unsupported pfs: %s! 'group2' and 'group5' "
|
||||
"are supported on VSE right now.") % ipsecpolicy['pfs']
|
||||
LOG.warning(msg)
|
||||
raise vcns_exc.VcnsBadRequest(resource='ipsecpolicy',
|
||||
msg=msg)
|
||||
|
||||
# Check whether transform protocol is allowed.
|
||||
if ipsecpolicy['transform_protocol'] not in TRANSFORM_PROTOCOL_ALLOWED:
|
||||
msg = _("Unsupported transform protocol: %s! 'esp' is supported "
|
||||
"by default on VSE right now."
|
||||
) % ipsecpolicy['transform_protocol']
|
||||
LOG.warning(msg)
|
||||
raise vcns_exc.VcnsBadRequest(resource='ipsecpolicy',
|
||||
msg=msg)
|
||||
|
||||
# Check whether encapsulation mode is allowed.
|
||||
if ipsecpolicy['encapsulation_mode'] not in ENCAPSULATION_MODE_ALLOWED:
|
||||
msg = _("Unsupported encapsulation mode: %s! 'tunnel' is "
|
||||
"supported by default on VSE right now."
|
||||
) % ipsecpolicy['encapsulation_mode']
|
||||
LOG.warning(msg)
|
||||
raise vcns_exc.VcnsBadRequest(resource='ipsecpolicy',
|
||||
msg=msg)
|
||||
|
||||
def _convert_ipsec_site(self, site, enablePfs=True):
|
||||
self._check_ikepolicy_ipsecpolicy_allowed(
|
||||
site['ikepolicy'], site['ipsecpolicy'])
|
||||
return {
|
||||
'enabled': site['site'].get('admin_state_up'),
|
||||
'enablePfs': enablePfs,
|
||||
'dhGroup': PFS_MAP.get(site['ipsecpolicy']['pfs']),
|
||||
'name': site['site'].get('name'),
|
||||
'description': site['site'].get('description'),
|
||||
'localId': site['external_ip'],
|
||||
'localIp': site['external_ip'],
|
||||
'peerId': site['site'].get('peer_id'),
|
||||
'peerIp': site['site'].get('peer_address'),
|
||||
'localSubnets': {
|
||||
'subnets': [site['subnet'].get('cidr')]},
|
||||
'peerSubnets': {
|
||||
'subnets': site['site'].get('peer_cidrs')},
|
||||
'authenticationMode': site['site'].get('auth_mode'),
|
||||
'psk': site['site'].get('psk'),
|
||||
'encryptionAlgorithm': ENCRYPTION_ALGORITHM_MAP.get(
|
||||
site['ipsecpolicy'].get('encryption_algorithm'))}
|
||||
|
||||
def update_ipsec_config(self, edge_id, sites, enabled=True):
|
||||
ipsec_config = {'featureType': "ipsec_4.0",
|
||||
'enabled': enabled}
|
||||
vse_sites = [self._convert_ipsec_site(site) for site in sites]
|
||||
ipsec_config['sites'] = {'sites': vse_sites}
|
||||
try:
|
||||
self.vcns.update_ipsec_config(edge_id, ipsec_config)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to update ipsec vpn "
|
||||
"configuration with edge_id: %s"),
|
||||
edge_id)
|
||||
|
||||
def delete_ipsec_config(self, edge_id):
|
||||
try:
|
||||
self.vcns.delete_ipsec_config(edge_id)
|
||||
except vcns_exc.ResourceNotFound:
|
||||
LOG.warning(_LW("IPsec config not found on edge: %s"), edge_id)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to delete ipsec vpn configuration "
|
||||
"with edge_id: %s"), edge_id)
|
||||
|
||||
def get_ipsec_config(self, edge_id):
|
||||
return self.vcns.get_ipsec_config(edge_id)
|
|
@ -1,404 +0,0 @@
|
|||
# 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.
|
||||
|
||||
from oslo.utils import excutils
|
||||
|
||||
from neutron.i18n import _LE
|
||||
from neutron.openstack.common import log as logging
|
||||
from neutron.plugins.vmware.dbexts import vcns_db
|
||||
from neutron.plugins.vmware.vshield.common import (
|
||||
constants as vcns_const)
|
||||
from neutron.plugins.vmware.vshield.common import (
|
||||
exceptions as vcns_exc)
|
||||
try:
|
||||
from neutron_lbaas.services.loadbalancer import constants as lb_constants
|
||||
except Exception:
|
||||
print("WARNING: missing neutron-lbaas package")
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
BALANCE_MAP = {
|
||||
lb_constants.LB_METHOD_ROUND_ROBIN: 'round-robin',
|
||||
lb_constants.LB_METHOD_LEAST_CONNECTIONS: 'leastconn',
|
||||
lb_constants.LB_METHOD_SOURCE_IP: 'source'
|
||||
}
|
||||
PROTOCOL_MAP = {
|
||||
lb_constants.PROTOCOL_TCP: 'tcp',
|
||||
lb_constants.PROTOCOL_HTTP: 'http',
|
||||
lb_constants.PROTOCOL_HTTPS: 'tcp'
|
||||
}
|
||||
SESSION_PERSISTENCE_METHOD_MAP = {
|
||||
lb_constants.SESSION_PERSISTENCE_SOURCE_IP: 'sourceip',
|
||||
lb_constants.SESSION_PERSISTENCE_APP_COOKIE: 'cookie',
|
||||
lb_constants.SESSION_PERSISTENCE_HTTP_COOKIE: 'cookie'}
|
||||
SESSION_PERSISTENCE_COOKIE_MAP = {
|
||||
lb_constants.SESSION_PERSISTENCE_APP_COOKIE: 'app',
|
||||
lb_constants.SESSION_PERSISTENCE_HTTP_COOKIE: 'insert'}
|
||||
|
||||
|
||||
class EdgeLbDriver():
|
||||
"""Implementation of driver APIs for
|
||||
Edge Loadbalancer feature configuration
|
||||
"""
|
||||
|
||||
def _convert_lb_vip(self, context, edge_id, vip, app_profileid):
|
||||
pool_id = vip.get('pool_id')
|
||||
poolid_map = vcns_db.get_vcns_edge_pool_binding(
|
||||
context.session, pool_id, edge_id)
|
||||
pool_vseid = poolid_map['pool_vseid']
|
||||
return {
|
||||
'name': vip.get(
|
||||
'name', '') + vip['id'][-vcns_const.SUFFIX_LENGTH:],
|
||||
'description': vip.get('description'),
|
||||
'ipAddress': vip.get('address'),
|
||||
'protocol': vip.get('protocol'),
|
||||
'port': vip.get('protocol_port'),
|
||||
'connectionLimit': max(0, vip.get('connection_limit')),
|
||||
'defaultPoolId': pool_vseid,
|
||||
'applicationProfileId': app_profileid
|
||||
}
|
||||
|
||||
def _restore_lb_vip(self, context, edge_id, vip_vse):
|
||||
pool_binding = vcns_db.get_vcns_edge_pool_binding_by_vseid(
|
||||
context.session,
|
||||
edge_id,
|
||||
vip_vse['defaultPoolId'])
|
||||
|
||||
return {
|
||||
'name': vip_vse['name'][:-vcns_const.SUFFIX_LENGTH],
|
||||
'address': vip_vse['ipAddress'],
|
||||
'protocol': vip_vse['protocol'],
|
||||
'protocol_port': vip_vse['port'],
|
||||
'pool_id': pool_binding['pool_id']
|
||||
}
|
||||
|
||||
def _convert_lb_pool(self, context, edge_id, pool, members):
|
||||
vsepool = {
|
||||
'name': pool.get(
|
||||
'name', '') + pool['id'][-vcns_const.SUFFIX_LENGTH:],
|
||||
'description': pool.get('description'),
|
||||
'algorithm': BALANCE_MAP.get(
|
||||
pool.get('lb_method'),
|
||||
'round-robin'),
|
||||
'transparent': True,
|
||||
'member': [],
|
||||
'monitorId': []
|
||||
}
|
||||
for member in members:
|
||||
vsepool['member'].append({
|
||||
'ipAddress': member['address'],
|
||||
'weight': member['weight'],
|
||||
'port': member['protocol_port']
|
||||
})
|
||||
##TODO(linb) right now, vse only accept at most one monitor per pool
|
||||
monitors = pool.get('health_monitors')
|
||||
if not monitors:
|
||||
return vsepool
|
||||
monitorid_map = vcns_db.get_vcns_edge_monitor_binding(
|
||||
context.session,
|
||||
monitors[0],
|
||||
edge_id)
|
||||
vsepool['monitorId'].append(monitorid_map['monitor_vseid'])
|
||||
return vsepool
|
||||
|
||||
def _restore_lb_pool(self, context, edge_id, pool_vse):
|
||||
#TODO(linb): Get more usefule info
|
||||
return {
|
||||
'name': pool_vse['name'][:-vcns_const.SUFFIX_LENGTH],
|
||||
}
|
||||
|
||||
def _convert_lb_monitor(self, context, monitor):
|
||||
return {
|
||||
'type': PROTOCOL_MAP.get(
|
||||
monitor.get('type'), 'http'),
|
||||
'interval': monitor.get('delay'),
|
||||
'timeout': monitor.get('timeout'),
|
||||
'maxRetries': monitor.get('max_retries'),
|
||||
'name': monitor.get('id')
|
||||
}
|
||||
|
||||
def _restore_lb_monitor(self, context, edge_id, monitor_vse):
|
||||
return {
|
||||
'delay': monitor_vse['interval'],
|
||||
'timeout': monitor_vse['timeout'],
|
||||
'max_retries': monitor_vse['maxRetries'],
|
||||
'id': monitor_vse['name']
|
||||
}
|
||||
|
||||
def _convert_app_profile(self, name, sess_persist, protocol):
|
||||
vcns_app_profile = {
|
||||
'insertXForwardedFor': False,
|
||||
'name': name,
|
||||
'serverSslEnabled': False,
|
||||
'sslPassthrough': False,
|
||||
'template': protocol,
|
||||
}
|
||||
# Since SSL Termination is not supported right now, so just use
|
||||
# sslPassthrough mehtod if the protocol is HTTPS.
|
||||
if protocol == lb_constants.PROTOCOL_HTTPS:
|
||||
vcns_app_profile['sslPassthrough'] = True
|
||||
|
||||
if sess_persist.get('type'):
|
||||
# If protocol is not HTTP, only sourceip is supported
|
||||
if (protocol != lb_constants.PROTOCOL_HTTP and
|
||||
sess_persist['type'] != (
|
||||
lb_constants.SESSION_PERSISTENCE_SOURCE_IP)):
|
||||
msg = (_("Invalid %(protocol)s persistence method: %(type)s") %
|
||||
{'protocol': protocol,
|
||||
'type': sess_persist['type']})
|
||||
raise vcns_exc.VcnsBadRequest(resource='sess_persist', msg=msg)
|
||||
persistence = {
|
||||
'method': SESSION_PERSISTENCE_METHOD_MAP.get(
|
||||
sess_persist['type'])}
|
||||
if sess_persist['type'] in SESSION_PERSISTENCE_COOKIE_MAP:
|
||||
if sess_persist.get('cookie_name'):
|
||||
persistence['cookieName'] = sess_persist['cookie_name']
|
||||
else:
|
||||
persistence['cookieName'] = 'default_cookie_name'
|
||||
persistence['cookieMode'] = SESSION_PERSISTENCE_COOKIE_MAP.get(
|
||||
sess_persist['type'])
|
||||
vcns_app_profile['persistence'] = persistence
|
||||
return vcns_app_profile
|
||||
|
||||
def create_vip(self, context, edge_id, vip):
|
||||
app_profile = self._convert_app_profile(
|
||||
vip['name'], (vip.get('session_persistence') or {}),
|
||||
vip.get('protocol'))
|
||||
try:
|
||||
header, response = self.vcns.create_app_profile(
|
||||
edge_id, app_profile)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to create app profile on edge: %s"),
|
||||
edge_id)
|
||||
objuri = header['location']
|
||||
app_profileid = objuri[objuri.rfind("/") + 1:]
|
||||
|
||||
vip_new = self._convert_lb_vip(context, edge_id, vip, app_profileid)
|
||||
try:
|
||||
header, response = self.vcns.create_vip(
|
||||
edge_id, vip_new)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to create vip on vshield edge: %s"),
|
||||
edge_id)
|
||||
self.vcns.delete_app_profile(edge_id, app_profileid)
|
||||
objuri = header['location']
|
||||
vip_vseid = objuri[objuri.rfind("/") + 1:]
|
||||
|
||||
# Add the vip mapping
|
||||
map_info = {
|
||||
"vip_id": vip['id'],
|
||||
"vip_vseid": vip_vseid,
|
||||
"edge_id": edge_id,
|
||||
"app_profileid": app_profileid
|
||||
}
|
||||
vcns_db.add_vcns_edge_vip_binding(context.session, map_info)
|
||||
|
||||
def _get_vip_binding(self, session, id):
|
||||
vip_binding = vcns_db.get_vcns_edge_vip_binding(session, id)
|
||||
if not vip_binding:
|
||||
msg = (_("vip_binding not found with id: %(id)s "
|
||||
"edge_id: %(edge_id)s") % {
|
||||
'id': id,
|
||||
'edge_id': vip_binding[vcns_const.EDGE_ID]})
|
||||
LOG.error(msg)
|
||||
raise vcns_exc.VcnsNotFound(
|
||||
resource='router_service_binding', msg=msg)
|
||||
return vip_binding
|
||||
|
||||
def get_vip(self, context, id):
|
||||
vip_binding = vcns_db.get_vcns_edge_vip_binding(context.session, id)
|
||||
edge_id = vip_binding[vcns_const.EDGE_ID]
|
||||
vip_vseid = vip_binding['vip_vseid']
|
||||
try:
|
||||
response = self.vcns.get_vip(edge_id, vip_vseid)[1]
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to get vip on edge"))
|
||||
return self._restore_lb_vip(context, edge_id, response)
|
||||
|
||||
def update_vip(self, context, vip, session_persistence_update=True):
|
||||
vip_binding = self._get_vip_binding(context.session, vip['id'])
|
||||
edge_id = vip_binding[vcns_const.EDGE_ID]
|
||||
vip_vseid = vip_binding.get('vip_vseid')
|
||||
if session_persistence_update:
|
||||
app_profileid = vip_binding.get('app_profileid')
|
||||
app_profile = self._convert_app_profile(
|
||||
vip['name'], vip.get('session_persistence', {}),
|
||||
vip.get('protocol'))
|
||||
try:
|
||||
self.vcns.update_app_profile(
|
||||
edge_id, app_profileid, app_profile)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to update app profile on "
|
||||
"edge: %s"), edge_id)
|
||||
|
||||
vip_new = self._convert_lb_vip(context, edge_id, vip, app_profileid)
|
||||
try:
|
||||
self.vcns.update_vip(edge_id, vip_vseid, vip_new)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to update vip on edge: %s"), edge_id)
|
||||
|
||||
def delete_vip(self, context, id):
|
||||
vip_binding = self._get_vip_binding(context.session, id)
|
||||
edge_id = vip_binding[vcns_const.EDGE_ID]
|
||||
vip_vseid = vip_binding['vip_vseid']
|
||||
app_profileid = vip_binding['app_profileid']
|
||||
|
||||
try:
|
||||
self.vcns.delete_vip(edge_id, vip_vseid)
|
||||
except vcns_exc.ResourceNotFound:
|
||||
LOG.exception(_LE("vip not found on edge: %s"), edge_id)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to delete vip on edge: %s"), edge_id)
|
||||
|
||||
try:
|
||||
self.vcns.delete_app_profile(edge_id, app_profileid)
|
||||
except vcns_exc.ResourceNotFound:
|
||||
LOG.exception(_LE("app profile not found on edge: %s"), edge_id)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to delete app profile on edge: %s"),
|
||||
edge_id)
|
||||
|
||||
vcns_db.delete_vcns_edge_vip_binding(context.session, id)
|
||||
|
||||
def create_pool(self, context, edge_id, pool, members):
|
||||
pool_new = self._convert_lb_pool(context, edge_id, pool, members)
|
||||
try:
|
||||
header = self.vcns.create_pool(edge_id, pool_new)[0]
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to create pool"))
|
||||
|
||||
objuri = header['location']
|
||||
pool_vseid = objuri[objuri.rfind("/") + 1:]
|
||||
|
||||
# update the pool mapping table
|
||||
map_info = {
|
||||
"pool_id": pool['id'],
|
||||
"pool_vseid": pool_vseid,
|
||||
"edge_id": edge_id
|
||||
}
|
||||
vcns_db.add_vcns_edge_pool_binding(context.session, map_info)
|
||||
|
||||
def get_pool(self, context, id, edge_id):
|
||||
pool_binding = vcns_db.get_vcns_edge_pool_binding(
|
||||
context.session, id, edge_id)
|
||||
if not pool_binding:
|
||||
msg = (_("pool_binding not found with id: %(id)s "
|
||||
"edge_id: %(edge_id)s") % {'id': id, 'edge_id': edge_id})
|
||||
LOG.error(msg)
|
||||
raise vcns_exc.VcnsNotFound(
|
||||
resource='router_service_binding', msg=msg)
|
||||
pool_vseid = pool_binding['pool_vseid']
|
||||
try:
|
||||
response = self.vcns.get_pool(edge_id, pool_vseid)[1]
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to get pool on edge"))
|
||||
return self._restore_lb_pool(context, edge_id, response)
|
||||
|
||||
def update_pool(self, context, edge_id, pool, members):
|
||||
pool_binding = vcns_db.get_vcns_edge_pool_binding(
|
||||
context.session, pool['id'], edge_id)
|
||||
pool_vseid = pool_binding['pool_vseid']
|
||||
pool_new = self._convert_lb_pool(context, edge_id, pool, members)
|
||||
try:
|
||||
self.vcns.update_pool(edge_id, pool_vseid, pool_new)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to update pool"))
|
||||
|
||||
def delete_pool(self, context, id, edge_id):
|
||||
pool_binding = vcns_db.get_vcns_edge_pool_binding(
|
||||
context.session, id, edge_id)
|
||||
pool_vseid = pool_binding['pool_vseid']
|
||||
try:
|
||||
self.vcns.delete_pool(edge_id, pool_vseid)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to delete pool"))
|
||||
vcns_db.delete_vcns_edge_pool_binding(
|
||||
context.session, id, edge_id)
|
||||
|
||||
def create_health_monitor(self, context, edge_id, health_monitor):
|
||||
monitor_new = self._convert_lb_monitor(context, health_monitor)
|
||||
try:
|
||||
header = self.vcns.create_health_monitor(edge_id, monitor_new)[0]
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to create monitor on edge: %s"),
|
||||
edge_id)
|
||||
|
||||
objuri = header['location']
|
||||
monitor_vseid = objuri[objuri.rfind("/") + 1:]
|
||||
|
||||
# update the health_monitor mapping table
|
||||
map_info = {
|
||||
"monitor_id": health_monitor['id'],
|
||||
"monitor_vseid": monitor_vseid,
|
||||
"edge_id": edge_id
|
||||
}
|
||||
vcns_db.add_vcns_edge_monitor_binding(context.session, map_info)
|
||||
|
||||
def get_health_monitor(self, context, id, edge_id):
|
||||
monitor_binding = vcns_db.get_vcns_edge_monitor_binding(
|
||||
context.session, id, edge_id)
|
||||
if not monitor_binding:
|
||||
msg = (_("monitor_binding not found with id: %(id)s "
|
||||
"edge_id: %(edge_id)s") % {'id': id, 'edge_id': edge_id})
|
||||
LOG.error(msg)
|
||||
raise vcns_exc.VcnsNotFound(
|
||||
resource='router_service_binding', msg=msg)
|
||||
monitor_vseid = monitor_binding['monitor_vseid']
|
||||
try:
|
||||
response = self.vcns.get_health_monitor(edge_id, monitor_vseid)[1]
|
||||
except vcns_exc.VcnsApiException as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to get monitor on edge: %s"),
|
||||
e.response)
|
||||
return self._restore_lb_monitor(context, edge_id, response)
|
||||
|
||||
def update_health_monitor(self, context, edge_id,
|
||||
old_health_monitor, health_monitor):
|
||||
monitor_binding = vcns_db.get_vcns_edge_monitor_binding(
|
||||
context.session,
|
||||
old_health_monitor['id'], edge_id)
|
||||
monitor_vseid = monitor_binding['monitor_vseid']
|
||||
monitor_new = self._convert_lb_monitor(
|
||||
context, health_monitor)
|
||||
try:
|
||||
self.vcns.update_health_monitor(
|
||||
edge_id, monitor_vseid, monitor_new)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to update monitor on edge: %s"),
|
||||
edge_id)
|
||||
|
||||
def delete_health_monitor(self, context, id, edge_id):
|
||||
monitor_binding = vcns_db.get_vcns_edge_monitor_binding(
|
||||
context.session, id, edge_id)
|
||||
monitor_vseid = monitor_binding['monitor_vseid']
|
||||
try:
|
||||
self.vcns.delete_health_monitor(edge_id, monitor_vseid)
|
||||
except vcns_exc.VcnsApiException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Failed to delete monitor"))
|
||||
vcns_db.delete_vcns_edge_monitor_binding(
|
||||
context.session, id, edge_id)
|
|
@ -17,19 +17,13 @@ from oslo.config import cfg
|
|||
from neutron.openstack.common import log as logging
|
||||
from neutron.plugins.vmware.common import config # noqa
|
||||
from neutron.plugins.vmware.vshield import edge_appliance_driver
|
||||
from neutron.plugins.vmware.vshield import edge_firewall_driver
|
||||
from neutron.plugins.vmware.vshield import edge_ipsecvpn_driver
|
||||
from neutron.plugins.vmware.vshield import edge_loadbalancer_driver
|
||||
from neutron.plugins.vmware.vshield.tasks import tasks
|
||||
from neutron.plugins.vmware.vshield import vcns
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class VcnsDriver(edge_appliance_driver.EdgeApplianceDriver,
|
||||
edge_firewall_driver.EdgeFirewallDriver,
|
||||
edge_loadbalancer_driver.EdgeLbDriver,
|
||||
edge_ipsecvpn_driver.EdgeIPsecVpnDriver):
|
||||
class VcnsDriver(edge_appliance_driver.EdgeApplianceDriver):
|
||||
|
||||
def __init__(self, callbacks):
|
||||
super(VcnsDriver, self).__init__()
|
||||
|
|
|
@ -55,11 +55,6 @@ EXTERNAL_FWAAS_TABLES = ['firewall_rules', 'firewalls', 'firewall_policies']
|
|||
EXTERNAL_TABLES = (EXTERNAL_FWAAS_TABLES + EXTERNAL_LBAAS_TABLES +
|
||||
EXTERNAL_VPNAAS_TABLES)
|
||||
|
||||
# TODO(akamyshnikova): Temporarily skip checking FKs on these tables.
|
||||
TABLES_WITH_EXTERNAL_FK = ['vcns_edge_monitor_bindings',
|
||||
'vcns_edge_pool_bindings', 'vcns_edge_vip_bindings',
|
||||
'vcns_firewall_rule_bindings']
|
||||
|
||||
|
||||
class _TestModelsMigrations(test_migrations.ModelsMigrationsSync):
|
||||
'''Test for checking of equality models state and migrations.
|
||||
|
@ -221,14 +216,6 @@ class _TestModelsMigrations(test_migrations.ModelsMigrationsSync):
|
|||
if col in insp.get_pk_constraint(
|
||||
table_name)['constrained_columns']:
|
||||
return False
|
||||
# TODO(akamyshnikova): Remove this skip once the logic for
|
||||
# vcns_*_bindings is fixed. (Part of advanced services split.)
|
||||
elif ((element[0] == 'remove_fk'
|
||||
and element[1].parent.name in TABLES_WITH_EXTERNAL_FK)
|
||||
or (element[0] == 'drop_key'
|
||||
and element[2] in TABLES_WITH_EXTERNAL_FK)):
|
||||
return False
|
||||
|
||||
else:
|
||||
for modified, _, table, column, _, _, new in element:
|
||||
if modified == 'modify_default' and dialect == 'mysql':
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
# 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.
|
||||
|
||||
import os
|
||||
|
||||
from neutron.plugins.vmware.api_client import client as nsx_client
|
||||
from neutron.plugins.vmware.api_client import eventlet_client
|
||||
from neutron.plugins.vmware import extensions
|
||||
import neutron.plugins.vmware.plugin as neutron_plugin
|
||||
from neutron.plugins.vmware.vshield.common import VcnsApiClient as vcnsapi
|
||||
from neutron.plugins.vmware.vshield import vcns
|
||||
import neutron.plugins.vmware.vshield.vcns_driver as vcnsdriver
|
||||
|
||||
|
||||
plugin = neutron_plugin.NsxPlugin
|
||||
service_plugin = neutron_plugin.NsxServicePlugin
|
||||
api_client = nsx_client.NsxApiClient
|
||||
evt_client = eventlet_client.EventletApiClient
|
||||
vcns_class = vcns.Vcns
|
||||
vcns_driver = vcnsdriver.VcnsDriver
|
||||
vcns_api_helper = vcnsapi.VcnsApiHelper
|
||||
|
||||
STUBS_PATH = os.path.join(os.path.dirname(__file__), 'etc')
|
||||
NSXEXT_PATH = os.path.dirname(extensions.__file__)
|
||||
NSXAPI_NAME = '%s.%s' % (api_client.__module__, api_client.__name__)
|
||||
PLUGIN_NAME = '%s.%s' % (plugin.__module__, plugin.__name__)
|
||||
SERVICE_PLUGIN_NAME = '%s.%s' % (service_plugin.__module__,
|
||||
service_plugin.__name__)
|
||||
CLIENT_NAME = '%s.%s' % (evt_client.__module__, evt_client.__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):
|
||||
return os.path.join(STUBS_PATH, filename)
|
||||
|
||||
|
||||
def nsx_method(method_name, module_name='nsxlib'):
|
||||
return '%s.%s.%s' % ('neutron.plugins.vmware', module_name, method_name)
|
|
@ -1,293 +0,0 @@
|
|||
# Copyright (c) 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.
|
||||
|
||||
import copy
|
||||
|
||||
from eventlet import greenthread
|
||||
import mock
|
||||
from oslo.config import cfg
|
||||
|
||||
from neutron.api.v2 import attributes
|
||||
from neutron.common import constants
|
||||
from neutron import context
|
||||
from neutron.extensions import l3
|
||||
from neutron import manager as n_manager
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.vmware.common import utils
|
||||
from neutron.plugins.vmware.plugins import service as nsp
|
||||
from neutron.tests import base
|
||||
from neutron.tests.unit import test_l3_plugin
|
||||
from neutron.tests.unit import vmware
|
||||
from neutron.tests.unit.vmware import test_nsx_plugin
|
||||
from neutron.tests.unit.vmware.vshield import fake_vcns
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
|
||||
|
||||
class ServiceRouterTestExtensionManager(object):
|
||||
|
||||
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
|
||||
l3_attr_map = copy.deepcopy(l3.RESOURCE_ATTRIBUTE_MAP)
|
||||
for res in l3.RESOURCE_ATTRIBUTE_MAP.keys():
|
||||
attr_info = attributes.RESOURCE_ATTRIBUTE_MAP.get(res)
|
||||
if attr_info:
|
||||
l3.RESOURCE_ATTRIBUTE_MAP[res] = attr_info
|
||||
resources = l3.L3.get_resources()
|
||||
# restore the original resources once the controllers are created
|
||||
l3.RESOURCE_ATTRIBUTE_MAP = l3_attr_map
|
||||
|
||||
return resources
|
||||
|
||||
def get_actions(self):
|
||||
return []
|
||||
|
||||
def get_request_extensions(self):
|
||||
return []
|
||||
|
||||
|
||||
class ServiceRouterTest(test_nsx_plugin.L3NatTest,
|
||||
test_l3_plugin.L3NatTestCaseMixin):
|
||||
|
||||
def vcns_patch(self):
|
||||
instance = self.mock_vcns.start()
|
||||
self.vcns_instance = instance
|
||||
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_deploy_status.side_effect = (
|
||||
self.fc2.get_edge_deploy_status)
|
||||
instance.return_value.delete_edge.side_effect = self.fc2.delete_edge
|
||||
instance.return_value.update_interface.side_effect = (
|
||||
self.fc2.update_interface)
|
||||
instance.return_value.get_nat_config.side_effect = (
|
||||
self.fc2.get_nat_config)
|
||||
instance.return_value.update_nat_config.side_effect = (
|
||||
self.fc2.update_nat_config)
|
||||
instance.return_value.delete_nat_rule.side_effect = (
|
||||
self.fc2.delete_nat_rule)
|
||||
instance.return_value.get_edge_status.side_effect = (
|
||||
self.fc2.get_edge_status)
|
||||
instance.return_value.get_edges.side_effect = self.fc2.get_edges
|
||||
instance.return_value.update_routes.side_effect = (
|
||||
self.fc2.update_routes)
|
||||
instance.return_value.create_lswitch.side_effect = (
|
||||
self.fc2.create_lswitch)
|
||||
instance.return_value.delete_lswitch.side_effect = (
|
||||
self.fc2.delete_lswitch)
|
||||
instance.return_value.get_loadbalancer_config.side_effect = (
|
||||
self.fc2.get_loadbalancer_config)
|
||||
instance.return_value.enable_service_loadbalancer.side_effect = (
|
||||
self.fc2.enable_service_loadbalancer)
|
||||
|
||||
def setUp(self, ext_mgr=None, service_plugins=None):
|
||||
cfg.CONF.set_override('api_extensions_path', vmware.NSXEXT_PATH)
|
||||
cfg.CONF.set_override('task_status_check_interval', 200, group="vcns")
|
||||
|
||||
# vcns does not support duplicated router name, ignore router name
|
||||
# validation for unit-test cases
|
||||
self.fc2 = fake_vcns.FakeVcns(unique_router_name=False)
|
||||
self.mock_vcns = mock.patch(vmware.VCNS_NAME, autospec=True)
|
||||
self.vcns_patch()
|
||||
mock_proxy = mock.patch(
|
||||
"%s.%s" % (vmware.SERVICE_PLUGIN_NAME,
|
||||
'_set_create_lswitch_proxy'))
|
||||
mock_proxy.start()
|
||||
|
||||
ext_mgr = ext_mgr or ServiceRouterTestExtensionManager()
|
||||
super(ServiceRouterTest, self).setUp(
|
||||
plugin=vmware.SERVICE_PLUGIN_NAME,
|
||||
service_plugins=service_plugins,
|
||||
ext_mgr=ext_mgr)
|
||||
|
||||
self.fc2.set_fake_nsx_api(self.fc)
|
||||
self.addCleanup(self.fc2.reset_all)
|
||||
|
||||
def tearDown(self):
|
||||
plugin = n_manager.NeutronManager.get_plugin()
|
||||
manager = plugin.vcns_driver.task_manager
|
||||
# wait max ~10 seconds for all tasks to be finished
|
||||
for i in range(100):
|
||||
if not manager.has_pending_task():
|
||||
break
|
||||
greenthread.sleep(0.1)
|
||||
if manager.has_pending_task():
|
||||
manager.show_pending_tasks()
|
||||
raise Exception(_("Tasks not completed"))
|
||||
manager.stop()
|
||||
# Ensure the manager thread has been stopped
|
||||
self.assertIsNone(manager._thread)
|
||||
super(ServiceRouterTest, self).tearDown()
|
||||
|
||||
def _create_router(self, fmt, tenant_id, name=None,
|
||||
admin_state_up=None, set_context=False,
|
||||
arg_list=None, **kwargs):
|
||||
data = {'router': {'tenant_id': tenant_id}}
|
||||
if name:
|
||||
data['router']['name'] = name
|
||||
if admin_state_up:
|
||||
data['router']['admin_state_up'] = admin_state_up
|
||||
for arg in (('admin_state_up', 'tenant_id') + (arg_list or ())):
|
||||
# Arg must be present and not empty
|
||||
if arg in kwargs and kwargs[arg]:
|
||||
data['router'][arg] = kwargs[arg]
|
||||
data['router']['service_router'] = True
|
||||
router_req = self.new_create_request('routers', data, fmt)
|
||||
if set_context and tenant_id:
|
||||
# create a specific auth context for this request
|
||||
router_req.environ['neutron.context'] = context.Context(
|
||||
'', tenant_id)
|
||||
|
||||
return router_req.get_response(self.ext_api)
|
||||
|
||||
|
||||
class ServiceRouterTestCase(ServiceRouterTest,
|
||||
test_nsx_plugin.TestL3NatTestCase):
|
||||
|
||||
def test_router_create(self):
|
||||
name = 'router1'
|
||||
tenant_id = _uuid()
|
||||
expected_value = [('name', name), ('tenant_id', tenant_id),
|
||||
('admin_state_up', True),
|
||||
('external_gateway_info', None),
|
||||
('service_router', True)]
|
||||
with self.router(name=name, admin_state_up=True,
|
||||
tenant_id=tenant_id) as router:
|
||||
expected_value_1 = expected_value + [('status', 'PENDING_CREATE')]
|
||||
for k, v in expected_value_1:
|
||||
self.assertEqual(router['router'][k], v)
|
||||
|
||||
# wait max ~10 seconds for router status update
|
||||
for i in range(20):
|
||||
greenthread.sleep(0.5)
|
||||
res = self._show('routers', router['router']['id'])
|
||||
if res['router']['status'] == 'ACTIVE':
|
||||
break
|
||||
expected_value_2 = expected_value + [('status', 'ACTIVE')]
|
||||
for k, v in expected_value_2:
|
||||
self.assertEqual(res['router'][k], v)
|
||||
|
||||
# check an integration lswitch is created
|
||||
lswitch_name = "%s-ls" % name
|
||||
for lswitch_id, lswitch in self.fc2._lswitches.iteritems():
|
||||
if lswitch['display_name'] == lswitch_name:
|
||||
break
|
||||
else:
|
||||
self.fail("Integration lswitch not found")
|
||||
|
||||
# check an integration lswitch is deleted
|
||||
lswitch_name = "%s-ls" % name
|
||||
for lswitch_id, lswitch in self.fc2._lswitches.iteritems():
|
||||
if lswitch['display_name'] == lswitch_name:
|
||||
self.fail("Integration switch is not deleted")
|
||||
|
||||
def test_router_delete_after_plugin_restart(self):
|
||||
name = 'router1'
|
||||
tenant_id = _uuid()
|
||||
with self.router(name=name, admin_state_up=True,
|
||||
tenant_id=tenant_id):
|
||||
# clear router type cache to mimic plugin restart
|
||||
plugin = n_manager.NeutronManager.get_plugin()
|
||||
plugin._router_type = {}
|
||||
|
||||
# check an integration lswitch is deleted
|
||||
lswitch_name = "%s-ls" % name
|
||||
for lswitch_id, lswitch in self.fc2._lswitches.iteritems():
|
||||
if lswitch['display_name'] == lswitch_name:
|
||||
self.fail("Integration switch is not deleted")
|
||||
|
||||
def test_router_show(self):
|
||||
name = 'router1'
|
||||
tenant_id = _uuid()
|
||||
expected_value = [('name', name), ('tenant_id', tenant_id),
|
||||
('admin_state_up', True),
|
||||
('status', 'PENDING_CREATE'),
|
||||
('external_gateway_info', None),
|
||||
('service_router', True)]
|
||||
with self.router(name='router1', admin_state_up=True,
|
||||
tenant_id=tenant_id) as router:
|
||||
res = self._show('routers', router['router']['id'])
|
||||
for k, v in expected_value:
|
||||
self.assertEqual(res['router'][k], v)
|
||||
|
||||
def _test_router_create_with_gwinfo_and_l3_ext_net(self, vlan_id=None):
|
||||
super(ServiceRouterTestCase,
|
||||
self)._test_router_create_with_gwinfo_and_l3_ext_net(
|
||||
vlan_id, validate_ext_gw=False)
|
||||
|
||||
def _test_router_update_gateway_on_l3_ext_net(self, vlan_id=None):
|
||||
super(ServiceRouterTestCase,
|
||||
self)._test_router_update_gateway_on_l3_ext_net(
|
||||
vlan_id, validate_ext_gw=False)
|
||||
|
||||
def test_floatingip_update(self):
|
||||
self._test_floatingip_update(constants.FLOATINGIP_STATUS_ACTIVE)
|
||||
|
||||
|
||||
class TestProxyCreateLswitch(base.BaseTestCase):
|
||||
def setUp(self):
|
||||
super(TestProxyCreateLswitch, self).setUp()
|
||||
self.tenant_id = "foo_tenant"
|
||||
self.display_name = "foo_network"
|
||||
self.tz_config = [
|
||||
{'zone_uuid': 'foo_zone',
|
||||
'transport_type': 'stt'}
|
||||
]
|
||||
self.tags = utils.get_tags(quantum_net_id='foo_id',
|
||||
os_tid=self.tenant_id)
|
||||
self.cluster = None
|
||||
|
||||
def test_create_lswitch_with_basic_args(self):
|
||||
result = nsp._process_base_create_lswitch_args(self.cluster,
|
||||
'foo_id',
|
||||
self.tenant_id,
|
||||
self.display_name,
|
||||
self.tz_config)
|
||||
self.assertEqual(self.display_name, result[0])
|
||||
self.assertEqual(self.tz_config, result[1])
|
||||
self.assertEqual(sorted(self.tags), sorted(result[2]))
|
||||
|
||||
def test_create_lswitch_with_shared_as_kwarg(self):
|
||||
result = nsp._process_base_create_lswitch_args(self.cluster,
|
||||
'foo_id',
|
||||
self.tenant_id,
|
||||
self.display_name,
|
||||
self.tz_config,
|
||||
shared=True)
|
||||
expected = self.tags + [{'scope': 'shared', 'tag': 'true'}]
|
||||
self.assertEqual(sorted(expected), sorted(result[2]))
|
||||
|
||||
def test_create_lswitch_with_shared_as_arg(self):
|
||||
result = nsp._process_base_create_lswitch_args(self.cluster,
|
||||
'foo_id',
|
||||
self.tenant_id,
|
||||
self.display_name,
|
||||
self.tz_config,
|
||||
True)
|
||||
additional_tags = [{'scope': 'shared', 'tag': 'true'}]
|
||||
expected = self.tags + additional_tags
|
||||
self.assertEqual(sorted(expected), sorted(result[2]))
|
||||
|
||||
def test_create_lswitch_with_additional_tags(self):
|
||||
more_tags = [{'scope': 'foo_scope', 'tag': 'foo_tag'}]
|
||||
result = nsp._process_base_create_lswitch_args(self.cluster,
|
||||
'foo_id',
|
||||
self.tenant_id,
|
||||
self.display_name,
|
||||
self.tz_config,
|
||||
tags=more_tags)
|
||||
expected = self.tags + more_tags
|
||||
self.assertEqual(sorted(expected), sorted(result[2]))
|
|
@ -1,375 +0,0 @@
|
|||
# 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.
|
||||
#
|
||||
|
||||
import contextlib
|
||||
import mock
|
||||
import webob.exc
|
||||
|
||||
from neutron import context
|
||||
from neutron.db.firewall import firewall_db
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.vmware.vshield.common import exceptions as vcns_exc
|
||||
from neutron.plugins.vmware.vshield import vcns_driver
|
||||
from neutron.tests.unit.db.firewall import test_db_firewall
|
||||
from neutron.tests.unit import vmware
|
||||
from neutron.tests.unit.vmware.vshield import fake_vcns
|
||||
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
|
||||
VSE_ID = 'edge-1'
|
||||
ROUTER_ID = '42f95450-5cc9-44e4-a744-1320e592a9d5'
|
||||
|
||||
VCNS_CONFIG_FILE = vmware.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):
|
||||
|
||||
self.config_parse(args=['--config-file', VCNS_CONFIG_FILE])
|
||||
# mock vcns
|
||||
self.fc2 = fake_vcns.FakeVcns(unique_router_name=False)
|
||||
self.mock_vcns = mock.patch(vmware.VCNS_NAME, autospec=True)
|
||||
self.vcns_firewall_patch()
|
||||
|
||||
self.driver = vcns_driver.VcnsDriver(mock.Mock())
|
||||
|
||||
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',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr2',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr3',
|
||||
do_delete=False)) as fr:
|
||||
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
|
||||
with self.firewall_policy(firewall_rules=fw_rule_ids,
|
||||
do_delete=False) 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',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr2',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr3',
|
||||
do_delete=False)) as fr:
|
||||
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
|
||||
with self.firewall_policy(firewall_rules=fw_rule_ids,
|
||||
do_delete=False) 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',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr2',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr3',
|
||||
do_delete=False)) as fr:
|
||||
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
|
||||
with self.firewall_policy(firewall_rules=fw_rule_ids,
|
||||
do_delete=False) 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',
|
||||
do_delete=False)) as fr:
|
||||
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
|
||||
with self.firewall_policy(firewall_rules=fw_rule_ids,
|
||||
do_delete=False) 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',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr2',
|
||||
do_delete=False)) as fr:
|
||||
fw_rule_ids = [r['firewall_rule']['id'] for r in fr]
|
||||
with self.firewall_policy(firewall_rules=fw_rule_ids,
|
||||
do_delete=False) 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',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr1',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr2',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr3',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr4',
|
||||
do_delete=False),
|
||||
self.firewall_rule(name='fwr5',
|
||||
do_delete=False),
|
||||
self.firewall_rule(
|
||||
name='fwr6',
|
||||
do_delete=False)) 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'])
|
|
@ -1,682 +0,0 @@
|
|||
# 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.vmware.vshield import test_edge_router
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
|
||||
FW_PLUGIN_CLASS = "neutron.plugins.vmware.plugin.NsxServicePlugin"
|
||||
|
||||
|
||||
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()
|
||||
|
||||
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 _create_and_get_router(self):
|
||||
req = self._create_router(self.fmt, self._tenant_id)
|
||||
res = self.deserialize(self.fmt, req)
|
||||
return 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': kwargs.get('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):
|
||||
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
|
||||
attrs['router_id'] = self._create_and_get_router()
|
||||
with self.firewall(
|
||||
name=name,
|
||||
firewall_policy_id=fwp_id,
|
||||
router_id=attrs['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_create_firewall_without_policy(self):
|
||||
name = "new_fw"
|
||||
attrs = self._get_test_firewall_attrs(name)
|
||||
attrs['router_id'] = self._create_and_get_router()
|
||||
|
||||
with self.firewall(
|
||||
name=name,
|
||||
router_id=attrs['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):
|
||||
name = "new_fw"
|
||||
attrs = self._get_test_firewall_attrs(name)
|
||||
attrs['router_id'] = self._create_and_get_router()
|
||||
|
||||
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=attrs['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()
|
||||
with self.firewall_policy() as fwp:
|
||||
fwp_id = fwp['firewall_policy']['id']
|
||||
with self.firewall(
|
||||
firewall_policy_id=fwp_id,
|
||||
router_id=self._create_and_get_router(),
|
||||
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
|
||||
do_delete=False) as fw:
|
||||
fw_id = fw['firewall']['id']
|
||||
with ctx.session.begin(subtransactions=True):
|
||||
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_delete_router_in_use_by_fwservice(self):
|
||||
router_id = self._create_and_get_router()
|
||||
with self.firewall_policy() as fwp:
|
||||
fwp_id = fwp['firewall_policy']['id']
|
||||
with self.firewall(
|
||||
name='fw',
|
||||
firewall_policy_id=fwp_id,
|
||||
router_id=router_id,
|
||||
admin_state_up=test_db_firewall.ADMIN_STATE_UP,
|
||||
expected_res_status=201
|
||||
):
|
||||
self._delete('routers', router_id,
|
||||
expected_code=webob.exc.HTTPConflict.code)
|
||||
|
||||
def test_show_firewall(self):
|
||||
name = "firewall1"
|
||||
attrs = self._get_test_firewall_attrs(name)
|
||||
attrs['router_id'] = self._create_and_get_router()
|
||||
|
||||
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=attrs['router_id'],
|
||||
admin_state_up=test_db_firewall.ADMIN_STATE_UP) as firewall:
|
||||
|
||||
req = self.new_show_request('firewalls',
|
||||
firewall['firewall']['id'],
|
||||
fmt=self.fmt)
|
||||
res = self.deserialize(self.fmt,
|
||||
req.get_response(self.ext_api))
|
||||
attrs = self._replace_firewall_status(
|
||||
attrs, const.PENDING_CREATE, const.ACTIVE)
|
||||
for k, v in attrs.iteritems():
|
||||
self.assertEqual(res['firewall'][k], v)
|
||||
|
||||
def test_list_firewalls(self):
|
||||
keys_list = []
|
||||
for i in range(3):
|
||||
keys_list.append({'name': "fw" + str(i),
|
||||
'router_id': self._create_and_get_router(),
|
||||
'admin_state_up': True,
|
||||
'status': "ACTIVE"})
|
||||
|
||||
with contextlib.nested(
|
||||
self.firewall(
|
||||
name='fw0', router_id=keys_list[0]['router_id'],
|
||||
admin_state_up=True, description='fw'),
|
||||
self.firewall(
|
||||
name='fw1', router_id=keys_list[1]['router_id'],
|
||||
admin_state_up=True, description='fw'),
|
||||
self.firewall(
|
||||
name='fw2', router_id=keys_list[2]['router_id'],
|
||||
admin_state_up=True, description='fw'),
|
||||
) as (fw1, fw2, fw3):
|
||||
self._test_list_resources(
|
||||
'firewall', (fw1, fw2, fw3),
|
||||
query_params='description=fw')
|
||||
|
||||
req = self.new_list_request('firewalls')
|
||||
res = self.deserialize(
|
||||
self.fmt, req.get_response(self.ext_api))
|
||||
self.assertEqual(len(res['firewalls']), 3)
|
||||
for index in range(len(res['firewalls'])):
|
||||
for k, v in keys_list[index].items():
|
||||
self.assertEqual(res['firewalls'][index][k], v)
|
||||
|
||||
def test_create_firewall_with_rules(self):
|
||||
ctx = context.get_admin_context()
|
||||
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._create_and_get_router(),
|
||||
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, audited=False)
|
||||
|
||||
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):
|
||||
name = "new_firewall_policy1"
|
||||
attrs = self._get_test_firewall_policy_attrs(name, audited=False)
|
||||
|
||||
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._create_and_get_router(),
|
||||
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):
|
||||
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._create_and_get_router(),
|
||||
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):
|
||||
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._create_and_get_router(),
|
||||
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):
|
||||
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._create_and_get_router(),
|
||||
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)
|
||||
|
||||
def test_remove_rule_with_firewalls(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(router_id=self._create_and_get_router(),
|
||||
firewall_policy_id=fwp_id),
|
||||
self.firewall(router_id=self._create_and_get_router(),
|
||||
firewall_policy_id=fwp_id)) as (fw1, fw2):
|
||||
attrs['firewall_list'].insert(0, fw1['firewall']['id'])
|
||||
attrs['firewall_list'].insert(1, fw2['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)
|
|
@ -1,517 +0,0 @@
|
|||
# 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.
|
||||
#
|
||||
|
||||
import contextlib
|
||||
|
||||
import testtools
|
||||
from webob import exc as web_exc
|
||||
|
||||
from neutron.api.v2 import attributes
|
||||
from neutron import context
|
||||
from neutron.extensions import loadbalancer as lb
|
||||
from neutron import manager
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.tests.unit.db.loadbalancer import test_db_loadbalancer
|
||||
from neutron.tests.unit.vmware.vshield import test_edge_router
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
|
||||
LBAAS_PLUGIN_CLASS = "neutron.plugins.vmware.plugin.NsxServicePlugin"
|
||||
|
||||
|
||||
class LoadBalancerTestExtensionManager(
|
||||
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(LoadBalancerTestExtensionManager,
|
||||
self).get_resources()
|
||||
lb_attr_map = lb.RESOURCE_ATTRIBUTE_MAP.copy()
|
||||
for res in lb.RESOURCE_ATTRIBUTE_MAP.keys():
|
||||
attr_info = attributes.RESOURCE_ATTRIBUTE_MAP.get(res)
|
||||
if attr_info:
|
||||
lb.RESOURCE_ATTRIBUTE_MAP[res] = attr_info
|
||||
lb_resources = lb.Loadbalancer.get_resources()
|
||||
# restore the original resources once the controllers are created
|
||||
lb.RESOURCE_ATTRIBUTE_MAP = lb_attr_map
|
||||
resources.extend(lb_resources)
|
||||
return resources
|
||||
|
||||
|
||||
class TestLoadbalancerPlugin(
|
||||
test_db_loadbalancer.LoadBalancerPluginDbTestCase,
|
||||
test_edge_router.ServiceRouterTest):
|
||||
|
||||
def vcns_loadbalancer_patch(self):
|
||||
instance = self.vcns_instance
|
||||
instance.return_value.create_vip.side_effect = (
|
||||
self.fc2.create_vip)
|
||||
instance.return_value.get_vip.side_effect = (
|
||||
self.fc2.get_vip)
|
||||
instance.return_value.update_vip.side_effect = (
|
||||
self.fc2.update_vip)
|
||||
instance.return_value.delete_vip.side_effect = (
|
||||
self.fc2.delete_vip)
|
||||
instance.return_value.create_pool.side_effect = (
|
||||
self.fc2.create_pool)
|
||||
instance.return_value.get_pool.side_effect = (
|
||||
self.fc2.get_pool)
|
||||
instance.return_value.update_pool.side_effect = (
|
||||
self.fc2.update_pool)
|
||||
instance.return_value.delete_pool.side_effect = (
|
||||
self.fc2.delete_pool)
|
||||
instance.return_value.create_health_monitor.side_effect = (
|
||||
self.fc2.create_health_monitor)
|
||||
instance.return_value.get_health_monitor.side_effect = (
|
||||
self.fc2.get_health_monitor)
|
||||
instance.return_value.update_health_monitor.side_effect = (
|
||||
self.fc2.update_health_monitor)
|
||||
instance.return_value.delete_health_monitor.side_effect = (
|
||||
self.fc2.delete_health_monitor)
|
||||
instance.return_value.create_app_profile.side_effect = (
|
||||
self.fc2.create_app_profile)
|
||||
instance.return_value.update_app_profile.side_effect = (
|
||||
self.fc2.update_app_profile)
|
||||
instance.return_value.delete_app_profile.side_effect = (
|
||||
self.fc2.delete_app_profile)
|
||||
|
||||
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(TestLoadbalancerPlugin, self).setUp(
|
||||
ext_mgr=LoadBalancerTestExtensionManager(),
|
||||
lb_plugin=LBAAS_PLUGIN_CLASS)
|
||||
self.vcns_loadbalancer_patch()
|
||||
self.plugin = manager.NeutronManager.get_plugin()
|
||||
|
||||
def tearDown(self):
|
||||
super(TestLoadbalancerPlugin, self).tearDown()
|
||||
# Restore the global RESOURCE_ATTRIBUTE_MAP
|
||||
attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map
|
||||
self.ext_api = None
|
||||
self.plugin = None
|
||||
|
||||
def _create_and_get_router(self):
|
||||
req = self._create_router(self.fmt, self._tenant_id)
|
||||
res = self.deserialize(self.fmt, req)
|
||||
return res['router']['id']
|
||||
|
||||
def _get_vip_optional_args(self):
|
||||
args = super(TestLoadbalancerPlugin, self)._get_vip_optional_args()
|
||||
return args + ('router_id',)
|
||||
|
||||
def test_update_healthmonitor(self):
|
||||
keys = [('type', "TCP"),
|
||||
('tenant_id', self._tenant_id),
|
||||
('delay', 20),
|
||||
('timeout', 20),
|
||||
('max_retries', 2),
|
||||
('admin_state_up', False)]
|
||||
|
||||
with contextlib.nested(
|
||||
self.subnet(),
|
||||
self.health_monitor(),
|
||||
self.pool()
|
||||
) as (subnet, health_mon, pool):
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
with self.vip(
|
||||
router_id=self._create_and_get_router(),
|
||||
pool=pool, subnet=subnet):
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
health_mon, pool['pool']['id']
|
||||
)
|
||||
data = {'health_monitor': {'delay': 20,
|
||||
'timeout': 20,
|
||||
'max_retries': 2,
|
||||
'admin_state_up': False}}
|
||||
req = self.new_update_request(
|
||||
"health_monitors",
|
||||
data,
|
||||
health_mon['health_monitor']['id'])
|
||||
res = self.deserialize(
|
||||
self.fmt, req.get_response(self.ext_api))
|
||||
for k, v in keys:
|
||||
self.assertEqual(res['health_monitor'][k], v)
|
||||
|
||||
def test_create_vip(self, **extras):
|
||||
expected = {
|
||||
'name': 'vip1',
|
||||
'description': '',
|
||||
'protocol_port': 80,
|
||||
'protocol': 'HTTP',
|
||||
'connection_limit': -1,
|
||||
'admin_state_up': True,
|
||||
'status': 'ACTIVE',
|
||||
'router_id': self._create_and_get_router(),
|
||||
'tenant_id': self._tenant_id,
|
||||
}
|
||||
|
||||
expected.update(extras)
|
||||
|
||||
name = expected['name']
|
||||
|
||||
with contextlib.nested(
|
||||
self.subnet(),
|
||||
self.health_monitor(),
|
||||
self.pool()
|
||||
) as (subnet, monitor, pool):
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
expected['pool_id'] = pool['pool']['id']
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
monitor, pool['pool']['id']
|
||||
)
|
||||
with self.vip(
|
||||
router_id=expected['router_id'], name=name,
|
||||
pool=pool, subnet=subnet, **extras) as vip:
|
||||
for k in ('id', 'address', 'port_id', 'pool_id'):
|
||||
self.assertTrue(vip['vip'].get(k, None))
|
||||
self.assertEqual(
|
||||
dict((k, v)
|
||||
for k, v in vip['vip'].items() if k in expected),
|
||||
expected
|
||||
)
|
||||
|
||||
def test_create_vip_with_session_persistence(self):
|
||||
self.test_create_vip(session_persistence={'type': 'HTTP_COOKIE'})
|
||||
|
||||
def test_create_vip_with_invalid_persistence_method(self):
|
||||
with testtools.ExpectedException(web_exc.HTTPClientError):
|
||||
self.test_create_vip(
|
||||
protocol='TCP',
|
||||
session_persistence={'type': 'HTTP_COOKIE'})
|
||||
|
||||
def test_create_vips_with_same_names(self):
|
||||
new_router_id = self._create_and_get_router()
|
||||
with self.subnet() as subnet:
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
with contextlib.nested(
|
||||
self.vip(
|
||||
name='vip',
|
||||
router_id=new_router_id,
|
||||
subnet=subnet, protocol_port=80),
|
||||
self.vip(
|
||||
name='vip',
|
||||
router_id=new_router_id,
|
||||
subnet=subnet, protocol_port=81),
|
||||
self.vip(
|
||||
name='vip',
|
||||
router_id=new_router_id,
|
||||
subnet=subnet, protocol_port=82),
|
||||
) as (vip1, vip2, vip3):
|
||||
req = self.new_list_request('vips')
|
||||
res = self.deserialize(
|
||||
self.fmt, req.get_response(self.ext_api))
|
||||
for index in range(len(res['vips'])):
|
||||
self.assertEqual(res['vips'][index]['name'], 'vip')
|
||||
|
||||
def test_update_vip(self):
|
||||
name = 'new_vip'
|
||||
router_id = self._create_and_get_router()
|
||||
keys = [('router_id', router_id),
|
||||
('name', name),
|
||||
('address', "10.0.0.2"),
|
||||
('protocol_port', 80),
|
||||
('connection_limit', 100),
|
||||
('admin_state_up', False),
|
||||
('status', 'ACTIVE')]
|
||||
|
||||
with contextlib.nested(
|
||||
self.subnet(),
|
||||
self.health_monitor(),
|
||||
self.pool()
|
||||
) as (subnet, monitor, pool):
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
monitor, pool['pool']['id']
|
||||
)
|
||||
with self.vip(
|
||||
router_id=router_id, name=name,
|
||||
pool=pool, subnet=subnet) as vip:
|
||||
keys.append(('subnet_id', vip['vip']['subnet_id']))
|
||||
data = {'vip': {'name': name,
|
||||
'connection_limit': 100,
|
||||
'session_persistence':
|
||||
{'type': "APP_COOKIE",
|
||||
'cookie_name': "jesssionId"},
|
||||
'admin_state_up': False}}
|
||||
req = self.new_update_request(
|
||||
'vips', data, vip['vip']['id'])
|
||||
res = self.deserialize(self.fmt,
|
||||
req.get_response(self.ext_api))
|
||||
for k, v in keys:
|
||||
self.assertEqual(res['vip'][k], v)
|
||||
|
||||
def test_delete_vip(self):
|
||||
with contextlib.nested(
|
||||
self.subnet(),
|
||||
self.health_monitor(),
|
||||
self.pool()
|
||||
) as (subnet, monitor, pool):
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
monitor, pool['pool']['id']
|
||||
)
|
||||
with self.vip(
|
||||
router_id=self._create_and_get_router(),
|
||||
pool=pool, subnet=subnet, do_delete=False) as vip:
|
||||
req = self.new_delete_request('vips', vip['vip']['id'])
|
||||
res = req.get_response(self.ext_api)
|
||||
self.assertEqual(res.status_int, 204)
|
||||
|
||||
def test_delete_router_in_use_by_lbservice(self):
|
||||
router_id = self._create_and_get_router()
|
||||
with contextlib.nested(
|
||||
self.subnet(),
|
||||
self.health_monitor(),
|
||||
self.pool()
|
||||
) as (subnet, monitor, pool):
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
monitor, pool['pool']['id']
|
||||
)
|
||||
with self.vip(
|
||||
router_id=router_id,
|
||||
pool=pool, subnet=subnet):
|
||||
self._delete('routers', router_id,
|
||||
expected_code=web_exc.HTTPConflict.code)
|
||||
|
||||
def test_show_vip(self):
|
||||
router_id = self._create_and_get_router()
|
||||
name = "vip_show"
|
||||
keys = [('name', name),
|
||||
('protocol_port', 80),
|
||||
('protocol', 'HTTP'),
|
||||
('connection_limit', -1),
|
||||
('admin_state_up', True),
|
||||
('status', 'ACTIVE'),
|
||||
('router_id', router_id)]
|
||||
|
||||
with contextlib.nested(
|
||||
self.subnet(),
|
||||
self.health_monitor(),
|
||||
self.pool()
|
||||
) as (subnet, monitor, pool):
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
monitor, pool['pool']['id']
|
||||
)
|
||||
with self.vip(
|
||||
router_id=router_id, name=name,
|
||||
pool=pool, subnet=subnet) as vip:
|
||||
req = self.new_show_request('vips',
|
||||
vip['vip']['id'])
|
||||
res = self.deserialize(
|
||||
self.fmt, req.get_response(self.ext_api))
|
||||
for k, v in keys:
|
||||
self.assertEqual(res['vip'][k], v)
|
||||
|
||||
def test_list_vips(self):
|
||||
keys_list = []
|
||||
for i in range(3):
|
||||
keys_list.append({'name': "vip" + str(i),
|
||||
'router_id': self._create_and_get_router(),
|
||||
'protocol_port': 80 + i,
|
||||
'protocol': "HTTP",
|
||||
'status': "ACTIVE",
|
||||
'admin_state_up': True})
|
||||
|
||||
with self.subnet() as subnet:
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
with contextlib.nested(
|
||||
self.vip(
|
||||
router_id=keys_list[0]['router_id'], name='vip0',
|
||||
subnet=subnet, protocol_port=80),
|
||||
self.vip(
|
||||
router_id=keys_list[1]['router_id'], name='vip1',
|
||||
subnet=subnet, protocol_port=81),
|
||||
self.vip(
|
||||
router_id=keys_list[2]['router_id'], name='vip2',
|
||||
subnet=subnet, protocol_port=82),
|
||||
) as (vip1, vip2, vip3):
|
||||
self._test_list_with_sort(
|
||||
'vip',
|
||||
(vip1, vip2, vip3),
|
||||
[('protocol_port', 'asc'), ('name', 'desc')]
|
||||
)
|
||||
req = self.new_list_request('vips')
|
||||
res = self.deserialize(
|
||||
self.fmt, req.get_response(self.ext_api))
|
||||
self.assertEqual(len(res['vips']), 3)
|
||||
for index in range(len(res['vips'])):
|
||||
for k, v in keys_list[index].items():
|
||||
self.assertEqual(res['vips'][index][k], v)
|
||||
|
||||
def test_update_pool(self):
|
||||
data = {'pool': {'name': "new_pool",
|
||||
'admin_state_up': False}}
|
||||
with contextlib.nested(
|
||||
self.subnet(),
|
||||
self.health_monitor(),
|
||||
self.pool()
|
||||
) as (subnet, monitor, pool):
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
monitor, pool['pool']['id']
|
||||
)
|
||||
with self.vip(
|
||||
router_id=self._create_and_get_router(),
|
||||
pool=pool, subnet=subnet):
|
||||
req = self.new_update_request(
|
||||
'pools', data, pool['pool']['id'])
|
||||
res = self.deserialize(self.fmt,
|
||||
req.get_response(self.ext_api))
|
||||
for k, v in data['pool'].items():
|
||||
self.assertEqual(res['pool'][k], v)
|
||||
|
||||
def test_create_member(self):
|
||||
router_id = self._create_and_get_router()
|
||||
with contextlib.nested(
|
||||
self.subnet(),
|
||||
self.health_monitor(),
|
||||
self.pool()
|
||||
) as (subnet, monitor, pool):
|
||||
pool_id = pool['pool']['id']
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
monitor, pool['pool']['id']
|
||||
)
|
||||
with self.vip(
|
||||
router_id=router_id,
|
||||
pool=pool, subnet=subnet):
|
||||
with contextlib.nested(
|
||||
self.member(address='192.168.1.100',
|
||||
protocol_port=80,
|
||||
pool_id=pool_id),
|
||||
self.member(router_id=router_id,
|
||||
address='192.168.1.101',
|
||||
protocol_port=80,
|
||||
pool_id=pool_id)) as (member1, member2):
|
||||
req = self.new_show_request('pools',
|
||||
pool_id,
|
||||
fmt=self.fmt)
|
||||
pool_update = self.deserialize(
|
||||
self.fmt,
|
||||
req.get_response(self.ext_api)
|
||||
)
|
||||
self.assertIn(member1['member']['id'],
|
||||
pool_update['pool']['members'])
|
||||
self.assertIn(member2['member']['id'],
|
||||
pool_update['pool']['members'])
|
||||
|
||||
def _show_pool(self, pool_id):
|
||||
req = self.new_show_request('pools', pool_id, fmt=self.fmt)
|
||||
res = req.get_response(self.ext_api)
|
||||
self.assertEqual(web_exc.HTTPOk.code, res.status_int)
|
||||
return self.deserialize(self.fmt, res)
|
||||
|
||||
def test_update_member(self):
|
||||
with contextlib.nested(
|
||||
self.subnet(),
|
||||
self.health_monitor(),
|
||||
self.pool(name="pool1"),
|
||||
self.pool(name="pool2")
|
||||
) as (subnet, monitor, pool1, pool2):
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
monitor, pool1['pool']['id']
|
||||
)
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
monitor, pool2['pool']['id']
|
||||
)
|
||||
with self.vip(
|
||||
router_id=self._create_and_get_router(),
|
||||
pool=pool1, subnet=subnet):
|
||||
keys = [('address', "192.168.1.100"),
|
||||
('tenant_id', self._tenant_id),
|
||||
('protocol_port', 80),
|
||||
('weight', 10),
|
||||
('pool_id', pool2['pool']['id']),
|
||||
('admin_state_up', False),
|
||||
('status', 'ACTIVE')]
|
||||
with self.member(
|
||||
pool_id=pool1['pool']['id']) as member:
|
||||
|
||||
pool1_update = self._show_pool(pool1['pool']['id'])
|
||||
self.assertEqual(len(pool1_update['pool']['members']), 1)
|
||||
pool2_update = self._show_pool(pool2['pool']['id'])
|
||||
self.assertEqual(len(pool1_update['pool']['members']), 1)
|
||||
self.assertFalse(pool2_update['pool']['members'])
|
||||
|
||||
data = {'member': {'pool_id': pool2['pool']['id'],
|
||||
'weight': 10,
|
||||
'admin_state_up': False}}
|
||||
req = self.new_update_request('members',
|
||||
data,
|
||||
member['member']['id'])
|
||||
raw_res = req.get_response(self.ext_api)
|
||||
self.assertEqual(web_exc.HTTPOk.code, raw_res.status_int)
|
||||
res = self.deserialize(self.fmt, raw_res)
|
||||
for k, v in keys:
|
||||
self.assertEqual(res['member'][k], v)
|
||||
pool1_update = self._show_pool(pool1['pool']['id'])
|
||||
pool2_update = self._show_pool(pool2['pool']['id'])
|
||||
self.assertEqual(len(pool2_update['pool']['members']), 1)
|
||||
self.assertFalse(pool1_update['pool']['members'])
|
||||
|
||||
def test_delete_member(self):
|
||||
with contextlib.nested(
|
||||
self.subnet(),
|
||||
self.health_monitor(),
|
||||
self.pool()
|
||||
) as (subnet, monitor, pool):
|
||||
pool_id = pool['pool']['id']
|
||||
net_id = subnet['subnet']['network_id']
|
||||
self._set_net_external(net_id)
|
||||
self.plugin.create_pool_health_monitor(
|
||||
context.get_admin_context(),
|
||||
monitor, pool['pool']['id']
|
||||
)
|
||||
with self.vip(
|
||||
router_id=self._create_and_get_router(),
|
||||
pool=pool, subnet=subnet):
|
||||
with self.member(pool_id=pool_id,
|
||||
do_delete=False) as member:
|
||||
req = self.new_delete_request('members',
|
||||
member['member']['id'])
|
||||
res = req.get_response(self.ext_api)
|
||||
self.assertEqual(res.status_int, 204)
|
||||
pool_update = self._show_pool(pool['pool']['id'])
|
||||
self.assertFalse(pool_update['pool']['members'])
|
|
@ -1,338 +0,0 @@
|
|||
# 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.
|
||||
|
||||
import mock
|
||||
|
||||
from neutron import context
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.vmware.dbexts import vcns_db
|
||||
from neutron.plugins.vmware.vshield.common import exceptions as vcns_exc
|
||||
from neutron.plugins.vmware.vshield import vcns_driver
|
||||
from neutron.tests.unit import vmware
|
||||
from neutron.tests.unit.vmware.vshield import fake_vcns
|
||||
from neutron_lbaas.services.loadbalancer import constants as lb_constants
|
||||
from neutron_lbaas.tests.unit.db.loadbalancer import test_db_loadbalancer
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
|
||||
VSE_ID = 'edge-1'
|
||||
POOL_MAP_INFO = {
|
||||
'pool_id': None,
|
||||
'edge_id': VSE_ID,
|
||||
'pool_vseid': 'pool-1'}
|
||||
|
||||
VCNS_CONFIG_FILE = vmware.get_fake_conf("vcns.ini.test")
|
||||
|
||||
|
||||
class VcnsDriverTestCase(test_db_loadbalancer.LoadBalancerPluginDbTestCase):
|
||||
|
||||
def vcns_loadbalancer_patch(self):
|
||||
instance = self.mock_vcns.start()
|
||||
instance.return_value.create_vip.side_effect = (
|
||||
self.fc2.create_vip)
|
||||
instance.return_value.get_vip.side_effect = (
|
||||
self.fc2.get_vip)
|
||||
instance.return_value.update_vip.side_effect = (
|
||||
self.fc2.update_vip)
|
||||
instance.return_value.delete_vip.side_effect = (
|
||||
self.fc2.delete_vip)
|
||||
instance.return_value.create_pool.side_effect = (
|
||||
self.fc2.create_pool)
|
||||
instance.return_value.get_pool.side_effect = (
|
||||
self.fc2.get_pool)
|
||||
instance.return_value.update_pool.side_effect = (
|
||||
self.fc2.update_pool)
|
||||
instance.return_value.delete_pool.side_effect = (
|
||||
self.fc2.delete_pool)
|
||||
instance.return_value.create_health_monitor.side_effect = (
|
||||
self.fc2.create_health_monitor)
|
||||
instance.return_value.get_health_monitor.side_effect = (
|
||||
self.fc2.get_health_monitor)
|
||||
instance.return_value.update_health_monitor.side_effect = (
|
||||
self.fc2.update_health_monitor)
|
||||
instance.return_value.delete_health_monitor.side_effect = (
|
||||
self.fc2.delete_health_monitor)
|
||||
instance.return_value.create_app_profile.side_effect = (
|
||||
self.fc2.create_app_profile)
|
||||
instance.return_value.update_app_profile.side_effect = (
|
||||
self.fc2.update_app_profile)
|
||||
instance.return_value.delete_app_profile.side_effect = (
|
||||
self.fc2.delete_app_profile)
|
||||
self.pool_id = None
|
||||
self.vip_id = None
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.config_parse(args=['--config-file', VCNS_CONFIG_FILE])
|
||||
# mock vcns
|
||||
self.fc2 = fake_vcns.FakeVcns(unique_router_name=False)
|
||||
self.mock_vcns = mock.patch(vmware.VCNS_NAME, autospec=True)
|
||||
self.vcns_loadbalancer_patch()
|
||||
|
||||
self.driver = vcns_driver.VcnsDriver(mock.Mock())
|
||||
|
||||
super(VcnsDriverTestCase, self).setUp()
|
||||
self.addCleanup(self.fc2.reset_all)
|
||||
self.addCleanup(self.mock_vcns.stop)
|
||||
|
||||
def tearDown(self):
|
||||
super(VcnsDriverTestCase, self).tearDown()
|
||||
|
||||
|
||||
class TestEdgeLbDriver(VcnsDriverTestCase):
|
||||
|
||||
def test_create_and_get_vip(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.pool(do_delete=False) as pool:
|
||||
self.pool_id = pool['pool']['id']
|
||||
POOL_MAP_INFO['pool_id'] = pool['pool']['id']
|
||||
vcns_db.add_vcns_edge_pool_binding(ctx.session, POOL_MAP_INFO)
|
||||
with self.vip(pool=pool) as res:
|
||||
vip_create = res['vip']
|
||||
self.driver.create_vip(ctx, VSE_ID, vip_create)
|
||||
vip_get = self.driver.get_vip(ctx, vip_create['id'])
|
||||
for k, v in vip_get.iteritems():
|
||||
self.assertEqual(vip_create[k], v)
|
||||
|
||||
def test_create_two_vips_with_same_name(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.pool(do_delete=False) as pool:
|
||||
self.pool_id = pool['pool']['id']
|
||||
POOL_MAP_INFO['pool_id'] = pool['pool']['id']
|
||||
vcns_db.add_vcns_edge_pool_binding(ctx.session, POOL_MAP_INFO)
|
||||
with self.vip(pool=pool) as res:
|
||||
vip_create = res['vip']
|
||||
self.driver.create_vip(ctx, VSE_ID, vip_create)
|
||||
self.assertRaises(vcns_exc.Forbidden,
|
||||
self.driver.create_vip,
|
||||
ctx, VSE_ID, vip_create)
|
||||
|
||||
def test_convert_app_profile(self):
|
||||
app_profile_name = 'app_profile_name'
|
||||
sess_persist1 = {'type': "SOURCE_IP"}
|
||||
sess_persist2 = {'type': "HTTP_COOKIE"}
|
||||
sess_persist3 = {'type': "APP_COOKIE",
|
||||
'cookie_name': "app_cookie_name"}
|
||||
# protocol is HTTP and type is SOURCE_IP
|
||||
expect_vcns_app_profile1 = {
|
||||
'insertXForwardedFor': False,
|
||||
'name': app_profile_name,
|
||||
'serverSslEnabled': False,
|
||||
'sslPassthrough': False,
|
||||
'template': lb_constants.PROTOCOL_HTTP,
|
||||
'persistence': {'method': 'sourceip'}}
|
||||
vcns_app_profile = self.driver._convert_app_profile(
|
||||
app_profile_name, sess_persist1, lb_constants.PROTOCOL_HTTP)
|
||||
for k, v in expect_vcns_app_profile1.iteritems():
|
||||
self.assertEqual(vcns_app_profile[k], v)
|
||||
# protocol is HTTP and type is HTTP_COOKIE and APP_COOKIE
|
||||
expect_vcns_app_profile2 = {
|
||||
'insertXForwardedFor': False,
|
||||
'name': app_profile_name,
|
||||
'serverSslEnabled': False,
|
||||
'sslPassthrough': False,
|
||||
'template': lb_constants.PROTOCOL_HTTP,
|
||||
'persistence': {'method': 'cookie',
|
||||
'cookieName': 'default_cookie_name',
|
||||
'cookieMode': 'insert'}}
|
||||
vcns_app_profile = self.driver._convert_app_profile(
|
||||
app_profile_name, sess_persist2, lb_constants.PROTOCOL_HTTP)
|
||||
for k, v in expect_vcns_app_profile2.iteritems():
|
||||
self.assertEqual(vcns_app_profile[k], v)
|
||||
expect_vcns_app_profile3 = {
|
||||
'insertXForwardedFor': False,
|
||||
'name': app_profile_name,
|
||||
'serverSslEnabled': False,
|
||||
'sslPassthrough': False,
|
||||
'template': lb_constants.PROTOCOL_HTTP,
|
||||
'persistence': {'method': 'cookie',
|
||||
'cookieName': sess_persist3['cookie_name'],
|
||||
'cookieMode': 'app'}}
|
||||
vcns_app_profile = self.driver._convert_app_profile(
|
||||
app_profile_name, sess_persist3, lb_constants.PROTOCOL_HTTP)
|
||||
for k, v in expect_vcns_app_profile3.iteritems():
|
||||
self.assertEqual(vcns_app_profile[k], v)
|
||||
# protocol is HTTPS and type is SOURCE_IP
|
||||
expect_vcns_app_profile1 = {
|
||||
'insertXForwardedFor': False,
|
||||
'name': app_profile_name,
|
||||
'serverSslEnabled': False,
|
||||
'sslPassthrough': True,
|
||||
'template': lb_constants.PROTOCOL_HTTPS,
|
||||
'persistence': {'method': 'sourceip'}}
|
||||
vcns_app_profile = self.driver._convert_app_profile(
|
||||
app_profile_name, sess_persist1, lb_constants.PROTOCOL_HTTPS)
|
||||
for k, v in expect_vcns_app_profile1.iteritems():
|
||||
self.assertEqual(vcns_app_profile[k], v)
|
||||
# protocol is HTTPS, and type isn't SOURCE_IP
|
||||
self.assertRaises(vcns_exc.VcnsBadRequest,
|
||||
self.driver._convert_app_profile,
|
||||
app_profile_name,
|
||||
sess_persist2, lb_constants.PROTOCOL_HTTPS)
|
||||
self.assertRaises(vcns_exc.VcnsBadRequest,
|
||||
self.driver._convert_app_profile,
|
||||
app_profile_name,
|
||||
sess_persist3, lb_constants.PROTOCOL_HTTPS)
|
||||
# protocol is TCP and type is SOURCE_IP
|
||||
expect_vcns_app_profile1 = {
|
||||
'insertXForwardedFor': False,
|
||||
'name': app_profile_name,
|
||||
'serverSslEnabled': False,
|
||||
'sslPassthrough': False,
|
||||
'template': lb_constants.PROTOCOL_TCP,
|
||||
'persistence': {'method': 'sourceip'}}
|
||||
vcns_app_profile = self.driver._convert_app_profile(
|
||||
app_profile_name, sess_persist1, lb_constants.PROTOCOL_TCP)
|
||||
for k, v in expect_vcns_app_profile1.iteritems():
|
||||
self.assertEqual(vcns_app_profile[k], v)
|
||||
# protocol is TCP, and type isn't SOURCE_IP
|
||||
self.assertRaises(vcns_exc.VcnsBadRequest,
|
||||
self.driver._convert_app_profile,
|
||||
app_profile_name,
|
||||
sess_persist2, lb_constants.PROTOCOL_TCP)
|
||||
self.assertRaises(vcns_exc.VcnsBadRequest,
|
||||
self.driver._convert_app_profile,
|
||||
app_profile_name,
|
||||
sess_persist3, lb_constants.PROTOCOL_TCP)
|
||||
|
||||
def test_update_vip(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.pool(do_delete=False) as pool:
|
||||
self.pool_id = pool['pool']['id']
|
||||
POOL_MAP_INFO['pool_id'] = pool['pool']['id']
|
||||
vcns_db.add_vcns_edge_pool_binding(ctx.session, POOL_MAP_INFO)
|
||||
with self.vip(pool=pool) as res:
|
||||
vip_create = res['vip']
|
||||
self.driver.create_vip(ctx, VSE_ID, vip_create)
|
||||
vip_update = {'id': vip_create['id'],
|
||||
'pool_id': pool['pool']['id'],
|
||||
'name': 'update_name',
|
||||
'description': 'description',
|
||||
'address': 'update_address',
|
||||
'port_id': 'update_port_id',
|
||||
'protocol_port': 'protocol_port',
|
||||
'protocol': 'update_protocol'}
|
||||
self.driver.update_vip(ctx, vip_update)
|
||||
vip_get = self.driver.get_vip(ctx, vip_create['id'])
|
||||
for k, v in vip_get.iteritems():
|
||||
if k in vip_update:
|
||||
self.assertEqual(vip_update[k], v)
|
||||
|
||||
def test_delete_vip(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.pool(do_delete=False) as pool:
|
||||
self.pool_id = pool['pool']['id']
|
||||
POOL_MAP_INFO['pool_id'] = pool['pool']['id']
|
||||
vcns_db.add_vcns_edge_pool_binding(ctx.session, POOL_MAP_INFO)
|
||||
with self.vip(pool=pool) as res:
|
||||
vip_create = res['vip']
|
||||
self.driver.create_vip(ctx, VSE_ID, vip_create)
|
||||
self.driver.delete_vip(ctx, vip_create['id'])
|
||||
self.assertRaises(vcns_exc.VcnsNotFound,
|
||||
self.driver.get_vip,
|
||||
ctx,
|
||||
vip_create['id'])
|
||||
|
||||
#Test Pool Operation
|
||||
def test_create_and_get_pool(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.pool(do_delete=False) as p:
|
||||
self.pool_id = p['pool']['id']
|
||||
pool_create = p['pool']
|
||||
self.driver.create_pool(ctx, VSE_ID, pool_create, [])
|
||||
pool_get = self.driver.get_pool(ctx, pool_create['id'], VSE_ID)
|
||||
for k, v in pool_get.iteritems():
|
||||
self.assertEqual(pool_create[k], v)
|
||||
|
||||
def test_create_two_pools_with_same_name(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.pool(do_delete=False) as p:
|
||||
self.pool_id = p['pool']['id']
|
||||
pool_create = p['pool']
|
||||
self.driver.create_pool(ctx, VSE_ID, pool_create, [])
|
||||
self.assertRaises(vcns_exc.Forbidden,
|
||||
self.driver.create_pool,
|
||||
ctx, VSE_ID, pool_create, [])
|
||||
|
||||
def test_update_pool(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.pool(do_delete=False) as p:
|
||||
self.pool_id = p['pool']['id']
|
||||
pool_create = p['pool']
|
||||
self.driver.create_pool(ctx, VSE_ID, pool_create, [])
|
||||
pool_update = {'id': pool_create['id'],
|
||||
'lb_method': 'lb_method',
|
||||
'name': 'update_name',
|
||||
'members': [],
|
||||
'health_monitors': []}
|
||||
self.driver.update_pool(ctx, VSE_ID, pool_update, [])
|
||||
pool_get = self.driver.get_pool(ctx, pool_create['id'], VSE_ID)
|
||||
for k, v in pool_get.iteritems():
|
||||
if k in pool_update:
|
||||
self.assertEqual(pool_update[k], v)
|
||||
|
||||
def test_delete_pool(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.pool(do_delete=False) as p:
|
||||
self.pool_id = p['pool']['id']
|
||||
pool_create = p['pool']
|
||||
self.driver.create_pool(ctx, VSE_ID, pool_create, [])
|
||||
self.driver.delete_pool(ctx, pool_create['id'], VSE_ID)
|
||||
self.assertRaises(vcns_exc.VcnsNotFound,
|
||||
self.driver.get_pool,
|
||||
ctx,
|
||||
pool_create['id'],
|
||||
VSE_ID)
|
||||
|
||||
def test_create_and_get_monitor(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.health_monitor(do_delete=False) as m:
|
||||
monitor_create = m['health_monitor']
|
||||
self.driver.create_health_monitor(ctx, VSE_ID, monitor_create)
|
||||
monitor_get = self.driver.get_health_monitor(
|
||||
ctx, monitor_create['id'], VSE_ID)
|
||||
for k, v in monitor_get.iteritems():
|
||||
self.assertEqual(monitor_create[k], v)
|
||||
|
||||
def test_update_health_monitor(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.health_monitor(do_delete=False) as m:
|
||||
monitor_create = m['health_monitor']
|
||||
self.driver.create_health_monitor(
|
||||
ctx, VSE_ID, monitor_create)
|
||||
monitor_update = {'id': monitor_create['id'],
|
||||
'delay': 'new_delay',
|
||||
'timeout': "new_timeout",
|
||||
'type': 'type',
|
||||
'max_retries': "max_retries"}
|
||||
self.driver.update_health_monitor(
|
||||
ctx, VSE_ID, monitor_create, monitor_update)
|
||||
monitor_get = self.driver.get_health_monitor(
|
||||
ctx, monitor_create['id'], VSE_ID)
|
||||
for k, v in monitor_get.iteritems():
|
||||
if k in monitor_update:
|
||||
self.assertEqual(monitor_update[k], v)
|
||||
|
||||
def test_delete_health_monitor(self):
|
||||
ctx = context.get_admin_context()
|
||||
with self.health_monitor(do_delete=False) as m:
|
||||
monitor_create = m['health_monitor']
|
||||
self.driver.create_health_monitor(ctx, VSE_ID, monitor_create)
|
||||
self.driver.delete_health_monitor(
|
||||
ctx, monitor_create['id'], VSE_ID)
|
||||
self.assertRaises(vcns_exc.VcnsNotFound,
|
||||
self.driver.get_health_monitor,
|
||||
ctx,
|
||||
monitor_create['id'],
|
||||
VSE_ID)
|
|
@ -1,394 +0,0 @@
|
|||
# Copyright 2014 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.
|
||||
|
||||
import contextlib
|
||||
import copy
|
||||
|
||||
import webob.exc
|
||||
|
||||
from neutron.api.v2 import attributes
|
||||
from neutron.db.vpn import vpn_db
|
||||
from neutron.extensions import vpnaas
|
||||
from neutron import manager
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.tests.unit.db.vpn import test_db_vpnaas
|
||||
from neutron.tests.unit.vmware.vshield import test_edge_router
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
|
||||
|
||||
class VPNTestExtensionManager(
|
||||
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(VPNTestExtensionManager, self).get_resources()
|
||||
vpn_attr_map = copy.deepcopy(vpnaas.RESOURCE_ATTRIBUTE_MAP)
|
||||
for res in vpnaas.RESOURCE_ATTRIBUTE_MAP.keys():
|
||||
attr_info = attributes.RESOURCE_ATTRIBUTE_MAP.get(res)
|
||||
if attr_info:
|
||||
vpnaas.RESOURCE_ATTRIBUTE_MAP[res] = attr_info
|
||||
vpn_resources = vpnaas.Vpnaas.get_resources()
|
||||
# restore the original resources once the controllers are created
|
||||
vpnaas.RESOURCE_ATTRIBUTE_MAP = vpn_attr_map
|
||||
resources.extend(vpn_resources)
|
||||
return resources
|
||||
|
||||
|
||||
class TestVpnPlugin(test_db_vpnaas.VPNTestMixin,
|
||||
test_edge_router.ServiceRouterTest):
|
||||
|
||||
def vcns_vpn_patch(self):
|
||||
instance = self.vcns_instance
|
||||
instance.return_value.update_ipsec_config.side_effect = (
|
||||
self.fc2.update_ipsec_config)
|
||||
instance.return_value.get_ipsec_config.side_effect = (
|
||||
self.fc2.get_ipsec_config)
|
||||
instance.return_value.delete_ipsec_config.side_effect = (
|
||||
self.fc2.delete_ipsec_config)
|
||||
|
||||
def setUp(self):
|
||||
# Save the global RESOURCE_ATTRIBUTE_MAP
|
||||
self.saved_attr_map = {}
|
||||
for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.items():
|
||||
self.saved_attr_map[resource] = attrs.copy()
|
||||
|
||||
super(TestVpnPlugin, self).setUp(ext_mgr=VPNTestExtensionManager())
|
||||
self.vcns_vpn_patch()
|
||||
self.plugin = manager.NeutronManager.get_plugin()
|
||||
self.router_id = None
|
||||
|
||||
def tearDown(self):
|
||||
super(TestVpnPlugin, self).tearDown()
|
||||
# Restore the global RESOURCE_ATTRIBUTE_MAP
|
||||
attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map
|
||||
self.ext_api = None
|
||||
self.plugin = None
|
||||
|
||||
@contextlib.contextmanager
|
||||
def router(self, vlan_id=None):
|
||||
with self._create_l3_ext_network(vlan_id) as net:
|
||||
with self.subnet(cidr='100.0.0.0/24', network=net) as s:
|
||||
data = {'router': {'tenant_id': self._tenant_id}}
|
||||
data['router']['service_router'] = True
|
||||
router_req = self.new_create_request('routers', data, self.fmt)
|
||||
|
||||
res = router_req.get_response(self.ext_api)
|
||||
router = self.deserialize(self.fmt, res)
|
||||
self._add_external_gateway_to_router(
|
||||
router['router']['id'],
|
||||
s['subnet']['network_id'])
|
||||
router = self._show('routers', router['router']['id'])
|
||||
yield router
|
||||
|
||||
self._delete('routers', router['router']['id'])
|
||||
|
||||
def test_create_vpnservice(self, **extras):
|
||||
"""Test case to create a vpnservice."""
|
||||
description = 'my-vpn-service'
|
||||
expected = {'name': 'vpnservice1',
|
||||
'description': 'my-vpn-service',
|
||||
'admin_state_up': True,
|
||||
'status': 'ACTIVE',
|
||||
'tenant_id': self._tenant_id, }
|
||||
|
||||
expected.update(extras)
|
||||
with self.subnet(cidr='10.2.0.0/24') as subnet:
|
||||
with self.router() as router:
|
||||
expected['router_id'] = router['router']['id']
|
||||
expected['subnet_id'] = subnet['subnet']['id']
|
||||
name = expected['name']
|
||||
with self.vpnservice(name=name,
|
||||
subnet=subnet,
|
||||
router=router,
|
||||
description=description,
|
||||
**extras) as vpnservice:
|
||||
self.assertEqual(dict((k, v) for k, v in
|
||||
vpnservice['vpnservice'].items()
|
||||
if k in expected),
|
||||
expected)
|
||||
|
||||
def test_create_vpnservices_with_same_router(self, **extras):
|
||||
"""Test case to create two vpnservices with same router."""
|
||||
with self.subnet(cidr='10.2.0.0/24') as subnet:
|
||||
with self.router() as router:
|
||||
with self.vpnservice(name='vpnservice1',
|
||||
subnet=subnet,
|
||||
router=router):
|
||||
res = self._create_vpnservice(
|
||||
'json', 'vpnservice2', True,
|
||||
router_id=(router['router']['id']),
|
||||
subnet_id=(subnet['subnet']['id']))
|
||||
self.assertEqual(
|
||||
res.status_int, webob.exc.HTTPConflict.code)
|
||||
|
||||
def test_update_vpnservice(self):
|
||||
"""Test case to update a vpnservice."""
|
||||
name = 'new_vpnservice1'
|
||||
expected = [('name', name)]
|
||||
with contextlib.nested(
|
||||
self.subnet(cidr='10.2.0.0/24'),
|
||||
self.router()) as (subnet, router):
|
||||
with self.vpnservice(name=name,
|
||||
subnet=subnet,
|
||||
router=router) as vpnservice:
|
||||
expected.append(('subnet_id',
|
||||
vpnservice['vpnservice']['subnet_id']))
|
||||
expected.append(('router_id',
|
||||
vpnservice['vpnservice']['router_id']))
|
||||
data = {'vpnservice': {'name': name,
|
||||
'admin_state_up': False}}
|
||||
expected.append(('admin_state_up', False))
|
||||
self._set_active(vpn_db.VPNService,
|
||||
vpnservice['vpnservice']['id'])
|
||||
req = self.new_update_request(
|
||||
'vpnservices',
|
||||
data,
|
||||
vpnservice['vpnservice']['id'])
|
||||
res = self.deserialize(self.fmt,
|
||||
req.get_response(self.ext_api))
|
||||
for k, v in expected:
|
||||
self.assertEqual(res['vpnservice'][k], v)
|
||||
|
||||
def test_delete_vpnservice(self):
|
||||
"""Test case to delete a vpnservice."""
|
||||
with self.subnet(cidr='10.2.0.0/24') as subnet:
|
||||
with self.router() as router:
|
||||
with self.vpnservice(name='vpnservice',
|
||||
subnet=subnet,
|
||||
router=router,
|
||||
do_delete=False) as vpnservice:
|
||||
req = self.new_delete_request(
|
||||
'vpnservices', vpnservice['vpnservice']['id'])
|
||||
res = req.get_response(self.ext_api)
|
||||
self.assertEqual(res.status_int, 204)
|
||||
|
||||
def test_delete_router_in_use_by_vpnservice(self):
|
||||
"""Test delete router in use by vpn service."""
|
||||
with self.subnet(cidr='10.2.0.0/24') as subnet:
|
||||
with self.router() as router:
|
||||
with self.vpnservice(subnet=subnet,
|
||||
router=router):
|
||||
self._delete('routers', router['router']['id'],
|
||||
expected_code=webob.exc.HTTPConflict.code)
|
||||
|
||||
def _test_create_ipsec_site_connection(self, key_overrides=None,
|
||||
ike_key_overrides=None,
|
||||
ipsec_key_overrides=None,
|
||||
setup_overrides=None,
|
||||
expected_status_int=200):
|
||||
"""Create ipsec_site_connection and check results."""
|
||||
params = {'ikename': 'ikepolicy1',
|
||||
'ipsecname': 'ipsecpolicy1',
|
||||
'vpnsname': 'vpnservice1',
|
||||
'subnet_cidr': '10.2.0.0/24',
|
||||
'subnet_version': 4}
|
||||
if setup_overrides:
|
||||
params.update(setup_overrides)
|
||||
expected = {'name': 'connection1',
|
||||
'description': 'my-ipsec-connection',
|
||||
'peer_address': '192.168.1.10',
|
||||
'peer_id': '192.168.1.10',
|
||||
'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'],
|
||||
'initiator': 'bi-directional',
|
||||
'mtu': 1500,
|
||||
'tenant_id': self._tenant_id,
|
||||
'psk': 'abcd',
|
||||
'status': 'ACTIVE',
|
||||
'admin_state_up': True}
|
||||
if key_overrides:
|
||||
expected.update(key_overrides)
|
||||
|
||||
ike_expected = {'name': params['ikename'],
|
||||
'auth_algorithm': 'sha1',
|
||||
'encryption_algorithm': 'aes-128',
|
||||
'ike_version': 'v1',
|
||||
'pfs': 'group5'}
|
||||
if ike_key_overrides:
|
||||
ike_expected.update(ike_key_overrides)
|
||||
|
||||
ipsec_expected = {'name': params['ipsecname'],
|
||||
'auth_algorithm': 'sha1',
|
||||
'encryption_algorithm': 'aes-128',
|
||||
'pfs': 'group5'}
|
||||
if ipsec_key_overrides:
|
||||
ipsec_expected.update(ipsec_key_overrides)
|
||||
|
||||
dpd = {'action': 'hold',
|
||||
'interval': 40,
|
||||
'timeout': 120}
|
||||
with contextlib.nested(
|
||||
self.ikepolicy(self.fmt, ike_expected['name'],
|
||||
ike_expected['auth_algorithm'],
|
||||
ike_expected['encryption_algorithm'],
|
||||
ike_version=ike_expected['ike_version'],
|
||||
pfs=ike_expected['pfs']),
|
||||
self.ipsecpolicy(self.fmt, ipsec_expected['name'],
|
||||
ipsec_expected['auth_algorithm'],
|
||||
ipsec_expected['encryption_algorithm'],
|
||||
pfs=ipsec_expected['pfs']),
|
||||
self.subnet(cidr=params['subnet_cidr'],
|
||||
ip_version=params['subnet_version']),
|
||||
self.router()) as (
|
||||
ikepolicy, ipsecpolicy, subnet, router):
|
||||
with self.vpnservice(name=params['vpnsname'], subnet=subnet,
|
||||
router=router) as vpnservice1:
|
||||
expected['ikepolicy_id'] = ikepolicy['ikepolicy']['id']
|
||||
expected['ipsecpolicy_id'] = (
|
||||
ipsecpolicy['ipsecpolicy']['id']
|
||||
)
|
||||
expected['vpnservice_id'] = (
|
||||
vpnservice1['vpnservice']['id']
|
||||
)
|
||||
try:
|
||||
with self.ipsec_site_connection(
|
||||
self.fmt,
|
||||
expected['name'],
|
||||
expected['peer_address'],
|
||||
expected['peer_id'],
|
||||
expected['peer_cidrs'],
|
||||
expected['mtu'],
|
||||
expected['psk'],
|
||||
expected['initiator'],
|
||||
dpd['action'],
|
||||
dpd['interval'],
|
||||
dpd['timeout'],
|
||||
vpnservice1,
|
||||
ikepolicy,
|
||||
ipsecpolicy,
|
||||
expected['admin_state_up'],
|
||||
description=expected['description']
|
||||
) as ipsec_site_connection:
|
||||
if expected_status_int != 200:
|
||||
self.fail("Expected failure on create")
|
||||
self._check_ipsec_site_connection(
|
||||
ipsec_site_connection['ipsec_site_connection'],
|
||||
expected,
|
||||
dpd)
|
||||
except webob.exc.HTTPClientError as ce:
|
||||
self.assertEqual(ce.code, expected_status_int)
|
||||
|
||||
def test_create_ipsec_site_connection(self, **extras):
|
||||
"""Test case to create an ipsec_site_connection."""
|
||||
self._test_create_ipsec_site_connection(key_overrides=extras)
|
||||
|
||||
def test_create_ipsec_site_connection_invalid_ikepolicy(self):
|
||||
self._test_create_ipsec_site_connection(
|
||||
ike_key_overrides={'ike_version': 'v2'},
|
||||
expected_status_int=400)
|
||||
|
||||
def test_create_ipsec_site_connection_invalid_ipsecpolicy(self):
|
||||
self._test_create_ipsec_site_connection(
|
||||
ipsec_key_overrides={'encryption_algorithm': 'aes-192'},
|
||||
expected_status_int=400)
|
||||
self._test_create_ipsec_site_connection(
|
||||
ipsec_key_overrides={'pfs': 'group14'},
|
||||
expected_status_int=400)
|
||||
|
||||
def _test_update_ipsec_site_connection(self,
|
||||
update={'name': 'new name'},
|
||||
overrides=None,
|
||||
expected_status_int=200):
|
||||
"""Creates and then updates ipsec_site_connection."""
|
||||
expected = {'name': 'new_ipsec_site_connection',
|
||||
'ikename': 'ikepolicy1',
|
||||
'ipsecname': 'ipsecpolicy1',
|
||||
'vpnsname': 'vpnservice1',
|
||||
'description': 'my-ipsec-connection',
|
||||
'peer_address': '192.168.1.10',
|
||||
'peer_id': '192.168.1.10',
|
||||
'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'],
|
||||
'initiator': 'bi-directional',
|
||||
'mtu': 1500,
|
||||
'tenant_id': self._tenant_id,
|
||||
'psk': 'abcd',
|
||||
'status': 'ACTIVE',
|
||||
'admin_state_up': True,
|
||||
'action': 'hold',
|
||||
'interval': 40,
|
||||
'timeout': 120,
|
||||
'subnet_cidr': '10.2.0.0/24',
|
||||
'subnet_version': 4,
|
||||
'make_active': True}
|
||||
if overrides:
|
||||
expected.update(overrides)
|
||||
|
||||
with contextlib.nested(
|
||||
self.ikepolicy(name=expected['ikename']),
|
||||
self.ipsecpolicy(name=expected['ipsecname']),
|
||||
self.subnet(cidr=expected['subnet_cidr'],
|
||||
ip_version=expected['subnet_version']),
|
||||
self.router()
|
||||
) as (ikepolicy, ipsecpolicy, subnet, router):
|
||||
with self.vpnservice(name=expected['vpnsname'], subnet=subnet,
|
||||
router=router) as vpnservice1:
|
||||
expected['vpnservice_id'] = vpnservice1['vpnservice']['id']
|
||||
expected['ikepolicy_id'] = ikepolicy['ikepolicy']['id']
|
||||
expected['ipsecpolicy_id'] = ipsecpolicy['ipsecpolicy']['id']
|
||||
with self.ipsec_site_connection(
|
||||
self.fmt,
|
||||
expected['name'],
|
||||
expected['peer_address'],
|
||||
expected['peer_id'],
|
||||
expected['peer_cidrs'],
|
||||
expected['mtu'],
|
||||
expected['psk'],
|
||||
expected['initiator'],
|
||||
expected['action'],
|
||||
expected['interval'],
|
||||
expected['timeout'],
|
||||
vpnservice1,
|
||||
ikepolicy,
|
||||
ipsecpolicy,
|
||||
expected['admin_state_up'],
|
||||
description=expected['description']
|
||||
) as ipsec_site_connection:
|
||||
data = {'ipsec_site_connection': update}
|
||||
if expected.get('make_active'):
|
||||
self._set_active(
|
||||
vpn_db.IPsecSiteConnection,
|
||||
(ipsec_site_connection['ipsec_site_connection']
|
||||
['id']))
|
||||
req = self.new_update_request(
|
||||
'ipsec-site-connections',
|
||||
data,
|
||||
ipsec_site_connection['ipsec_site_connection']['id'])
|
||||
res = req.get_response(self.ext_api)
|
||||
self.assertEqual(expected_status_int, res.status_int)
|
||||
if expected_status_int == 200:
|
||||
res_dict = self.deserialize(self.fmt, res)
|
||||
for k, v in update.items():
|
||||
self.assertEqual(
|
||||
res_dict['ipsec_site_connection'][k], v)
|
||||
|
||||
def test_update_ipsec_site_connection(self):
|
||||
"""Test case for valid updates to IPSec site connection."""
|
||||
dpd = {'action': 'hold',
|
||||
'interval': 40,
|
||||
'timeout': 120}
|
||||
self._test_update_ipsec_site_connection(update={'dpd': dpd})
|
||||
self._test_update_ipsec_site_connection(update={'mtu': 2000})
|
||||
|
||||
def test_delete_ipsec_site_connection(self):
|
||||
"""Test case to delete a ipsec_site_connection."""
|
||||
with self.ipsec_site_connection(
|
||||
do_delete=False) as ipsec_site_connection:
|
||||
req = self.new_delete_request(
|
||||
'ipsec-site-connections',
|
||||
ipsec_site_connection['ipsec_site_connection']['id']
|
||||
)
|
||||
res = req.get_response(self.ext_api)
|
||||
self.assertEqual(res.status_int, 204)
|
Loading…
Reference in New Issue