Merge "Add Azure support for Neutron"

This commit is contained in:
Jenkins 2017-09-08 23:22:01 +00:00 committed by Gerrit Code Review
commit b4369a7e5f
6 changed files with 813 additions and 0 deletions

View File

View File

@ -0,0 +1,30 @@
"""
Copyright 2017 Platform9 Systems Inc.(http://www.platform9.com)
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_config import cfg
azure_group = cfg.OptGroup(name='azure',
title='Options to connect to Azure cloud')
azure_opts = [
cfg.StrOpt('tenant_id', help='Tenant id of Azure account'),
cfg.StrOpt('client_id', help='Azure client id'),
cfg.StrOpt('client_secret', help='Azure Client secret', secret=True),
cfg.StrOpt('subscription_id', help='Azure subscription id'),
cfg.StrOpt('region', help='Azure region'),
cfg.StrOpt('resource_group', help="Azure resource group"),
]
cfg.CONF.register_group(azure_group)
cfg.CONF.register_opts(azure_opts, group=azure_group)
azure_conf = cfg.CONF.azure

View File

@ -0,0 +1,231 @@
"""
Copyright (c) 2017 Platform9 Systems 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 expressed or implied. See the
License for the specific language governing permissions and limitations
under the License.
"""
from functools import partial
import uuid
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from msrestazure.azure_exceptions import CloudError
from oslo_log import log as logging
from neutron.extensions import securitygroup as sg
from neutron_lib import exceptions as n_exceptions
LOG = logging.getLogger(__name__)
class FloatingIPNotFound(n_exceptions.NotFound):
message = "Floating IP %(ip)s could not be found."
def azure_handle_exception(fn):
def wrapper(*args, **kwargs):
try:
return fn(*args, **kwargs)
except Exception as e:
LOG.exception("Exception occurred in Azure operation: %s" %
(e.message))
return wrapper
def get_credentials(tenant_id, client_id, client_secret):
credentials = ServicePrincipalCredentials(
client_id=client_id, secret=client_secret, tenant=tenant_id)
return credentials
def _get_client(tenant_id, client_id, client_secret, subscription_id,
cls=None):
"""Returns Azure compute resource object for interacting with Azure API
:param tenant_id: string, tenant_id from azure account
:param client_id: string, client_id (application id)
:param client_secret: string, secret key of application
:param subscription_id: string, unique identification id of account
:return: :class:`Resource <Resource>` object
"""
credentials = get_credentials(tenant_id, client_id, client_secret)
client = cls(credentials, subscription_id)
return client
get_compute_client = partial(_get_client, cls=ComputeManagementClient)
get_network_client = partial(_get_client, cls=NetworkManagementClient)
def _perform_and_wait(operation, args=(), kwargs={}, timeout=300):
operation(*args, **kwargs).wait(timeout=timeout)
def create_network(network, resource_group, name, info):
_perform_and_wait(network.virtual_networks.create_or_update,
(resource_group, name, info))
@azure_handle_exception
def delete_network(network, resource_group, name):
_perform_and_wait(network.virtual_networks.delete, (resource_group, name))
def get_network(network, resource_group, name):
try:
return network.virtual_networks.get(resource_group, name)
except CloudError:
raise n_exceptions.NetworkNotFound(net_id=name)
def create_subnet(network, resource_group, network_name, name, info):
_perform_and_wait(network.subnets.create_or_update,
(resource_group, network_name, name, info))
@azure_handle_exception
def delete_subnet(network, resource_group, network_name, name):
_perform_and_wait(network.subnets.delete, (resource_group, network_name,
name))
def get_subnet(network, resource_group, network_name, name):
try:
return network.subnets.get(resource_group, network_name, name)
except CloudError:
raise n_exceptions.SubnetNotFound(subnet_id=name)
def get_nic(network, resource_group, name):
try:
return network.network_interfaces.get(resource_group, name)
except CloudError:
raise n_exceptions.PortNotFound(port_id=name)
def create_nic(network, resource_group, name, body):
_perform_and_wait(network.network_interfaces.create_or_update,
(resource_group, name, body))
@azure_handle_exception
def delete_nic(network, resource_group, name):
_perform_and_wait(network.network_interfaces.delete, (resource_group,
name))
def get_sg(network, resource_group, name):
return network.network_security_groups.get(resource_group, name)
def create_sg(network, resource_group, name, body):
_perform_and_wait(network.network_security_groups.create_or_update,
(resource_group, name, body))
@azure_handle_exception
def delete_sg(network, resource_group, name):
_perform_and_wait(network.network_security_groups.delete, (resource_group,
name))
def get_sg_rule(network, resource_group, sg_name, name):
return network.network_security_rules.get(resource_group, sg_name, name)
def create_sg_rule(network, resource_group, sg_name, name, body):
_perform_and_wait(network.security_rules.create_or_update,
(resource_group, sg_name, name, body))
@azure_handle_exception
def delete_sg_rule(network, resource_group, sg_name, name):
_perform_and_wait(network.security_rules.delete, (resource_group, sg_name,
name))
# Maintaining different calls for update to simplify mocking
update_network = create_network
update_nic = create_nic
update_sg = create_sg
update_sg_rule = create_sg_rule
def convert_sg_rule(openstack_rule, priority=None):
directions = {'ingress': 'Inbound', 'egress': 'Outbound'}
protocols = {'tcp': 'Tcp', 'udp': 'Udp'}
# Asterix '*' is used to match all possible values.
# E.g. In case of source_port_range it will allow all ports.
# The default security group is allow all traffic, based on
# user inputs we refine it further.
sg_rule = {
'source_port_range': '*',
'destination_port_range': '*',
'source_address_prefix': '*',
'destination_address_prefix': '*',
'access': 'Allow',
'priority': priority
}
sg_rule['direction'] = directions[openstack_rule['direction']]
if openstack_rule['ethertype'] != 'IPv4':
raise sg.SecurityGroupRuleInvalidEtherType(
ethertype=openstack_rule['ethertype'], values=('IPv4', ))
protocol = openstack_rule['protocol']
if protocol is None:
sg_rule['protocol'] = '*'
if protocol and protocol in protocols:
sg_rule['protocol'] = protocols[protocol]
else:
raise sg.SecurityGroupRuleInvalidProtocol(
protocol=protocol, values=protocols.keys())
port_range_min = openstack_rule['port_range_min']
port_range_max = openstack_rule['port_range_max']
if port_range_min and port_range_min == port_range_max:
sg_rule['destination_port_range'] = str(port_range_min)
elif port_range_min and port_range_max:
sg_rule['destination_port_range'] = "%s-%s" % (port_range_min,
port_range_max)
if openstack_rule['remote_ip_prefix']:
# TODO(ssudake21): Allow support for tags in source_address_prefix
sg_rule['source_address_prefix'] = openstack_rule['remote_ip_prefix']
return sg_rule
def allocate_floatingip(network, resource_group, region):
name = 'eip-' + str(uuid.uuid4())
data = {
'location': region,
'public_ip_allocation_method': 'Static',
'public_ip_address_version': 'IPv4',
'idle_timeout_in_minutes': 4
}
response = network.public_ip_addresses.create_or_update(
resource_group, name, data)
return response.result()
def get_floatingip(network, resource_group, ip):
for public_ip in network.public_ip_addresses.list(resource_group):
if public_ip.ip_address == ip:
return public_ip
raise FloatingIPNotFound(ip=ip)
@azure_handle_exception
def delete_floatingip(network, resource_group, public_ip_name):
_perform_and_wait(network.public_ip_addresses.delete, (resource_group,
public_ip_name))

View File

@ -0,0 +1,349 @@
"""
Copyright 2017 Platform9 Systems Inc.(http://www.platform9.com)
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 random
from oslo_log import log
import ipaddr
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.common.azure.config import azure_conf
from neutron.common.azure import utils
from neutron.manager import NeutronManager
from neutron.plugins.ml2 import driver_api as api
from neutron_lib import constants as n_const
from neutron_lib import exceptions as e
try:
from neutron_lib.plugins import directory
except ImportError:
pass
LOG = log.getLogger(__name__)
def log_network_hook(function):
def wraps(self, context):
LOG.debug("Called %s with context: %s" % (function.__name__, context))
return function(self, context)
return wraps
# Custom VIF type for Azure
VIF_TYPE_AZURE = "azure_nic"
class AzureMechanismDriver(api.MechanismDriver):
"""Ml2 Mechanism driver for Azure"""
def __init__(self):
super(AzureMechanismDriver, self).__init__()
self._network_client = None
self._sg_callback_map = {}
def initialize(self):
LOG.info("Azure Mechanism driver init with %s project, %s region" %
(azure_conf.tenant_id, azure_conf.region))
self._subscribe_events()
def _subscribe_events(self):
events_info = [(resources.SECURITY_GROUP, events.BEFORE_DELETE,
self._delete_secgrp),
(resources.SECURITY_GROUP, events.BEFORE_UPDATE,
self._update_secgrp), (resources.SECURITY_GROUP,
events.BEFORE_CREATE,
self._validate_secgrp),
(resources.SECURITY_GROUP, events.AFTER_CREATE,
self._create_secgrp), (resources.SECURITY_GROUP_RULE,
events.BEFORE_DELETE,
self._delete_secrule),
(resources.SECURITY_GROUP_RULE, events.BEFORE_UPDATE,
self._update_secrule), (resources.SECURITY_GROUP_RULE,
events.BEFORE_CREATE,
self._validate_secrule),
(resources.SECURITY_GROUP_RULE, events.AFTER_CREATE,
self._create_secrule)]
for resource, event, callback in events_info:
registry.subscribe(self.secgrp_callback, resource, event)
self._sg_callback_map[(resource, event)] = callback
LOG.info("Azure mechanism driver registered security groups callbacks")
@property
def network_client(self):
conf = azure_conf
if self._network_client is None:
args = (conf.tenant_id, conf.client_id, conf.client_secret,
conf.subscription_id)
self._network_client = utils.get_network_client(*args)
return self._network_client
def _azure_network_name(self, context):
return 'net-' + context.current[api.ID]
def _azure_subnet_name(self, context):
return 'subnet-' + context.current[api.ID]
def _azure_subnet_network_name(self, context):
return 'net-' + context.current['network_id']
def _azure_secgrp_id(self, openstack_id):
return "secgrp-" + openstack_id
def _azure_secrule_id(self, openstack_id):
return "secrule-" + openstack_id
@staticmethod
def is_private_network(cidr):
return ipaddr.IPNetwork(cidr).is_private
@log_network_hook
def create_network_precommit(self, context):
pass
@log_network_hook
def create_network_postcommit(self, context):
pass
@log_network_hook
def update_network_precommit(self, context):
pass
@log_network_hook
def update_network_postcommit(self, context):
pass
@log_network_hook
def delete_network_precommit(self, context):
pass
@log_network_hook
def delete_network_postcommit(self, context):
name = self._azure_network_name(context)
utils.delete_network(self.network_client, azure_conf.resource_group,
name)
@log_network_hook
def create_subnet_precommit(self, context):
net_svc = self.network_client
name = self._azure_subnet_name(context)
network_name = self._azure_subnet_network_name(context)
cidr = context.current['cidr']
if self.is_private_network(cidr):
try:
azure_network = utils.get_network(
net_svc, azure_conf.resource_group, network_name)
address_prefixes = azure_network.address_space.address_prefixes
if cidr not in address_prefixes:
address_prefixes.append(cidr)
utils.update_network(net_svc, azure_conf.resource_group,
network_name, azure_network)
except e.NetworkNotFound:
body = {
'location': azure_conf.region,
'address_space': {
'address_prefixes': [
cidr,
]
}
}
utils.create_network(net_svc, azure_conf.resource_group,
network_name, body)
utils.create_subnet(net_svc, azure_conf.resource_group,
network_name, name, {'address_prefix': cidr})
@log_network_hook
def create_subnet_postcommit(self, context):
pass
@log_network_hook
def update_subnet_precommit(self, context):
pass
@log_network_hook
def update_subnet_postcommit(self, context):
pass
@log_network_hook
def delete_subnet_precommit(self, context):
cidr = context.current['cidr']
if self.is_private_network(cidr):
name = self._azure_subnet_name(context)
network_name = self._azure_subnet_network_name(context)
utils.delete_subnet(self.network_client, azure_conf.resource_group,
network_name, name)
@log_network_hook
def delete_subnet_postcommit(self, context):
pass
def _check_dev_owner(self, port_context):
dev_owner = port_context.current['device_owner']
return len(dev_owner) == 0 or dev_owner.startswith(
n_const.DEVICE_OWNER_COMPUTE_PREFIX)
@log_network_hook
def create_port_precommit(self, context):
LOG.debug("Create_port_precommit: %s" % context.current)
if not self._check_dev_owner(context):
return
net_svc = self.network_client
resource_group = azure_conf.resource_group
region = azure_conf.region
network_name = self._azure_subnet_network_name(context)
details = context.current['fixed_ips'][0]
subnet_name = 'subnet-' + details['subnet_id']
ip_address = details['ip_address']
nic_name = 'nic-' + context.current['id']
ipc_name = 'ipc-' + context.current['id']
azure_subnet = utils.get_subnet(net_svc, resource_group, network_name,
subnet_name)
body = {
'location':
region,
'ip_configurations': [{
'name': ipc_name,
'private_ip_address': ip_address,
'private_ip_allocation_method': 'Static',
'subnet': {
'id': azure_subnet.id
},
}]
}
security_groups = context.current['security_groups']
if security_groups and len(security_groups) == 1:
sg_name = self._azure_secgrp_id(security_groups[0])
sg = utils.get_sg(net_svc, resource_group, sg_name)
body['network_security_group'] = {'id': sg.id}
utils.create_nic(net_svc, resource_group, nic_name, body)
LOG.info("Created NIC %s on Azure." % nic_name)
@log_network_hook
def create_port_postcommit(self, context):
pass
@log_network_hook
def update_port_precommit(self, context):
pass
@log_network_hook
def update_port_postcommit(self, context):
pass
@log_network_hook
def delete_port_precommit(self, context):
if not self._check_dev_owner(context):
return
net_svc = self.network_client
resource_group = azure_conf.resource_group
nic_name = 'nic-' + context.current['id']
utils.get_nic(net_svc, resource_group, nic_name)
utils.delete_nic(net_svc, resource_group, nic_name)
LOG.info("Deleted NIC %s on Azure." % nic_name)
@log_network_hook
def delete_port_postcommit(self, context):
pass
def get_secgrp(self, context, id):
try:
core_plugin = NeutronManager.get_plugin()
except AttributeError:
core_plugin = directory.get_plugin()
return core_plugin.get_security_group(context, id)
def get_secgrp_rule(self, context, id):
try:
core_plugin = NeutronManager.get_plugin()
except AttributeError:
core_plugin = directory.get_plugin()
return core_plugin.get_security_group_rule(context, id)
def _validate_secrule(self, **kwargs):
rule = kwargs['security_group_rule']
utils.convert_sg_rule(rule)
def _create_secrule(self, **kwargs):
net_svc = self.network_client
resource_group = azure_conf.resource_group
rule = kwargs['security_group_rule']
azure_rule = utils.convert_sg_rule(rule)
sg_name = self._azure_secgrp_id(rule['security_group_id'])
name = self._azure_secrule_id(rule['id'])
sg = utils.get_sg(net_svc, resource_group, sg_name)
"""Each Azure security rule has a priority.
The value can be between 100 and 4096. The priority number must be
unique for each rule in the collection. The lower the priority number,
the higher the priority of the rule.
"""
previous_priorities = sorted([i.priority for i in sg.security_rules])
if previous_priorities:
priority = previous_priorities[-1] + 1
else:
priority = 100
azure_rule['priority'] = priority
utils.create_sg_rule(net_svc, resource_group, sg_name, name,
azure_rule)
def _update_secrule(self, **kwargs):
pass
def _delete_secrule(self, **kwargs):
net_svc = self.network_client
resource_group = azure_conf.resource_group
secrule_id = kwargs['security_group_rule_id']
sec_rule = self.get_secgrp_rule(kwargs['context'], secrule_id)
sg_name = self._azure_secgrp_id(sec_rule['security_group_id'])
name = self._azure_secrule_id(secrule_id)
utils.delete_sg_rule(net_svc, resource_group, sg_name, name)
def _validate_secgrp(self, **kwargs):
pass
def _create_secgrp(self, **kwargs):
net_svc = self.network_client
resource_group = azure_conf.resource_group
region = azure_conf.region
name = self._azure_secgrp_id(kwargs['security_group']['id'])
body = {
'location': region,
}
utils.create_sg(net_svc, resource_group, name, body)
def _update_secgrp(self, **kwargs):
pass
def _delete_secgrp(self, **kwargs):
net_svc = self.network_client
resource_group = azure_conf.resource_group
name = self._azure_secgrp_id(kwargs['security_group_id'])
utils.delete_sg(net_svc, resource_group, name)
@log_network_hook
def bind_port(self, context):
fixed_ip_dict = dict()
if 'fixed_ips' in context.current:
if len(context.current['fixed_ips']):
fixed_ip_dict = context.current['fixed_ips'][0]
segment_id = random.choice(context.segments_to_bind)[api.ID]
context.set_binding(
segment_id, VIF_TYPE_AZURE, fixed_ip_dict, status='ACTIVE')
return True
def secgrp_callback(self, resource, event, trigger, **kwargs):
LOG.info("Secgrp_callback: %s %s %s" % (resource, event, kwargs))
callback = self._sg_callback_map[(resource, event)]
callback(**kwargs)

View File

@ -0,0 +1,203 @@
"""
Copyright 2017 Platform9 Systems Inc.(http://www.platform9.com)
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 neutron_lib
from distutils.version import LooseVersion
from neutron.common.azure.config import azure_conf
from neutron.common.azure import utils
from neutron.db import common_db_mixin
from neutron.db import extraroute_db
from neutron.db import l3_db
from neutron.db import l3_dvrscheduler_db
from neutron.db import l3_gwmode_db
from neutron.db import l3_hamode_db
from neutron.db import l3_hascheduler_db
from neutron.plugins.common import constants
from neutron.quota import resource_registry
from neutron.services import service_base
from neutron_lib import constants as n_const
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
if LooseVersion(neutron_lib.__version__) < LooseVersion("1.0.0"):
router = l3_db.Router
floating_ip = l3_db.FloatingIP
plugin_type = constants.L3_ROUTER_NAT
service_plugin_class = service_base.ServicePluginBase
else:
from neutron.db.models import l3
from neutron_lib.plugins import constants as plugin_constants
from neutron_lib.services import base
router = l3.Router
floating_ip = l3.FloatingIP
plugin_type = plugin_constants.L3
service_plugin_class = base.ServicePluginBase
class AzureRouterPlugin(
service_plugin_class, common_db_mixin.CommonDbMixin,
extraroute_db.ExtraRoute_db_mixin, l3_hamode_db.L3_HA_NAT_db_mixin,
l3_gwmode_db.L3_NAT_db_mixin, l3_dvrscheduler_db.L3_DVRsch_db_mixin,
l3_hascheduler_db.L3_HA_scheduler_db_mixin):
"""Implementation of the Neutron L3 Router Service Plugin.
This class implements a L3 service plugin that provides
router and floatingip resources and manages associated
request/response.
All DB related work is implemented in classes
l3_db.L3_NAT_db_mixin, l3_hamode_db.L3_HA_NAT_db_mixin,
l3_dvr_db.L3_NAT_with_dvr_db_mixin, and extraroute_db.ExtraRoute_db_mixin.
"""
supported_extension_aliases = [
"dvr", "router", "ext-gw-mode", "extraroute", "l3_agent_scheduler",
"l3-ha"
]
@resource_registry.tracked_resources(router=router, floatingip=floating_ip)
def __init__(self):
super(AzureRouterPlugin, self).__init__()
l3_db.subscribe()
self._compute_client = None
self._network_client = None
self.tenant_id = azure_conf.tenant_id
self.client_id = azure_conf.client_id
self.client_secret = azure_conf.client_secret
self.subscription_id = azure_conf.subscription_id
self.region = azure_conf.region
self.resource_group = azure_conf.resource_group
LOG.info("Azure Router plugin init with %s project, %s region" %
(self.tenant_id, self.region))
@property
def compute_client(self):
if self._compute_client is None:
args = (self.tenant_id, self.client_id, self.client_secret,
self.subscription_id)
self._compute_client = utils.get_compute_client(*args)
return self._compute_client
@property
def network_client(self):
if self._network_client is None:
args = (self.tenant_id, self.client_id, self.client_secret,
self.subscription_id)
self._network_client = utils.get_network_client(*args)
return self._network_client
def get_plugin_type(self):
return plugin_type
def get_plugin_description(self):
"""returns string description of the plugin."""
return ("Azure L3 Router Service Plugin for basic L3 forwarding"
" between (L2) Neutron networks and access to external"
" networks via a NAT gateway.")
def _add_floatingip_to_port(self, port_id, public_ip):
net_svc = self.network_client
resource_group = self.resource_group
nic_name = 'nic-' + port_id
nic = utils.get_nic(net_svc, resource_group, nic_name)
nic.ip_configurations[0].public_ip_address = public_ip
utils.update_nic(net_svc, resource_group, nic_name, nic)
def _remove_floatingip_from_port(self, port_id):
self._add_floatingip_to_port(port_id, public_ip=None)
def create_floatingip(self, context, floatingip):
net_svc = self.network_client
resource_group = self.resource_group
public_ip = None
port_id = None
status = n_const.FLOATINGIP_STATUS_DOWN
try:
floatingip_dict = floatingip['floatingip']
public_ip = utils.allocate_floatingip(net_svc, resource_group,
self.region)
LOG.info("Created Azure static IP %s" % public_ip.ip_address)
floatingip_dict['floating_ip_address'] = public_ip.ip_address
port_id = floatingip_dict['port_id']
if port_id:
self._add_floatingip_to_port(port_id, public_ip)
status = n_const.FLOATINGIP_STATUS_ACTIVE
res = super(AzureRouterPlugin, self).create_floatingip(
context, floatingip, initial_status=status)
except Exception as e:
LOG.exception("Error in Creation/Allocating floating IP: %s" % e)
if status == n_const.FLOATINGIP_STATUS_ACTIVE:
self._remove_floatingip_from_port(port_id)
if public_ip:
utils.delete_floatingip(net_svc, resource_group,
public_ip.name)
raise e
return res
def update_floatingip(self, context, id, floatingip):
net_svc = self.network_client
resource_group = self.resource_group
status = n_const.FLOATINGIP_STATUS_DOWN
floatingip_dict = floatingip['floatingip']
orig_floatingip = super(AzureRouterPlugin, self).get_floatingip(
context, id)
ip_address = orig_floatingip['floating_ip_address']
port_id = floatingip_dict['port_id']
if port_id:
public_ip = utils.get_floatingip(net_svc, resource_group,
ip_address)
self._add_floatingip_to_port(port_id, public_ip)
status = n_const.FLOATINGIP_STATUS_ACTIVE
else:
self._remove_floatingip_from_port(orig_floatingip['port_id'])
floatingip_dict['status'] = status
return super(AzureRouterPlugin, self).update_floatingip(
context, id, floatingip)
def delete_floatingip(self, context, id):
net_svc = self.network_client
resource_group = self.resource_group
floating_ip = super(AzureRouterPlugin, self).get_floatingip(
context, id)
ip_address = floating_ip['floating_ip_address']
public_ip = utils.get_floatingip(net_svc, resource_group, ip_address)
port_id = floating_ip['port_id']
if port_id:
self._remove_floatingip_from_port(port_id)
utils.delete_floatingip(net_svc, resource_group, public_ip.name)
return super(AzureRouterPlugin, self).delete_floatingip(context, id)
def create_router(self, context, router):
LOG.debug("Creating router %s" % router['router']['name'])
return super(AzureRouterPlugin, self).create_router(context, router)
def delete_router(self, context, id):
LOG.debug("Deleting router %s" % id)
return super(AzureRouterPlugin, self).delete_router(context, id)
def update_router(self, context, id, router):
LOG.debug("Updating router %s" % id)
return super(AzureRouterPlugin, self).update_router(
context, id, router)
def add_router_interface(self, context, router_id, interface_info):
LOG.debug("Adding interface %s to router %s" % (interface_info,
router_id))
return super(AzureRouterPlugin, self).add_router_interface(
context, router_id, interface_info)
def remove_router_interface(self, context, router_id, interface_info):
LOG.debug("Deleting interface %s from router %s" % (interface_info,
router_id))
return super(AzureRouterPlugin, self).remove_router_interface(
context, router_id, interface_info)