Merge "Add NVP port security implementation"
This commit is contained in:
commit
3c334853ed
@ -0,0 +1,73 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
#
|
||||||
|
# Copyright 2013 OpenStack LLC
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""inital port security
|
||||||
|
|
||||||
|
Revision ID: 1149d7de0cfa
|
||||||
|
Revises: 1b693c095aa3
|
||||||
|
Create Date: 2013-01-22 14:05:20.696502
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '1149d7de0cfa'
|
||||||
|
down_revision = '1b693c095aa3'
|
||||||
|
|
||||||
|
# Change to ['*'] if this migration applies to all plugins
|
||||||
|
|
||||||
|
migration_for_plugins = [
|
||||||
|
'quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2'
|
||||||
|
]
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
from quantum.db import migration
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(active_plugin=None, options=None):
|
||||||
|
if not migration.should_run(active_plugin, migration_for_plugins):
|
||||||
|
return
|
||||||
|
|
||||||
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('networksecuritybindings',
|
||||||
|
sa.Column('network_id', sa.String(length=36),
|
||||||
|
nullable=False),
|
||||||
|
sa.Column('port_security_enabled', sa.Boolean(),
|
||||||
|
nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['network_id'], ['networks.id'],
|
||||||
|
ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('network_id'))
|
||||||
|
op.create_table('portsecuritybindings',
|
||||||
|
sa.Column('port_id', sa.String(length=36),
|
||||||
|
nullable=False),
|
||||||
|
sa.Column('port_security_enabled', sa.Boolean(),
|
||||||
|
nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['port_id'], ['ports.id'],
|
||||||
|
ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('port_id'))
|
||||||
|
### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade(active_plugin=None, options=None):
|
||||||
|
if not migration.should_run(active_plugin, migration_for_plugins):
|
||||||
|
return
|
||||||
|
|
||||||
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_table('portsecuritybindings')
|
||||||
|
op.drop_table('networksecuritybindings')
|
||||||
|
### end Alembic commands ###
|
@ -34,8 +34,10 @@ from quantum.common import topics
|
|||||||
from quantum.db import api as db
|
from quantum.db import api as db
|
||||||
from quantum.db import db_base_plugin_v2
|
from quantum.db import db_base_plugin_v2
|
||||||
from quantum.db import dhcp_rpc_base
|
from quantum.db import dhcp_rpc_base
|
||||||
|
from quantum.db import portsecurity_db
|
||||||
# NOTE: quota_db cannot be removed, it is for db model
|
# NOTE: quota_db cannot be removed, it is for db model
|
||||||
from quantum.db import quota_db
|
from quantum.db import quota_db
|
||||||
|
from quantum.extensions import portsecurity as psec
|
||||||
from quantum.extensions import providernet as pnet
|
from quantum.extensions import providernet as pnet
|
||||||
from quantum.openstack.common import cfg
|
from quantum.openstack.common import cfg
|
||||||
from quantum.openstack.common import rpc
|
from quantum.openstack.common import rpc
|
||||||
@ -105,16 +107,22 @@ class NVPRpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin):
|
|||||||
return q_rpc.PluginRpcDispatcher([self])
|
return q_rpc.PluginRpcDispatcher([self])
|
||||||
|
|
||||||
|
|
||||||
class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||||
|
portsecurity_db.PortSecurityDbMixin):
|
||||||
"""
|
"""
|
||||||
NvpPluginV2 is a Quantum plugin that provides L2 Virtual Network
|
NvpPluginV2 is a Quantum plugin that provides L2 Virtual Network
|
||||||
functionality using NVP.
|
functionality using NVP.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
supported_extension_aliases = ["provider", "quotas"]
|
supported_extension_aliases = ["provider", "quotas", "port-security"]
|
||||||
# Default controller cluster
|
# Default controller cluster
|
||||||
default_cluster = None
|
default_cluster = None
|
||||||
|
|
||||||
|
provider_network_view = "extension:provider_network:view"
|
||||||
|
provider_network_set = "extension:provider_network:set"
|
||||||
|
port_security_enabled_create = "create_port:port_security_enabled"
|
||||||
|
port_security_enabled_update = "update_port:port_security_enabled"
|
||||||
|
|
||||||
def __init__(self, loglevel=None):
|
def __init__(self, loglevel=None):
|
||||||
if loglevel:
|
if loglevel:
|
||||||
logging.basicConfig(level=loglevel)
|
logging.basicConfig(level=loglevel)
|
||||||
@ -216,15 +224,11 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
else:
|
else:
|
||||||
return self.default_cluster
|
return self.default_cluster
|
||||||
|
|
||||||
def _check_provider_view_auth(self, context, network):
|
def _check_view_auth(self, context, resource, action):
|
||||||
return policy.check(context,
|
return policy.check(context, action, resource)
|
||||||
"extension:provider_network:view",
|
|
||||||
network)
|
|
||||||
|
|
||||||
def _enforce_provider_set_auth(self, context, network):
|
def _enforce_set_auth(self, context, resource, action):
|
||||||
return policy.enforce(context,
|
return policy.enforce(context, action, resource)
|
||||||
"extension:provider_network:set",
|
|
||||||
network)
|
|
||||||
|
|
||||||
def _handle_provider_create(self, context, attrs):
|
def _handle_provider_create(self, context, attrs):
|
||||||
# NOTE(salvatore-orlando): This method has been borrowed from
|
# NOTE(salvatore-orlando): This method has been borrowed from
|
||||||
@ -240,7 +244,7 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Authorize before exposing plugin details to client
|
# Authorize before exposing plugin details to client
|
||||||
self._enforce_provider_set_auth(context, attrs)
|
self._enforce_set_auth(context, attrs, self.provider_network_set)
|
||||||
err_msg = None
|
err_msg = None
|
||||||
if not network_type_set:
|
if not network_type_set:
|
||||||
err_msg = _("%s required") % pnet.NETWORK_TYPE
|
err_msg = _("%s required") % pnet.NETWORK_TYPE
|
||||||
@ -273,7 +277,7 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
# which should be specified in physical_network
|
# which should be specified in physical_network
|
||||||
|
|
||||||
def _extend_network_dict_provider(self, context, network, binding=None):
|
def _extend_network_dict_provider(self, context, network, binding=None):
|
||||||
if self._check_provider_view_auth(context, network):
|
if self._check_view_auth(context, network, self.provider_network_view):
|
||||||
if not binding:
|
if not binding:
|
||||||
binding = nicira_db.get_network_binding(context.session,
|
binding = nicira_db.get_network_binding(context.session,
|
||||||
network['id'])
|
network['id'])
|
||||||
@ -365,6 +369,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
new_net = super(NvpPluginV2, self).create_network(context,
|
new_net = super(NvpPluginV2, self).create_network(context,
|
||||||
network)
|
network)
|
||||||
|
self._process_network_create_port_security(context,
|
||||||
|
network['network'])
|
||||||
if net_data.get(pnet.NETWORK_TYPE):
|
if net_data.get(pnet.NETWORK_TYPE):
|
||||||
net_binding = nicira_db.add_network_binding(
|
net_binding = nicira_db.add_network_binding(
|
||||||
context.session, new_net['id'],
|
context.session, new_net['id'],
|
||||||
@ -373,6 +379,7 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
net_data.get(pnet.SEGMENTATION_ID))
|
net_data.get(pnet.SEGMENTATION_ID))
|
||||||
self._extend_network_dict_provider(context, new_net,
|
self._extend_network_dict_provider(context, new_net,
|
||||||
net_binding)
|
net_binding)
|
||||||
|
self._extend_network_port_security_dict(context, new_net)
|
||||||
return new_net
|
return new_net
|
||||||
|
|
||||||
def delete_network(self, context, id):
|
def delete_network(self, context, id):
|
||||||
@ -409,6 +416,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
network = self._get_network(context, id)
|
network = self._get_network(context, id)
|
||||||
net_result = self._make_network_dict(network, None)
|
net_result = self._make_network_dict(network, None)
|
||||||
self._extend_network_dict_provider(context, net_result)
|
self._extend_network_dict_provider(context, net_result)
|
||||||
|
self._extend_network_port_security_dict(context, net_result)
|
||||||
|
|
||||||
# verify the fabric status of the corresponding
|
# verify the fabric status of the corresponding
|
||||||
# logical switch(es) in nvp
|
# logical switch(es) in nvp
|
||||||
try:
|
try:
|
||||||
@ -441,6 +450,7 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
super(NvpPluginV2, self).get_networks(context, filters))
|
super(NvpPluginV2, self).get_networks(context, filters))
|
||||||
for net in quantum_lswitches:
|
for net in quantum_lswitches:
|
||||||
self._extend_network_dict_provider(context, net)
|
self._extend_network_dict_provider(context, net)
|
||||||
|
self._extend_network_port_security_dict(context, net)
|
||||||
|
|
||||||
if context.is_admin and not filters.get("tenant_id"):
|
if context.is_admin and not filters.get("tenant_id"):
|
||||||
tenant_filter = ""
|
tenant_filter = ""
|
||||||
@ -516,10 +526,23 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
raise q_exc.NotImplementedError(_("admin_state_up=False "
|
raise q_exc.NotImplementedError(_("admin_state_up=False "
|
||||||
"networks are not "
|
"networks are not "
|
||||||
"supported."))
|
"supported."))
|
||||||
return super(NvpPluginV2, self).update_network(context, id, network)
|
with context.session.begin(subtransactions=True):
|
||||||
|
quantum_db = super(NvpPluginV2, self).update_network(
|
||||||
|
context, id, network)
|
||||||
|
if psec.PORTSECURITY in network['network']:
|
||||||
|
self._update_network_security_binding(
|
||||||
|
context, id, network['network'][psec.PORTSECURITY])
|
||||||
|
self._extend_network_port_security_dict(
|
||||||
|
context, quantum_db)
|
||||||
|
return quantum_db
|
||||||
|
|
||||||
def get_ports(self, context, filters=None, fields=None):
|
def get_ports(self, context, filters=None, fields=None):
|
||||||
quantum_lports = super(NvpPluginV2, self).get_ports(context, filters)
|
with context.session.begin(subtransactions=True):
|
||||||
|
quantum_lports = super(NvpPluginV2, self).get_ports(
|
||||||
|
context, filters)
|
||||||
|
for quantum_lport in quantum_lports:
|
||||||
|
self._extend_port_port_security_dict(context, quantum_lport)
|
||||||
|
|
||||||
vm_filter = ""
|
vm_filter = ""
|
||||||
tenant_filter = ""
|
tenant_filter = ""
|
||||||
# This is used when calling delete_network. Quantum checks to see if
|
# This is used when calling delete_network. Quantum checks to see if
|
||||||
@ -607,12 +630,28 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
return lports
|
return lports
|
||||||
|
|
||||||
def create_port(self, context, port):
|
def create_port(self, context, port):
|
||||||
|
# If PORTSECURITY is not the default value ATTR_NOT_SPECIFIED
|
||||||
|
# then we pass the port to the policy engine. The reason why we don't
|
||||||
|
# pass the value to the policy engine when the port is
|
||||||
|
# ATTR_NOT_SPECIFIED is for the case where a port is created on a
|
||||||
|
# shared network that is not owned by the tenant.
|
||||||
|
# TODO(arosen) fix policy engine to do this for us automatically.
|
||||||
|
if attributes.is_attr_set(port['port'].get(psec.PORTSECURITY)):
|
||||||
|
self._enforce_set_auth(context, port,
|
||||||
|
self.port_security_enabled_create)
|
||||||
|
port_data = port['port']
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
# First we allocate port in quantum database
|
# First we allocate port in quantum database
|
||||||
quantum_db = super(NvpPluginV2, self).create_port(context, port)
|
quantum_db = super(NvpPluginV2, self).create_port(context, port)
|
||||||
# Update fields obtained from quantum db (eg: MAC address)
|
# Update fields obtained from quantum db (eg: MAC address)
|
||||||
port["port"].update(quantum_db)
|
port["port"].update(quantum_db)
|
||||||
port_data = port['port']
|
|
||||||
|
# port security extension checks
|
||||||
|
(port_security, has_ip) = self._determine_port_security_and_has_ip(
|
||||||
|
context, port_data)
|
||||||
|
port_data[psec.PORTSECURITY] = port_security
|
||||||
|
self._process_port_security_create(context, port_data)
|
||||||
|
# provider networking extension checks
|
||||||
# Fetch the network and network binding from Quantum db
|
# Fetch the network and network binding from Quantum db
|
||||||
network = self._get_network(context, port_data['network_id'])
|
network = self._get_network(context, port_data['network_id'])
|
||||||
network_binding = nicira_db.get_network_binding(
|
network_binding = nicira_db.get_network_binding(
|
||||||
@ -639,7 +678,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
port_data['device_id'],
|
port_data['device_id'],
|
||||||
port_data['admin_state_up'],
|
port_data['admin_state_up'],
|
||||||
port_data['mac_address'],
|
port_data['mac_address'],
|
||||||
port_data['fixed_ips'])
|
port_data['fixed_ips'],
|
||||||
|
port_data[psec.PORTSECURITY])
|
||||||
# Get NVP ls uuid for quantum network
|
# Get NVP ls uuid for quantum network
|
||||||
nvplib.plug_interface(cluster, selected_lswitch['uuid'],
|
nvplib.plug_interface(cluster, selected_lswitch['uuid'],
|
||||||
lport['uuid'], "VifAttachment",
|
lport['uuid'], "VifAttachment",
|
||||||
@ -660,20 +700,50 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2):
|
|||||||
LOG.debug(_("create_port completed on NVP for tenant "
|
LOG.debug(_("create_port completed on NVP for tenant "
|
||||||
"%(tenant_id)s: (%(id)s)"), port_data)
|
"%(tenant_id)s: (%(id)s)"), port_data)
|
||||||
|
|
||||||
return port_data
|
self._extend_port_port_security_dict(context, port_data)
|
||||||
|
return port_data
|
||||||
|
|
||||||
def update_port(self, context, id, port):
|
def update_port(self, context, id, port):
|
||||||
params = {}
|
self._enforce_set_auth(context, port,
|
||||||
port_quantum = super(NvpPluginV2, self).get_port(context, id)
|
self.port_security_enabled_update)
|
||||||
port_nvp, cluster = (
|
tenant_id = self._get_tenant_id_for_create(context, port)
|
||||||
nvplib.get_port_by_quantum_tag(self.clusters.itervalues(),
|
with context.session.begin(subtransactions=True):
|
||||||
port_quantum["network_id"], id))
|
ret_port = super(NvpPluginV2, self).update_port(
|
||||||
params["cluster"] = cluster
|
context, id, port)
|
||||||
params["port"] = port_quantum
|
# copy values over
|
||||||
LOG.debug(_("Update port request: %s"), params)
|
ret_port.update(port['port'])
|
||||||
nvplib.update_port(port_quantum['network_id'],
|
|
||||||
port_nvp['uuid'], **params)
|
# Handle port security
|
||||||
return super(NvpPluginV2, self).update_port(context, id, port)
|
if psec.PORTSECURITY in port['port']:
|
||||||
|
self._update_port_security_binding(
|
||||||
|
context, id, ret_port[psec.PORTSECURITY])
|
||||||
|
# populate with value
|
||||||
|
else:
|
||||||
|
ret_port[psec.PORTSECURITY] = self._get_port_security_binding(
|
||||||
|
context, id)
|
||||||
|
|
||||||
|
port_nvp, cluster = (
|
||||||
|
nvplib.get_port_by_quantum_tag(self.clusters.itervalues(),
|
||||||
|
ret_port["network_id"], id))
|
||||||
|
LOG.debug(_("Update port request: %s"), port)
|
||||||
|
nvplib.update_port(cluster, ret_port['network_id'],
|
||||||
|
port_nvp['uuid'], id, tenant_id,
|
||||||
|
ret_port['name'], ret_port['device_id'],
|
||||||
|
ret_port['admin_state_up'],
|
||||||
|
ret_port['mac_address'],
|
||||||
|
ret_port['fixed_ips'],
|
||||||
|
ret_port[psec.PORTSECURITY])
|
||||||
|
|
||||||
|
# Update the port status from nvp. If we fail here hide it since
|
||||||
|
# the port was successfully updated but we were not able to retrieve
|
||||||
|
# the status.
|
||||||
|
try:
|
||||||
|
ret_port['status'] = nvplib.get_port_status(
|
||||||
|
cluster, ret_port['network_id'], port_nvp['uuid'])
|
||||||
|
except:
|
||||||
|
LOG.warn(_("Unable to retrieve port status for: %s."),
|
||||||
|
port_nvp['uuid'])
|
||||||
|
return ret_port
|
||||||
|
|
||||||
def delete_port(self, context, id):
|
def delete_port(self, context, id):
|
||||||
# TODO(salvatore-orlando): pass only actual cluster
|
# TODO(salvatore-orlando): pass only actual cluster
|
||||||
|
@ -290,7 +290,6 @@ def get_all_networks(cluster, tenant_id, networks):
|
|||||||
raise exception.QuantumException()
|
raise exception.QuantumException()
|
||||||
if not resp_obj:
|
if not resp_obj:
|
||||||
return []
|
return []
|
||||||
lswitches = json.loads(resp_obj)["results"]
|
|
||||||
networks_result = copy(networks)
|
networks_result = copy(networks)
|
||||||
return networks_result
|
return networks_result
|
||||||
|
|
||||||
@ -371,7 +370,7 @@ def get_port_by_quantum_tag(clusters, lswitch, quantum_tag):
|
|||||||
for c in clusters:
|
for c in clusters:
|
||||||
try:
|
try:
|
||||||
res_obj = do_single_request('GET', query, cluster=c)
|
res_obj = do_single_request('GET', query, cluster=c)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
res = json.loads(res_obj)
|
res = json.loads(res_obj)
|
||||||
if len(res["results"]) == 1:
|
if len(res["results"]) == 1:
|
||||||
@ -417,44 +416,56 @@ def get_port(cluster, network, port, relations=None):
|
|||||||
return port
|
return port
|
||||||
|
|
||||||
|
|
||||||
def update_port(network, port_id, **params):
|
def _configure_extensions(lport_obj, mac_address, fixed_ips,
|
||||||
cluster = params["cluster"]
|
port_security_enabled):
|
||||||
lport_obj = {}
|
lport_obj['allowed_address_pairs'] = []
|
||||||
|
if port_security_enabled:
|
||||||
|
for fixed_ip in fixed_ips:
|
||||||
|
ip_address = fixed_ip.get('ip_address')
|
||||||
|
if ip_address:
|
||||||
|
lport_obj['allowed_address_pairs'].append(
|
||||||
|
{'mac_address': mac_address, 'ip_address': ip_address})
|
||||||
|
# add address pair allowing src_ip 0.0.0.0 to leave
|
||||||
|
# this is required for outgoing dhcp request
|
||||||
|
lport_obj["allowed_address_pairs"].append(
|
||||||
|
{"mac_address": mac_address,
|
||||||
|
"ip_address": "0.0.0.0"})
|
||||||
|
|
||||||
admin_state_up = params['port'].get('admin_state_up')
|
|
||||||
name = params["port"].get("name")
|
|
||||||
device_id = params["port"].get("device_id")
|
|
||||||
if admin_state_up:
|
|
||||||
lport_obj["admin_status_enabled"] = admin_state_up
|
|
||||||
if name:
|
|
||||||
lport_obj["display_name"] = name
|
|
||||||
|
|
||||||
if device_id:
|
def update_port(cluster, lswitch_uuid, lport_uuid, quantum_port_id, tenant_id,
|
||||||
# device_id can be longer than 40 so we rehash it
|
display_name, device_id, admin_status_enabled,
|
||||||
device_id = hashlib.sha1(device_id).hexdigest()
|
mac_address=None, fixed_ips=None, port_security_enabled=None):
|
||||||
lport_obj["tags"] = (
|
|
||||||
[dict(scope='os_tid', tag=params["port"].get("tenant_id")),
|
|
||||||
dict(scope='q_port_id', tag=params["port"]["id"]),
|
|
||||||
dict(scope='vm_id', tag=device_id)])
|
|
||||||
|
|
||||||
uri = "/ws.v1/lswitch/" + network + "/lport/" + port_id
|
# device_id can be longer than 40 so we rehash it
|
||||||
|
hashed_device_id = hashlib.sha1(device_id).hexdigest()
|
||||||
|
lport_obj = dict(
|
||||||
|
admin_status_enabled=admin_status_enabled,
|
||||||
|
display_name=display_name,
|
||||||
|
tags=[dict(scope='os_tid', tag=tenant_id),
|
||||||
|
dict(scope='q_port_id', tag=quantum_port_id),
|
||||||
|
dict(scope='vm_id', tag=hashed_device_id)])
|
||||||
|
|
||||||
|
_configure_extensions(lport_obj, mac_address, fixed_ips,
|
||||||
|
port_security_enabled)
|
||||||
|
|
||||||
|
path = "/ws.v1/lswitch/" + lswitch_uuid + "/lport/" + lport_uuid
|
||||||
try:
|
try:
|
||||||
resp_obj = do_single_request("PUT", uri, json.dumps(lport_obj),
|
resp_obj = do_single_request("PUT", path, json.dumps(lport_obj),
|
||||||
cluster=cluster)
|
cluster=cluster)
|
||||||
except NvpApiClient.ResourceNotFound as e:
|
except NvpApiClient.ResourceNotFound as e:
|
||||||
LOG.error(_("Port or Network not found, Error: %s"), str(e))
|
LOG.error(_("Port or Network not found, Error: %s"), str(e))
|
||||||
raise exception.PortNotFound(port_id=port_id, net_id=network)
|
raise exception.PortNotFound(port_id=lport_uuid, net_id=lswitch_uuid)
|
||||||
except NvpApiClient.NvpApiException as e:
|
except NvpApiClient.NvpApiException as e:
|
||||||
raise exception.QuantumException()
|
raise exception.QuantumException()
|
||||||
|
result = json.loads(resp_obj)
|
||||||
obj = json.loads(resp_obj)
|
LOG.debug(_("Updated logical port %(result)s on logical swtich %(uuid)s"),
|
||||||
obj["port-op-status"] = get_port_status(cluster, network, obj["uuid"])
|
{'result': result['uuid'], 'uuid': lswitch_uuid})
|
||||||
return obj
|
return result
|
||||||
|
|
||||||
|
|
||||||
def create_lport(cluster, lswitch_uuid, tenant_id, quantum_port_id,
|
def create_lport(cluster, lswitch_uuid, tenant_id, quantum_port_id,
|
||||||
display_name, device_id, admin_status_enabled,
|
display_name, device_id, admin_status_enabled,
|
||||||
mac_address=None, fixed_ips=None):
|
mac_address=None, fixed_ips=None, port_security_enabled=None):
|
||||||
""" Creates a logical port on the assigned logical switch """
|
""" Creates a logical port on the assigned logical switch """
|
||||||
# device_id can be longer than 40 so we rehash it
|
# device_id can be longer than 40 so we rehash it
|
||||||
hashed_device_id = hashlib.sha1(device_id).hexdigest()
|
hashed_device_id = hashlib.sha1(device_id).hexdigest()
|
||||||
@ -465,6 +476,10 @@ def create_lport(cluster, lswitch_uuid, tenant_id, quantum_port_id,
|
|||||||
dict(scope='q_port_id', tag=quantum_port_id),
|
dict(scope='q_port_id', tag=quantum_port_id),
|
||||||
dict(scope='vm_id', tag=hashed_device_id)],
|
dict(scope='vm_id', tag=hashed_device_id)],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_configure_extensions(lport_obj, mac_address, fixed_ips,
|
||||||
|
port_security_enabled)
|
||||||
|
|
||||||
path = _build_uri_path(LPORT_RESOURCE, parent_resource_id=lswitch_uuid)
|
path = _build_uri_path(LPORT_RESOURCE, parent_resource_id=lswitch_uuid)
|
||||||
try:
|
try:
|
||||||
resp_obj = do_single_request("POST", path,
|
resp_obj = do_single_request("POST", path,
|
||||||
|
@ -27,6 +27,8 @@ from quantum.openstack.common import cfg
|
|||||||
from quantum.plugins.nicira.nicira_nvp_plugin import nvplib
|
from quantum.plugins.nicira.nicira_nvp_plugin import nvplib
|
||||||
from quantum.tests.unit.nicira import fake_nvpapiclient
|
from quantum.tests.unit.nicira import fake_nvpapiclient
|
||||||
import quantum.tests.unit.test_db_plugin as test_plugin
|
import quantum.tests.unit.test_db_plugin as test_plugin
|
||||||
|
import quantum.tests.unit.test_extension_portsecurity as psec
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
NICIRA_PKG_PATH = 'quantum.plugins.nicira.nicira_nvp_plugin'
|
NICIRA_PKG_PATH = 'quantum.plugins.nicira.nicira_nvp_plugin'
|
||||||
@ -152,3 +154,34 @@ class TestNiciraNetworksV2(test_plugin.TestNetworksV2,
|
|||||||
with self.assertRaises(webob.exc.HTTPClientError) as ctx_manager:
|
with self.assertRaises(webob.exc.HTTPClientError) as ctx_manager:
|
||||||
self._test_create_bridge_network(vlan_id=5000)
|
self._test_create_bridge_network(vlan_id=5000)
|
||||||
self.assertEquals(ctx_manager.exception.code, 400)
|
self.assertEquals(ctx_manager.exception.code, 400)
|
||||||
|
|
||||||
|
|
||||||
|
class NiciraPortSecurityTestCase(psec.PortSecurityDBTestCase):
|
||||||
|
|
||||||
|
_plugin_name = ('%s.QuantumPlugin.NvpPluginV2' % NICIRA_PKG_PATH)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
etc_path = os.path.join(os.path.dirname(__file__), 'etc')
|
||||||
|
test_lib.test_config['config_files'] = [os.path.join(etc_path,
|
||||||
|
'nvp.ini.test')]
|
||||||
|
# mock nvp api client
|
||||||
|
fc = fake_nvpapiclient.FakeClient(etc_path)
|
||||||
|
self.mock_nvpapi = mock.patch('%s.NvpApiClient.NVPApiHelper'
|
||||||
|
% NICIRA_PKG_PATH, autospec=True)
|
||||||
|
instance = self.mock_nvpapi.start()
|
||||||
|
instance.return_value.login.return_value = "the_cookie"
|
||||||
|
|
||||||
|
def _fake_request(*args, **kwargs):
|
||||||
|
return fc.fake_request(*args, **kwargs)
|
||||||
|
|
||||||
|
instance.return_value.request.side_effect = _fake_request
|
||||||
|
super(NiciraPortSecurityTestCase, self).setUp(self._plugin_name)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(NiciraPortSecurityTestCase, self).tearDown()
|
||||||
|
self.mock_nvpapi.stop()
|
||||||
|
|
||||||
|
|
||||||
|
class TestNiciraPortSecurity(psec.TestPortSecurity,
|
||||||
|
NiciraPortSecurityTestCase):
|
||||||
|
pass
|
||||||
|
Loading…
x
Reference in New Issue
Block a user