You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1180 lines
54 KiB
1180 lines
54 KiB
# Copyright 2014 Alcatel-Lucent USA Inc. |
|
# |
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
# not use this file except in compliance with the License. You may obtain |
|
# a copy of the License at |
|
# |
|
# http://www.apache.org/licenses/LICENSE-2.0 |
|
# |
|
# Unless required by applicable law or agreed to in writing, software |
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
# License for the specific language governing permissions and limitations |
|
# under the License. |
|
# |
|
# @author: Ronak Shah, Nuage Networks, Alcatel-Lucent USA Inc. |
|
|
|
|
|
import re |
|
|
|
import netaddr |
|
from oslo.config import cfg |
|
from sqlalchemy.orm import exc |
|
|
|
from neutron.api import extensions as neutron_extensions |
|
from neutron.api.v2 import attributes |
|
from neutron.common import constants as os_constants |
|
from neutron.common import exceptions as n_exc |
|
from neutron.common import utils |
|
from neutron.db import api as db |
|
from neutron.db import db_base_plugin_v2 |
|
from neutron.db import external_net_db |
|
from neutron.db import extraroute_db |
|
from neutron.db import l3_db |
|
from neutron.db import quota_db # noqa |
|
from neutron.db import securitygroups_db as sg_db |
|
from neutron.extensions import external_net |
|
from neutron.extensions import l3 |
|
from neutron.extensions import portbindings |
|
from neutron.extensions import securitygroup as ext_sg |
|
from neutron.openstack.common import excutils |
|
from neutron.openstack.common import importutils |
|
from neutron.openstack.common import lockutils |
|
from neutron.plugins.nuage.common import config |
|
from neutron.plugins.nuage.common import constants |
|
from neutron.plugins.nuage.common import exceptions as nuage_exc |
|
from neutron.plugins.nuage import extensions |
|
from neutron.plugins.nuage.extensions import netpartition |
|
from neutron.plugins.nuage import nuagedb |
|
from neutron import policy |
|
|
|
|
|
class NuagePlugin(db_base_plugin_v2.NeutronDbPluginV2, |
|
external_net_db.External_net_db_mixin, |
|
extraroute_db.ExtraRoute_db_mixin, |
|
l3_db.L3_NAT_db_mixin, |
|
netpartition.NetPartitionPluginBase, |
|
sg_db.SecurityGroupDbMixin): |
|
"""Class that implements Nuage Networks' plugin functionality.""" |
|
supported_extension_aliases = ["router", "binding", "external-net", |
|
"net-partition", "nuage-router", |
|
"nuage-subnet", "quotas", |
|
"extraroute", "security-group"] |
|
|
|
binding_view = "extension:port_binding:view" |
|
|
|
def __init__(self): |
|
super(NuagePlugin, self).__init__() |
|
neutron_extensions.append_api_extensions_path(extensions.__path__) |
|
config.nuage_register_cfg_opts() |
|
self.nuageclient_init() |
|
net_partition = cfg.CONF.RESTPROXY.default_net_partition_name |
|
self._create_default_net_partition(net_partition) |
|
|
|
def nuageclient_init(self): |
|
server = cfg.CONF.RESTPROXY.server |
|
serverauth = cfg.CONF.RESTPROXY.serverauth |
|
serverssl = cfg.CONF.RESTPROXY.serverssl |
|
base_uri = cfg.CONF.RESTPROXY.base_uri |
|
auth_resource = cfg.CONF.RESTPROXY.auth_resource |
|
organization = cfg.CONF.RESTPROXY.organization |
|
nuageclient = importutils.import_module('nuagenetlib.nuageclient') |
|
self.nuageclient = nuageclient.NuageClient(server, base_uri, |
|
serverssl, serverauth, |
|
auth_resource, |
|
organization) |
|
|
|
def _resource_finder(self, context, for_resource, resource, user_req): |
|
match = re.match(attributes.UUID_PATTERN, user_req[resource]) |
|
if match: |
|
obj_lister = getattr(self, "get_%s" % resource) |
|
found_resource = obj_lister(context, user_req[resource]) |
|
if not found_resource: |
|
msg = (_("%(resource)s with id %(resource_id)s does not " |
|
"exist") % {'resource': resource, |
|
'resource_id': user_req[resource]}) |
|
raise n_exc.BadRequest(resource=for_resource, msg=msg) |
|
else: |
|
filter = {'name': [user_req[resource]]} |
|
obj_lister = getattr(self, "get_%ss" % resource) |
|
found_resource = obj_lister(context, filters=filter) |
|
if not found_resource: |
|
msg = (_("Either %(resource)s %(req_resource)s not found " |
|
"or you dont have credential to access it") |
|
% {'resource': resource, |
|
'req_resource': user_req[resource]}) |
|
raise n_exc.BadRequest(resource=for_resource, msg=msg) |
|
if len(found_resource) > 1: |
|
msg = (_("More than one entry found for %(resource)s " |
|
"%(req_resource)s. Use id instead") |
|
% {'resource': resource, |
|
'req_resource': user_req[resource]}) |
|
raise n_exc.BadRequest(resource=for_resource, msg=msg) |
|
found_resource = found_resource[0] |
|
return found_resource |
|
|
|
def _create_update_port(self, context, port, |
|
netpart_id, parent_id): |
|
filters = {'device_id': [port['device_id']]} |
|
ports = self.get_ports(context, filters) |
|
net_partition = nuagedb.get_net_partition_by_id(context.session, |
|
netpart_id) |
|
params = { |
|
'port_id': port['id'], |
|
'id': port['device_id'], |
|
'mac': port['mac_address'], |
|
'parent_id': parent_id, |
|
'net_partition': net_partition, |
|
'ip': port['fixed_ips'][0]['ip_address'], |
|
'no_of_ports': len(ports), |
|
'tenant': port['tenant_id'], |
|
} |
|
|
|
nuage_vm = self.nuageclient.create_vms(params) |
|
if nuage_vm: |
|
if port['fixed_ips'][0]['ip_address'] != str(nuage_vm['ip']): |
|
self._update_port_ip(context, port, nuage_vm['ip']) |
|
|
|
def _get_router_by_subnet(self, context, subnet_id): |
|
filters = { |
|
'fixed_ips': {'subnet_id': [subnet_id]}, |
|
'device_owner': [os_constants.DEVICE_OWNER_ROUTER_INTF] |
|
} |
|
router_port = self.get_ports(context, filters=filters) |
|
if not router_port: |
|
msg = (_("Router for subnet %s not found ") % subnet_id) |
|
raise n_exc.BadRequest(resource='port', msg=msg) |
|
return router_port[0]['device_id'] |
|
|
|
def _process_port_create_security_group(self, context, port, |
|
sec_group): |
|
if not attributes.is_attr_set(sec_group): |
|
port[ext_sg.SECURITYGROUPS] = [] |
|
return |
|
port_id = port['id'] |
|
with context.session.begin(subtransactions=True): |
|
for sg_id in sec_group: |
|
super(NuagePlugin, |
|
self)._create_port_security_group_binding(context, |
|
port_id, |
|
sg_id) |
|
try: |
|
vptag_vport_list = [] |
|
for sg_id in sec_group: |
|
params = { |
|
'neutron_port_id': port_id |
|
} |
|
nuage_port = self.nuageclient.get_nuage_port_by_id(params) |
|
if nuage_port and nuage_port.get('nuage_vport_id'): |
|
nuage_vport_id = nuage_port['nuage_vport_id'] |
|
sg = self._get_security_group(context, sg_id) |
|
sg_rules = self.get_security_group_rules( |
|
context, |
|
{'security_group_id': [sg_id]}) |
|
sg_params = { |
|
'nuage_port': nuage_port, |
|
'sg': sg, |
|
'sg_rules': sg_rules |
|
} |
|
nuage_vptag_id = ( |
|
self.nuageclient.process_port_create_security_group( |
|
sg_params)) |
|
vptag_vport = { |
|
'nuage_vporttag_id': nuage_vptag_id |
|
} |
|
vptag_vport_list.append(vptag_vport) |
|
|
|
if vptag_vport_list: |
|
params = { |
|
'vptag_vport_list': vptag_vport_list, |
|
'nuage_vport_id': nuage_vport_id |
|
} |
|
self.nuageclient.update_nuage_vport(params) |
|
except Exception: |
|
with excutils.save_and_reraise_exception(): |
|
for sg_id in sec_group: |
|
super(NuagePlugin, |
|
self)._delete_port_security_group_bindings(context, |
|
port_id) |
|
# Convert to list as a set might be passed here and |
|
# this has to be serialized |
|
port[ext_sg.SECURITYGROUPS] = (list(sec_group) if sec_group else []) |
|
|
|
def _delete_port_security_group_bindings(self, context, port_id): |
|
super(NuagePlugin, |
|
self)._delete_port_security_group_bindings(context, port_id) |
|
self.nuageclient.delete_port_security_group_bindings(port_id) |
|
|
|
@lockutils.synchronized('create_port', 'nuage-port', external=True) |
|
def create_port(self, context, port): |
|
session = context.session |
|
with session.begin(subtransactions=True): |
|
p = port['port'] |
|
self._ensure_default_security_group_on_port(context, port) |
|
port = super(NuagePlugin, self).create_port(context, port) |
|
device_owner = port.get('device_owner', None) |
|
if device_owner not in constants.AUTO_CREATE_PORT_OWNERS: |
|
if 'fixed_ips' not in port or len(port['fixed_ips']) == 0: |
|
return self._extend_port_dict_binding(context, port) |
|
subnet_id = port['fixed_ips'][0]['subnet_id'] |
|
subnet_mapping = nuagedb.get_subnet_l2dom_by_id(session, |
|
subnet_id) |
|
if subnet_mapping: |
|
port_prefix = constants.NOVA_PORT_OWNER_PREF |
|
if port['device_owner'].startswith(port_prefix): |
|
#This request is coming from nova |
|
try: |
|
self._create_update_port( |
|
context, |
|
port, |
|
subnet_mapping['net_partition_id'], |
|
subnet_mapping['nuage_subnet_id']) |
|
except Exception: |
|
with excutils.save_and_reraise_exception(): |
|
super(NuagePlugin, self).delete_port( |
|
context, |
|
port['id']) |
|
if ext_sg.SECURITYGROUPS in p: |
|
self._process_port_create_security_group( |
|
context, |
|
port, |
|
p[ext_sg.SECURITYGROUPS]) |
|
return self._extend_port_dict_binding(context, port) |
|
|
|
def update_port(self, context, id, port): |
|
p = port['port'] |
|
sg_groups = None |
|
if p.get('device_owner', '').startswith( |
|
constants.NOVA_PORT_OWNER_PREF): |
|
session = context.session |
|
with session.begin(subtransactions=True): |
|
port = self._get_port(context, id) |
|
port.update(p) |
|
if not port.get('fixed_ips'): |
|
return self._make_port_dict(port) |
|
subnet_id = port['fixed_ips'][0]['subnet_id'] |
|
|
|
subnet_mapping = nuagedb.get_subnet_l2dom_by_id(session, |
|
subnet_id) |
|
if not subnet_mapping: |
|
msg = (_("Subnet %s not found on VSD") % subnet_id) |
|
raise n_exc.BadRequest(resource='port', msg=msg) |
|
|
|
params = { |
|
'neutron_port_id': id, |
|
} |
|
nuage_port = self.nuageclient.get_nuage_port_by_id(params) |
|
if not nuage_port or not nuage_port.get('nuage_vport_id'): |
|
self._create_update_port(context, port, |
|
subnet_mapping[ |
|
'net_partition_id'], |
|
subnet_mapping['nuage_subnet_id']) |
|
updated_port = self._make_port_dict(port) |
|
sg_port = self._extend_port_dict_security_group( |
|
updated_port, |
|
port |
|
) |
|
sg_groups = sg_port[ext_sg.SECURITYGROUPS] |
|
else: |
|
updated_port = super(NuagePlugin, self).update_port(context, id, |
|
port) |
|
if not updated_port.get('fixed_ips'): |
|
return updated_port |
|
subnet_id = updated_port['fixed_ips'][0]['subnet_id'] |
|
subnet_mapping = nuagedb.get_subnet_l2dom_by_id(context.session, |
|
subnet_id) |
|
if subnet_mapping: |
|
if sg_groups: |
|
self._delete_port_security_group_bindings(context, |
|
updated_port['id']) |
|
self._process_port_create_security_group(context, |
|
updated_port, |
|
sg_groups) |
|
elif ext_sg.SECURITYGROUPS in p: |
|
self._delete_port_security_group_bindings(context, |
|
updated_port['id']) |
|
self._process_port_create_security_group( |
|
context, |
|
updated_port, |
|
p[ext_sg.SECURITYGROUPS] |
|
) |
|
return updated_port |
|
|
|
@lockutils.synchronized('delete-port', 'nuage-del', external=True) |
|
def delete_port(self, context, id, l3_port_check=True): |
|
if l3_port_check: |
|
self.prevent_l3_port_deletion(context, id) |
|
port = self._get_port(context, id) |
|
nuage_vif_id = None |
|
params = { |
|
'neutron_port_id': id, |
|
} |
|
nuage_port = self.nuageclient.get_nuage_port_by_id(params) |
|
|
|
# This is required for to pass ut test_floatingip_port_delete |
|
self.disassociate_floatingips(context, id) |
|
if not port['fixed_ips']: |
|
return super(NuagePlugin, self).delete_port(context, id) |
|
|
|
sub_id = port['fixed_ips'][0]['subnet_id'] |
|
|
|
subnet_mapping = nuagedb.get_subnet_l2dom_by_id(context.session, |
|
sub_id) |
|
if not subnet_mapping: |
|
return super(NuagePlugin, self).delete_port(context, id) |
|
|
|
# Need to call this explicitly to delete vport to vporttag binding |
|
if ext_sg.SECURITYGROUPS in port: |
|
self._delete_port_security_group_bindings(context, id) |
|
|
|
netpart_id = subnet_mapping['net_partition_id'] |
|
net_partition = nuagedb.get_net_partition_by_id(context.session, |
|
netpart_id) |
|
|
|
# Need to call this explicitly to delete vport |
|
if constants.NOVA_PORT_OWNER_PREF in port['device_owner']: |
|
if nuage_port: |
|
nuage_vif_id = nuage_port['nuage_vif_id'] |
|
# This was a VM Port |
|
filters = {'device_id': [port['device_id']]} |
|
ports = self.get_ports(context, filters) |
|
params = { |
|
'no_of_ports': len(ports), |
|
'net_partition': net_partition, |
|
'tenant': port['tenant_id'], |
|
'mac': port['mac_address'], |
|
'nuage_vif_id': nuage_vif_id, |
|
'id': port['device_id'] |
|
} |
|
self.nuageclient.delete_vms(params) |
|
super(NuagePlugin, self).delete_port(context, id) |
|
|
|
def _check_view_auth(self, context, resource, action): |
|
return policy.check(context, action, resource) |
|
|
|
def _extend_port_dict_binding(self, context, port): |
|
if self._check_view_auth(context, port, self.binding_view): |
|
port[portbindings.VIF_TYPE] = portbindings.VIF_TYPE_OVS |
|
port[portbindings.VIF_DETAILS] = { |
|
portbindings.CAP_PORT_FILTER: False |
|
} |
|
return port |
|
|
|
def get_port(self, context, id, fields=None): |
|
port = super(NuagePlugin, self).get_port(context, id, fields) |
|
return self._fields(self._extend_port_dict_binding(context, port), |
|
fields) |
|
|
|
def get_ports(self, context, filters=None, fields=None): |
|
ports = super(NuagePlugin, self).get_ports(context, filters, fields) |
|
return [self._fields(self._extend_port_dict_binding(context, port), |
|
fields) for port in ports] |
|
|
|
def _check_router_subnet_for_tenant(self, context, tenant_id): |
|
# Search router and subnet tables. |
|
# If no entry left delete user and group from VSD |
|
filters = {'tenant_id': [tenant_id]} |
|
routers = self.get_routers(context, filters=filters) |
|
subnets = self.get_subnets(context, filters=filters) |
|
return bool(routers or subnets) |
|
|
|
def create_network(self, context, network): |
|
net = network['network'] |
|
with context.session.begin(subtransactions=True): |
|
self._ensure_default_security_group( |
|
context, |
|
network['network']['tenant_id'] |
|
) |
|
net = super(NuagePlugin, self).create_network(context, |
|
network) |
|
self._process_l3_create(context, net, network['network']) |
|
return net |
|
|
|
def _validate_update_network(self, context, id, network): |
|
req_data = network['network'] |
|
is_external_set = req_data.get(external_net.EXTERNAL) |
|
if not attributes.is_attr_set(is_external_set): |
|
return (None, None) |
|
neutron_net = self.get_network(context, id) |
|
if neutron_net.get(external_net.EXTERNAL) == is_external_set: |
|
return (None, None) |
|
subnet = self._validate_nuage_sharedresource(context, 'network', id) |
|
if subnet and not is_external_set: |
|
msg = _('External network with subnets can not be ' |
|
'changed to non-external network') |
|
raise nuage_exc.OperationNotSupported(msg=msg) |
|
if is_external_set: |
|
# Check if there are vm ports attached to this network |
|
# If there are, then updating the network is not allowed |
|
ports = self.get_ports(context, filters={'network_id': [id]}) |
|
for p in ports: |
|
if p['device_owner'].startswith( |
|
constants.NOVA_PORT_OWNER_PREF): |
|
raise n_exc.NetworkInUse(net_id=id) |
|
return (is_external_set, subnet) |
|
|
|
def update_network(self, context, id, network): |
|
with context.session.begin(subtransactions=True): |
|
is_external_set, subnet = self._validate_update_network(context, |
|
id, |
|
network) |
|
net = super(NuagePlugin, self).update_network(context, id, |
|
network) |
|
self._process_l3_update(context, net, network['network']) |
|
if subnet and is_external_set: |
|
subn = subnet[0] |
|
subnet_l2dom = nuagedb.get_subnet_l2dom_by_id(context.session, |
|
subn['id']) |
|
if subnet_l2dom: |
|
nuage_subnet_id = subnet_l2dom['nuage_subnet_id'] |
|
nuage_l2dom_tid = subnet_l2dom['nuage_l2dom_tmplt_id'] |
|
user_id = subnet_l2dom['nuage_user_id'] |
|
group_id = subnet_l2dom['nuage_group_id'] |
|
self.nuageclient.delete_subnet(nuage_subnet_id, |
|
nuage_l2dom_tid) |
|
nuagedb.delete_subnetl2dom_mapping(context.session, |
|
subnet_l2dom) |
|
if not self._check_router_subnet_for_tenant( |
|
context, subn['tenant_id']): |
|
self.nuageclient.delete_user(user_id) |
|
self.nuageclient.delete_group(group_id) |
|
|
|
self._add_nuage_sharedresource(subnet[0], |
|
id, |
|
constants.SR_TYPE_FLOATING) |
|
return net |
|
|
|
def delete_network(self, context, id): |
|
with context.session.begin(subtransactions=True): |
|
self._process_l3_delete(context, id) |
|
filter = {'network_id': [id]} |
|
subnets = self.get_subnets(context, filters=filter) |
|
for subnet in subnets: |
|
self.delete_subnet(context, subnet['id']) |
|
super(NuagePlugin, self).delete_network(context, id) |
|
|
|
def _get_net_partition_for_subnet(self, context, subnet): |
|
ent = subnet.get('net_partition', None) |
|
if not ent: |
|
def_net_part = cfg.CONF.RESTPROXY.default_net_partition_name |
|
net_partition = nuagedb.get_net_partition_by_name(context.session, |
|
def_net_part) |
|
else: |
|
net_partition = self._resource_finder(context, 'subnet', |
|
'net_partition', subnet) |
|
if not net_partition: |
|
msg = _('Either net_partition is not provided with subnet OR ' |
|
'default net_partition is not created at the start') |
|
raise n_exc.BadRequest(resource='subnet', msg=msg) |
|
return net_partition |
|
|
|
def _validate_create_subnet(self, subnet): |
|
if ('host_routes' in subnet and |
|
attributes.is_attr_set(subnet['host_routes'])): |
|
msg = 'host_routes extensions not supported for subnets' |
|
raise nuage_exc.OperationNotSupported(msg=msg) |
|
if subnet['gateway_ip'] is None: |
|
msg = "no-gateway option not supported with subnets" |
|
raise nuage_exc.OperationNotSupported(msg=msg) |
|
|
|
def _delete_nuage_sharedresource(self, net_id): |
|
self.nuageclient.delete_nuage_sharedresource(net_id) |
|
|
|
def _validate_nuage_sharedresource(self, context, resource, net_id): |
|
filter = {'network_id': [net_id]} |
|
existing_subn = self.get_subnets(context, filters=filter) |
|
if len(existing_subn) > 1: |
|
msg = _('Only one subnet is allowed per ' |
|
'external network %s') % net_id |
|
raise nuage_exc.OperationNotSupported(msg=msg) |
|
return existing_subn |
|
|
|
def _add_nuage_sharedresource(self, subnet, net_id, type): |
|
net = netaddr.IPNetwork(subnet['cidr']) |
|
params = { |
|
'neutron_subnet': subnet, |
|
'net': net, |
|
'type': type, |
|
'net_id': net_id |
|
} |
|
self.nuageclient.create_nuage_sharedresource(params) |
|
|
|
def _create_nuage_sharedresource(self, context, subnet, type): |
|
subn = subnet['subnet'] |
|
net_id = subn['network_id'] |
|
self._validate_nuage_sharedresource(context, 'subnet', net_id) |
|
with context.session.begin(subtransactions=True): |
|
subn = super(NuagePlugin, self).create_subnet(context, subnet) |
|
self._add_nuage_sharedresource(subn, net_id, type) |
|
return subn |
|
|
|
def _create_nuage_subnet(self, context, neutron_subnet, netpart_id): |
|
net = netaddr.IPNetwork(neutron_subnet['cidr']) |
|
params = { |
|
'netpart_id': netpart_id, |
|
'tenant_id': neutron_subnet['tenant_id'], |
|
'net': net |
|
} |
|
try: |
|
nuage_subnet = self.nuageclient.create_subnet(neutron_subnet, |
|
params) |
|
except Exception: |
|
with excutils.save_and_reraise_exception(): |
|
super(NuagePlugin, self).delete_subnet( |
|
context, |
|
neutron_subnet['id']) |
|
|
|
if nuage_subnet: |
|
l2dom_id = str(nuage_subnet['nuage_l2template_id']) |
|
user_id = nuage_subnet['nuage_userid'] |
|
group_id = nuage_subnet['nuage_groupid'] |
|
id = nuage_subnet['nuage_l2domain_id'] |
|
with context.session.begin(subtransactions=True): |
|
nuagedb.add_subnetl2dom_mapping(context.session, |
|
neutron_subnet['id'], |
|
id, |
|
netpart_id, |
|
l2dom_id=l2dom_id, |
|
nuage_user_id=user_id, |
|
nuage_group_id=group_id) |
|
|
|
def create_subnet(self, context, subnet): |
|
subn = subnet['subnet'] |
|
net_id = subn['network_id'] |
|
|
|
if self._network_is_external(context, net_id): |
|
return self._create_nuage_sharedresource( |
|
context, subnet, constants.SR_TYPE_FLOATING) |
|
|
|
self._validate_create_subnet(subn) |
|
|
|
net_partition = self._get_net_partition_for_subnet(context, subn) |
|
neutron_subnet = super(NuagePlugin, self).create_subnet(context, |
|
subnet) |
|
self._create_nuage_subnet(context, neutron_subnet, net_partition['id']) |
|
return neutron_subnet |
|
|
|
def delete_subnet(self, context, id): |
|
subnet = self.get_subnet(context, id) |
|
if self._network_is_external(context, subnet['network_id']): |
|
super(NuagePlugin, self).delete_subnet(context, id) |
|
return self._delete_nuage_sharedresource(id) |
|
|
|
subnet_l2dom = nuagedb.get_subnet_l2dom_by_id(context.session, id) |
|
if subnet_l2dom: |
|
try: |
|
self.nuageclient.delete_subnet( |
|
subnet_l2dom['nuage_subnet_id'], |
|
subnet_l2dom['nuage_l2dom_tmplt_id']) |
|
except Exception: |
|
msg = (_('Unable to complete operation on subnet %s.' |
|
'One or more ports have an IP allocation ' |
|
'from this subnet.') % id) |
|
raise n_exc.BadRequest(resource='subnet', msg=msg) |
|
super(NuagePlugin, self).delete_subnet(context, id) |
|
if subnet_l2dom and not self._check_router_subnet_for_tenant( |
|
context, subnet['tenant_id']): |
|
self.nuageclient.delete_user(subnet_l2dom['nuage_user_id']) |
|
self.nuageclient.delete_group(subnet_l2dom['nuage_group_id']) |
|
|
|
def add_router_interface(self, context, router_id, interface_info): |
|
session = context.session |
|
with session.begin(subtransactions=True): |
|
rtr_if_info = super(NuagePlugin, |
|
self).add_router_interface(context, |
|
router_id, |
|
interface_info) |
|
subnet_id = rtr_if_info['subnet_id'] |
|
subn = self.get_subnet(context, subnet_id) |
|
ent_rtr_mapping = nuagedb.get_ent_rtr_mapping_by_rtrid(session, |
|
router_id) |
|
nuage_zone = self.nuageclient.get_zone_by_routerid(router_id) |
|
if not nuage_zone or not ent_rtr_mapping: |
|
super(NuagePlugin, |
|
self).remove_router_interface(context, |
|
router_id, |
|
interface_info) |
|
msg = (_("Router %s does not hold default zone OR " |
|
"domain in VSD. Router-IF add failed") |
|
% router_id) |
|
raise n_exc.BadRequest(resource='router', msg=msg) |
|
|
|
subnet_l2dom = nuagedb.get_subnet_l2dom_by_id(session, |
|
subnet_id) |
|
if not subnet_l2dom: |
|
super(NuagePlugin, |
|
self).remove_router_interface(context, |
|
router_id, |
|
interface_info) |
|
msg = (_("Subnet %s does not hold Nuage VSD reference. " |
|
"Router-IF add failed") % subnet_id) |
|
raise n_exc.BadRequest(resource='subnet', msg=msg) |
|
|
|
if (subnet_l2dom['net_partition_id'] != |
|
ent_rtr_mapping['net_partition_id']): |
|
super(NuagePlugin, |
|
self).remove_router_interface(context, |
|
router_id, |
|
interface_info) |
|
msg = (_("Subnet %(subnet)s and Router %(router)s belong to " |
|
"different net_partition Router-IF add " |
|
"not permitted") % {'subnet': subnet_id, |
|
'router': router_id}) |
|
raise n_exc.BadRequest(resource='subnet', msg=msg) |
|
nuage_subnet_id = subnet_l2dom['nuage_subnet_id'] |
|
nuage_l2dom_tmplt_id = subnet_l2dom['nuage_l2dom_tmplt_id'] |
|
if self.nuageclient.vms_on_l2domain(nuage_subnet_id): |
|
super(NuagePlugin, |
|
self).remove_router_interface(context, |
|
router_id, |
|
interface_info) |
|
msg = (_("Subnet %s has one or more active VMs " |
|
"Router-IF add not permitted") % subnet_id) |
|
raise n_exc.BadRequest(resource='subnet', msg=msg) |
|
self.nuageclient.delete_subnet(nuage_subnet_id, |
|
nuage_l2dom_tmplt_id) |
|
net = netaddr.IPNetwork(subn['cidr']) |
|
params = { |
|
'net': net, |
|
'zone_id': nuage_zone['nuage_zone_id'], |
|
'neutron_subnet_id': subnet_id |
|
} |
|
if not attributes.is_attr_set(subn['gateway_ip']): |
|
subn['gateway_ip'] = str(netaddr.IPAddress(net.first + 1)) |
|
try: |
|
nuage_subnet = self.nuageclient.create_domain_subnet(subn, |
|
params) |
|
except Exception: |
|
with excutils.save_and_reraise_exception(): |
|
super(NuagePlugin, |
|
self).remove_router_interface(context, |
|
router_id, |
|
interface_info) |
|
|
|
if nuage_subnet: |
|
ns_dict = {} |
|
ns_dict['nuage_subnet_id'] = nuage_subnet['nuage_subnetid'] |
|
ns_dict['nuage_l2dom_tmplt_id'] = None |
|
nuagedb.update_subnetl2dom_mapping(subnet_l2dom, |
|
ns_dict) |
|
|
|
return rtr_if_info |
|
|
|
def remove_router_interface(self, context, router_id, interface_info): |
|
if 'subnet_id' in interface_info: |
|
subnet_id = interface_info['subnet_id'] |
|
subnet = self.get_subnet(context, subnet_id) |
|
found = False |
|
try: |
|
filters = {'device_id': [router_id], |
|
'device_owner': |
|
[os_constants.DEVICE_OWNER_ROUTER_INTF], |
|
'network_id': [subnet['network_id']]} |
|
ports = self.get_ports(context, filters) |
|
|
|
for p in ports: |
|
if p['fixed_ips'][0]['subnet_id'] == subnet_id: |
|
found = True |
|
break |
|
except exc.NoResultFound: |
|
msg = (_("No router interface found for Router %s. " |
|
"Router-IF delete failed") % router_id) |
|
raise n_exc.BadRequest(resource='router', msg=msg) |
|
|
|
if not found: |
|
msg = (_("No router interface found for Router %s. " |
|
"Router-IF delete failed") % router_id) |
|
raise n_exc.BadRequest(resource='router', msg=msg) |
|
elif 'port_id' in interface_info: |
|
port_db = self._get_port(context, interface_info['port_id']) |
|
if not port_db: |
|
msg = (_("No router interface found for Router %s. " |
|
"Router-IF delete failed") % router_id) |
|
raise n_exc.BadRequest(resource='router', msg=msg) |
|
subnet_id = port_db['fixed_ips'][0]['subnet_id'] |
|
|
|
session = context.session |
|
with session.begin(subtransactions=True): |
|
subnet_l2dom = nuagedb.get_subnet_l2dom_by_id(session, |
|
subnet_id) |
|
if not subnet_l2dom: |
|
return super(NuagePlugin, |
|
self).remove_router_interface(context, |
|
router_id, |
|
interface_info) |
|
nuage_subn_id = subnet_l2dom['nuage_subnet_id'] |
|
if self.nuageclient.vms_on_subnet(nuage_subn_id): |
|
msg = (_("Subnet %s has one or more active VMs " |
|
"Router-IF delete not permitted") % subnet_id) |
|
raise n_exc.BadRequest(resource='subnet', msg=msg) |
|
|
|
neutron_subnet = self.get_subnet(context, subnet_id) |
|
ent_rtr_mapping = nuagedb.get_ent_rtr_mapping_by_rtrid( |
|
context.session, |
|
router_id) |
|
if not ent_rtr_mapping: |
|
msg = (_("Router %s does not hold net_partition " |
|
"assoc on Nuage VSD. Router-IF delete failed") |
|
% router_id) |
|
raise n_exc.BadRequest(resource='router', msg=msg) |
|
|
|
net = netaddr.IPNetwork(neutron_subnet['cidr']) |
|
netpart_id = ent_rtr_mapping['net_partition_id'] |
|
params = { |
|
'tenant_id': neutron_subnet['tenant_id'], |
|
'net': net, |
|
'netpart_id': netpart_id |
|
} |
|
nuage_subnet = self.nuageclient.create_subnet(neutron_subnet, |
|
params) |
|
self.nuageclient.delete_domain_subnet(nuage_subn_id) |
|
info = super(NuagePlugin, |
|
self).remove_router_interface(context, router_id, |
|
interface_info) |
|
|
|
if nuage_subnet: |
|
tmplt_id = str(nuage_subnet['nuage_l2template_id']) |
|
ns_dict = {} |
|
ns_dict['nuage_subnet_id'] = nuage_subnet['nuage_l2domain_id'] |
|
ns_dict['nuage_l2dom_tmplt_id'] = tmplt_id |
|
nuagedb.update_subnetl2dom_mapping(subnet_l2dom, |
|
ns_dict) |
|
return info |
|
|
|
def _get_net_partition_for_router(self, context, rtr): |
|
ent = rtr.get('net_partition', None) |
|
if not ent: |
|
def_net_part = cfg.CONF.RESTPROXY.default_net_partition_name |
|
net_partition = nuagedb.get_net_partition_by_name(context.session, |
|
def_net_part) |
|
else: |
|
net_partition = self._resource_finder(context, 'router', |
|
'net_partition', rtr) |
|
if not net_partition: |
|
msg = _("Either net_partition is not provided with router OR " |
|
"default net_partition is not created at the start") |
|
raise n_exc.BadRequest(resource='router', msg=msg) |
|
return net_partition |
|
|
|
def create_router(self, context, router): |
|
net_partition = self._get_net_partition_for_router(context, router) |
|
neutron_router = super(NuagePlugin, self).create_router(context, |
|
router) |
|
params = { |
|
'net_partition': net_partition, |
|
'tenant_id': neutron_router['tenant_id'] |
|
} |
|
try: |
|
nuage_router = self.nuageclient.create_router(neutron_router, |
|
router['router'], |
|
params) |
|
except Exception: |
|
with excutils.save_and_reraise_exception(): |
|
super(NuagePlugin, self).delete_router(context, |
|
neutron_router['id']) |
|
|
|
if nuage_router: |
|
with context.session.begin(subtransactions=True): |
|
nuagedb.add_entrouter_mapping(context.session, |
|
net_partition['id'], |
|
neutron_router['id'], |
|
nuage_router['nuage_domain_id']) |
|
|
|
return neutron_router |
|
|
|
def _validate_nuage_staticroutes(self, old_routes, added, removed): |
|
cidrs = [] |
|
for old in old_routes: |
|
if old not in removed: |
|
ip = netaddr.IPNetwork(old['destination']) |
|
cidrs.append(ip) |
|
for route in added: |
|
ip = netaddr.IPNetwork(route['destination']) |
|
matching = netaddr.all_matching_cidrs(ip.ip, cidrs) |
|
if matching: |
|
msg = _('for same subnet, multiple static routes not allowed') |
|
raise n_exc.BadRequest(resource='router', msg=msg) |
|
cidrs.append(ip) |
|
|
|
def update_router(self, context, id, router): |
|
r = router['router'] |
|
with context.session.begin(subtransactions=True): |
|
if 'routes' in r: |
|
old_routes = self._get_extra_routes_by_router_id(context, |
|
id) |
|
added, removed = utils.diff_list_of_dict(old_routes, |
|
r['routes']) |
|
self._validate_nuage_staticroutes(old_routes, added, removed) |
|
|
|
ent_rtr_mapping = nuagedb.get_ent_rtr_mapping_by_rtrid( |
|
context.session, id) |
|
if not ent_rtr_mapping: |
|
msg = (_("Router %s does not hold net-partition " |
|
"assoc on VSD. extra-route failed") % id) |
|
raise n_exc.BadRequest(resource='router', msg=msg) |
|
# Let it do internal checks first and verify it. |
|
router_updated = super(NuagePlugin, |
|
self).update_router(context, |
|
id, |
|
router) |
|
for route in removed: |
|
destaddr = route['destination'] |
|
cidr = destaddr.split('/') |
|
params = { |
|
"address": cidr[0], |
|
"nexthop": route['nexthop'], |
|
"nuage_domain_id": ent_rtr_mapping['nuage_router_id'] |
|
} |
|
self.nuageclient.delete_nuage_staticroute(params) |
|
|
|
for route in added: |
|
params = { |
|
'parent_id': ent_rtr_mapping['nuage_router_id'], |
|
'net': netaddr.IPNetwork(route['destination']), |
|
'nexthop': route['nexthop'] |
|
} |
|
self.nuageclient.create_nuage_staticroute( |
|
params) |
|
else: |
|
router_updated = super(NuagePlugin, self).update_router( |
|
context, id, router) |
|
return router_updated |
|
|
|
def delete_router(self, context, id): |
|
neutron_router = self.get_router(context, id) |
|
session = context.session |
|
ent_rtr_mapping = nuagedb.get_ent_rtr_mapping_by_rtrid(session, |
|
id) |
|
if ent_rtr_mapping: |
|
filters = { |
|
'device_id': [id], |
|
'device_owner': [os_constants.DEVICE_OWNER_ROUTER_INTF] |
|
} |
|
ports = self.get_ports(context, filters) |
|
if ports: |
|
raise l3.RouterInUse(router_id=id) |
|
nuage_domain_id = ent_rtr_mapping['nuage_router_id'] |
|
self.nuageclient.delete_router(nuage_domain_id) |
|
|
|
super(NuagePlugin, self).delete_router(context, id) |
|
|
|
nuage_zone = self.nuageclient.get_zone_by_routerid(id) |
|
if nuage_zone and not self._check_router_subnet_for_tenant( |
|
context, neutron_router['tenant_id']): |
|
user_id, group_id = self.nuageclient.get_usergroup( |
|
neutron_router['tenant_id'], |
|
ent_rtr_mapping['net_partition_id']) |
|
self.nuageclient.delete_user(user_id) |
|
self.nuageclient.delete_group(group_id) |
|
|
|
def _make_net_partition_dict(self, net_partition, fields=None): |
|
res = { |
|
'id': net_partition['id'], |
|
'name': net_partition['name'], |
|
'l3dom_tmplt_id': net_partition['l3dom_tmplt_id'], |
|
'l2dom_tmplt_id': net_partition['l2dom_tmplt_id'], |
|
} |
|
return self._fields(res, fields) |
|
|
|
def _create_net_partition(self, session, net_part_name): |
|
fip_quota = cfg.CONF.RESTPROXY.default_floatingip_quota |
|
params = { |
|
"name": net_part_name, |
|
"fp_quota": str(fip_quota) |
|
} |
|
nuage_net_partition = self.nuageclient.create_net_partition(params) |
|
net_partitioninst = None |
|
if nuage_net_partition: |
|
nuage_entid = nuage_net_partition['nuage_entid'] |
|
l3dom_id = nuage_net_partition['l3dom_id'] |
|
l2dom_id = nuage_net_partition['l2dom_id'] |
|
with session.begin(): |
|
net_partitioninst = nuagedb.add_net_partition(session, |
|
nuage_entid, |
|
l3dom_id, |
|
l2dom_id, |
|
net_part_name) |
|
if not net_partitioninst: |
|
return {} |
|
return self._make_net_partition_dict(net_partitioninst) |
|
|
|
def _create_default_net_partition(self, default_net_part): |
|
def_netpart = self.nuageclient.get_def_netpartition_data( |
|
default_net_part) |
|
session = db.get_session() |
|
if def_netpart: |
|
net_partition = nuagedb.get_net_partition_by_name( |
|
session, default_net_part) |
|
with session.begin(subtransactions=True): |
|
if net_partition: |
|
nuagedb.delete_net_partition(session, net_partition) |
|
net_part = nuagedb.add_net_partition(session, |
|
def_netpart['np_id'], |
|
def_netpart['l3dom_tid'], |
|
def_netpart['l2dom_tid'], |
|
default_net_part) |
|
return self._make_net_partition_dict(net_part) |
|
else: |
|
return self._create_net_partition(session, default_net_part) |
|
|
|
def create_net_partition(self, context, net_partition): |
|
ent = net_partition['net_partition'] |
|
session = context.session |
|
return self._create_net_partition(session, ent["name"]) |
|
|
|
def delete_net_partition(self, context, id): |
|
ent_rtr_mapping = nuagedb.get_ent_rtr_mapping_by_entid(context.session, |
|
id) |
|
if ent_rtr_mapping: |
|
msg = (_("One or more router still attached to " |
|
"net_partition %s.") % id) |
|
raise n_exc.BadRequest(resource='net_partition', msg=msg) |
|
net_partition = nuagedb.get_net_partition_by_id(context.session, id) |
|
if not net_partition: |
|
msg = (_("NetPartition with %s does not exist") % id) |
|
raise n_exc.BadRequest(resource='net_partition', msg=msg) |
|
l3dom_tmplt_id = net_partition['l3dom_tmplt_id'] |
|
l2dom_tmplt_id = net_partition['l2dom_tmplt_id'] |
|
self.nuageclient.delete_net_partition(net_partition['id'], |
|
l3dom_id=l3dom_tmplt_id, |
|
l2dom_id=l2dom_tmplt_id) |
|
with context.session.begin(subtransactions=True): |
|
nuagedb.delete_net_partition(context.session, |
|
net_partition) |
|
|
|
def get_net_partition(self, context, id, fields=None): |
|
net_partition = nuagedb.get_net_partition_by_id(context.session, |
|
id) |
|
return self._make_net_partition_dict(net_partition) |
|
|
|
def get_net_partitions(self, context, filters=None, fields=None): |
|
net_partitions = nuagedb.get_net_partitions(context.session, |
|
filters=filters, |
|
fields=fields) |
|
return [self._make_net_partition_dict(net_partition, fields) |
|
for net_partition in net_partitions] |
|
|
|
def _check_floatingip_update(self, context, port): |
|
filter = {'fixed_port_id': [port['id']]} |
|
local_fip = self.get_floatingips(context, |
|
filters=filter) |
|
if local_fip: |
|
fip = local_fip[0] |
|
self._create_update_floatingip(context, |
|
fip, port['id']) |
|
|
|
def _create_update_floatingip(self, context, |
|
neutron_fip, port_id): |
|
rtr_id = neutron_fip['router_id'] |
|
net_id = neutron_fip['floating_network_id'] |
|
|
|
fip_pool = self.nuageclient.get_nuage_fip_pool_by_id(net_id) |
|
if not fip_pool: |
|
msg = _('sharedresource %s not found on VSD') % net_id |
|
raise n_exc.BadRequest(resource='floatingip', |
|
msg=msg) |
|
|
|
ent_rtr_mapping = nuagedb.get_ent_rtr_mapping_by_rtrid(context.session, |
|
rtr_id) |
|
if not ent_rtr_mapping: |
|
msg = _('router %s is not associated with ' |
|
'any net-partition') % rtr_id |
|
raise n_exc.BadRequest(resource='floatingip', |
|
msg=msg) |
|
|
|
params = { |
|
'router_id': ent_rtr_mapping['nuage_router_id'], |
|
'fip_id': neutron_fip['id'], |
|
'neutron_fip': neutron_fip |
|
} |
|
|
|
fip = self.nuageclient.get_nuage_fip_by_id(params) |
|
if not fip: |
|
params = { |
|
'nuage_rtr_id': ent_rtr_mapping['nuage_router_id'], |
|
'nuage_fippool_id': fip_pool['nuage_fip_pool_id'], |
|
'neutron_fip_ip': neutron_fip['floating_ip_address'], |
|
'neutron_fip_id': neutron_fip['id'] |
|
} |
|
nuage_fip_id = self.nuageclient.create_nuage_floatingip(params) |
|
else: |
|
nuage_fip_id = fip['nuage_fip_id'] |
|
|
|
# Update VM if required |
|
params = { |
|
'neutron_port_id': port_id, |
|
'nuage_fip_id': nuage_fip_id, |
|
'nuage_rtr_id': ent_rtr_mapping['nuage_router_id'] |
|
} |
|
nuage_port = self.nuageclient.get_nuage_port_by_id(params) |
|
if nuage_port: |
|
if (nuage_port['nuage_domain_id']) != ( |
|
ent_rtr_mapping['nuage_router_id']): |
|
msg = _('Floating IP can not be associated to VM in ' |
|
'different router context') |
|
raise nuage_exc.OperationNotSupported(msg=msg) |
|
|
|
params = { |
|
'nuage_vport_id': nuage_port['nuage_vport_id'], |
|
'nuage_fip_id': nuage_fip_id |
|
} |
|
self.nuageclient.update_nuage_vm_vport(params) |
|
|
|
def create_floatingip(self, context, floatingip): |
|
fip = floatingip['floatingip'] |
|
with context.session.begin(subtransactions=True): |
|
neutron_fip = super(NuagePlugin, self).create_floatingip( |
|
context, floatingip) |
|
if not neutron_fip['router_id']: |
|
return neutron_fip |
|
try: |
|
self._create_update_floatingip(context, neutron_fip, |
|
fip['port_id']) |
|
except (nuage_exc.OperationNotSupported, n_exc.BadRequest): |
|
with excutils.save_and_reraise_exception(): |
|
super(NuagePlugin, self).delete_floatingip( |
|
context, neutron_fip['id']) |
|
return neutron_fip |
|
|
|
def disassociate_floatingips(self, context, port_id, do_notify=True): |
|
router_ids = super(NuagePlugin, self).disassociate_floatingips( |
|
context, port_id, do_notify=do_notify) |
|
|
|
params = { |
|
'neutron_port_id': port_id, |
|
} |
|
nuage_port = self.nuageclient.get_nuage_port_by_id(params) |
|
if nuage_port: |
|
params = { |
|
'nuage_vport_id': nuage_port['nuage_vport_id'], |
|
'nuage_fip_id': None |
|
} |
|
self.nuageclient.update_nuage_vm_vport(params) |
|
|
|
return router_ids |
|
|
|
def update_floatingip(self, context, id, floatingip): |
|
fip = floatingip['floatingip'] |
|
orig_fip = self._get_floatingip(context, id) |
|
port_id = orig_fip['fixed_port_id'] |
|
router_ids = [] |
|
with context.session.begin(subtransactions=True): |
|
neutron_fip = super(NuagePlugin, self).update_floatingip( |
|
context, id, floatingip) |
|
if fip['port_id'] is not None: |
|
if not neutron_fip['router_id']: |
|
ret_msg = 'floating-ip is not associated yet' |
|
raise n_exc.BadRequest(resource='floatingip', |
|
msg=ret_msg) |
|
|
|
try: |
|
self._create_update_floatingip(context, |
|
neutron_fip, |
|
fip['port_id']) |
|
except nuage_exc.OperationNotSupported: |
|
with excutils.save_and_reraise_exception(): |
|
router_ids = super( |
|
NuagePlugin, self).disassociate_floatingips( |
|
context, fip['port_id'], do_notify=False) |
|
except n_exc.BadRequest: |
|
with excutils.save_and_reraise_exception(): |
|
super(NuagePlugin, self).delete_floatingip(context, |
|
id) |
|
else: |
|
params = { |
|
'neutron_port_id': port_id, |
|
} |
|
nuage_port = self.nuageclient.get_nuage_port_by_id(params) |
|
if nuage_port: |
|
params = { |
|
'nuage_vport_id': nuage_port['nuage_vport_id'], |
|
'nuage_fip_id': None |
|
} |
|
self.nuageclient.update_nuage_vm_vport(params) |
|
|
|
# now that we've left db transaction, we are safe to notify |
|
self.notify_routers_updated(context, router_ids) |
|
|
|
return neutron_fip |
|
|
|
def delete_floatingip(self, context, id): |
|
fip = self._get_floatingip(context, id) |
|
port_id = fip['fixed_port_id'] |
|
with context.session.begin(subtransactions=True): |
|
if port_id: |
|
params = { |
|
'neutron_port_id': id, |
|
} |
|
nuage_port = self.nuageclient.get_nuage_port_by_id(params) |
|
if (nuage_port and |
|
nuage_port['nuage_vport_id'] is not None): |
|
params = { |
|
'nuage_vport_id': nuage_port['nuage_vport_id'], |
|
'nuage_fip_id': None |
|
} |
|
self.nuageclient.update_nuage_vm_vport(params) |
|
rtr_id = fip['last_known_router_id'] |
|
if rtr_id: |
|
ent_rtr_mapping = nuagedb.get_ent_rtr_mapping_by_rtrid( |
|
context.session, |
|
rtr_id) |
|
if not ent_rtr_mapping: |
|
msg = _('router %s is not associated with ' |
|
'any net-partition') % rtr_id |
|
raise n_exc.BadRequest(resource='floatingip', |
|
msg=msg) |
|
params = { |
|
'router_id': ent_rtr_mapping['nuage_router_id'], |
|
'fip_id': id |
|
} |
|
fip = self.nuageclient.get_nuage_fip_by_id(params) |
|
if fip: |
|
self.nuageclient.delete_nuage_floatingip( |
|
fip['nuage_fip_id']) |
|
super(NuagePlugin, self).delete_floatingip(context, id) |
|
|
|
def delete_security_group(self, context, id): |
|
filters = {'security_group_id': [id]} |
|
ports = self._get_port_security_group_bindings(context, |
|
filters) |
|
if ports: |
|
raise ext_sg.SecurityGroupInUse(id=id) |
|
sg_rules = self.get_security_group_rules(context, |
|
{'security_group_id': [id]}) |
|
|
|
if sg_rules: |
|
self.nuageclient.delete_nuage_sgrule(sg_rules) |
|
self.nuageclient.delete_nuage_secgroup(id) |
|
|
|
super(NuagePlugin, self).delete_security_group(context, id) |
|
|
|
def create_security_group_rule(self, context, security_group_rule): |
|
sg_rule = security_group_rule['security_group_rule'] |
|
self.nuageclient.validate_nuage_sg_rule_definition(sg_rule) |
|
sg_id = sg_rule['security_group_id'] |
|
|
|
local_sg_rule = super(NuagePlugin, |
|
self).create_security_group_rule( |
|
context, security_group_rule) |
|
|
|
try: |
|
nuage_vptag = self.nuageclient.get_sg_vptag_mapping(sg_id) |
|
if nuage_vptag: |
|
sg_params = { |
|
'sg_id': sg_id, |
|
'neutron_sg_rule': local_sg_rule, |
|
'vptag': nuage_vptag |
|
} |
|
self.nuageclient.create_nuage_sgrule(sg_params) |
|
except Exception: |
|
with excutils.save_and_reraise_exception(): |
|
super(NuagePlugin, |
|
self).delete_security_group_rule(context, |
|
local_sg_rule['id']) |
|
|
|
return local_sg_rule |
|
|
|
def delete_security_group_rule(self, context, id): |
|
local_sg_rule = self.get_security_group_rule(context, id) |
|
super(NuagePlugin, self).delete_security_group_rule(context, id) |
|
self.nuageclient.delete_nuage_sgrule([local_sg_rule])
|
|
|