nfv/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/nfvi_network_api.py

770 lines
26 KiB
Python
Executable File

#
# Copyright (c) 2015-2018 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import httplib
from nfv_common import debug
from nfv_vim import nfvi
from nfv_plugins.nfvi_plugins import config
from nfv_plugins.nfvi_plugins.openstack import exceptions
from nfv_plugins.nfvi_plugins.openstack import openstack
from nfv_plugins.nfvi_plugins.openstack import neutron
from nfv_plugins.nfvi_plugins.openstack.objects import OPENSTACK_SERVICE
DLOG = debug.debug_get_logger('nfv_plugins.nfvi_plugins.network_api')
def network_get_admin_state(admin_state):
"""
Convert the nfvi network administrative state to a network administrative
state
"""
if neutron.NETWORK_ADMIN_STATE.UP == admin_state:
return nfvi.objects.v1.NETWORK_ADMIN_STATE.UNLOCKED
else:
return nfvi.objects.v1.NETWORK_ADMIN_STATE.LOCKED
def network_get_oper_state(status):
"""
Convert the nfvi network status to a network operational state
"""
if neutron.NETWORK_STATUS.ACTIVE == status:
return nfvi.objects.v1.NETWORK_OPER_STATE.ENABLED
else:
return nfvi.objects.v1.NETWORK_OPER_STATE.DISABLED
def network_get_avail_status(status):
"""
Convert the nfvi network status to a network availability status
"""
avail_status = list()
if neutron.NETWORK_STATUS.BUILD == status:
avail_status.append(nfvi.objects.v1.NETWORK_AVAIL_STATUS.BUILDING)
elif neutron.NETWORK_STATUS.ERROR == status:
avail_status.append(nfvi.objects.v1.NETWORK_AVAIL_STATUS.FAILED)
return avail_status
class NFVINetworkAPI(nfvi.api.v1.NFVINetworkAPI):
"""
NFVI Network API Class Definition
"""
_name = 'Network-API'
_version = '1.0.0'
_provider = 'Wind River'
_signature = '22b3dbf6-e4ba-441b-8797-fb8a51210a43'
def __init__(self):
super(NFVINetworkAPI, self).__init__()
self._token = None
self._directory = None
@property
def name(self):
return self._name
@property
def version(self):
return self._version
@property
def provider(self):
return self._provider
@property
def signature(self):
return self._signature
def get_networks(self, future, paging, callback):
"""
Get a list of networks
"""
response = dict()
response['completed'] = False
response['reason'] = ''
response['page-request-id'] = paging.page_request_id
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._directory.get_service_info(OPENSTACK_SERVICE.NEUTRON) \
is None:
DLOG.info("Neutron service get-networks not available.")
response['result-data'] = list()
response['completed'] = True
paging.next_page = None
return
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
return
self._token = future.result.data
DLOG.verbose("Network paging (before): %s" % paging)
future.work(neutron.get_networks, self._token, paging.page_limit,
paging.next_page)
future.result = (yield)
if not future.result.is_complete():
return
network_data_list = future.result.data
network_objs = list()
for network_data in network_data_list['networks']:
provider_data = nfvi.objects.v1.NetworkProviderData(
network_data['provider:physical_network'],
network_data['provider:network_type'],
network_data['provider:segmentation_id'])
network_obj = nfvi.objects.v1.Network(
network_data['id'], network_data['name'],
network_get_admin_state(network_data['admin_state_up']),
network_get_oper_state(network_data['status']),
network_get_avail_status(network_data['status']),
network_data['shared'],
network_data['mtu'],
provider_data)
network_objs.append(network_obj)
paging.next_page = None
networks_links = network_data_list.get('networks_links', None)
if networks_links is not None:
for network_link in networks_links:
if 'next' == network_link['rel']:
paging.next_page = network_link['href']
break
DLOG.verbose("Network paging (after): %s" % paging)
response['result-data'] = network_objs
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to get list of "
"networks, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to get network list, "
"error=%s." % e)
finally:
callback.send(response)
callback.close()
def create_network(self, future, network_name, network_type,
segmentation_id, physical_network, shared, callback):
"""
Create a network
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
return
self._token = future.result.data
future.work(neutron.create_network, self._token, network_name,
network_type, segmentation_id, physical_network,
shared)
future.result = (yield)
if not future.result.is_complete():
return
network_data = future.result.data['network']
provider_data = nfvi.objects.v1.NetworkProviderData(
network_data['provider:physical_network'],
network_data['provider:network_type'],
network_data['provider:segmentation_id'])
network_obj = nfvi.objects.v1.Network(
network_data['id'], network_data['name'],
network_get_admin_state(network_data['admin_state_up']),
network_get_oper_state(network_data['status']),
network_get_avail_status(network_data['status']),
network_data['shared'],
network_data['mtu'],
provider_data)
response['result-data'] = network_obj
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to create a "
"network, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to create a network, "
"error=%s." % e)
finally:
callback.send(response)
callback.close()
def update_network(self, future, network_uuid, shared, callback):
"""
Update a network
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
return
self._token = future.result.data
future.work(neutron.update_network, self._token, network_uuid,
shared=shared)
future.result = (yield)
if not future.result.is_complete():
return
network_data = future.result.data['network']
provider_data = nfvi.objects.v1.NetworkProviderData(
network_data['provider:physical_network'],
network_data['provider:network_type'],
network_data['provider:segmentation_id'])
network_obj = nfvi.objects.v1.Network(
network_data['id'], network_data['name'],
network_get_admin_state(network_data['admin_state_up']),
network_get_oper_state(network_data['status']),
network_get_avail_status(network_data['status']),
network_data['shared'],
network_data['mtu'],
provider_data)
response['result-data'] = network_obj
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to update a "
"network, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to update a network, "
"error=%s." % e)
finally:
callback.send(response)
callback.close()
def delete_network(self, future, network_uuid, callback):
"""
Delete a network
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
return
self._token = future.result.data
future.work(neutron.delete_network, self._token, network_uuid)
future.result = (yield)
if not future.result.is_complete():
return
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
elif httplib.NOT_FOUND == e.http_status_code:
response['completed'] = True
else:
DLOG.exception("Caught exception while trying to delete a "
"network, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to delete a network, "
"error=%s." % e)
finally:
callback.send(response)
callback.close()
def get_network(self, future, network_uuid, callback):
"""
Get a network
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
return
self._token = future.result.data
future.work(neutron.get_network, self._token, network_uuid)
future.result = (yield)
if not future.result.is_complete():
return
network_data = future.result.data['network']
provider_data = nfvi.objects.v1.NetworkProviderData(
network_data['provider:physical_network'],
network_data['provider:network_type'],
network_data['provider:segmentation_id'])
network_obj = nfvi.objects.v1.Network(
network_data['id'], network_data['name'],
network_get_admin_state(network_data['admin_state_up']),
network_get_oper_state(network_data['status']),
network_get_avail_status(network_data['status']),
network_data['shared'],
network_data['mtu'],
provider_data)
response['result-data'] = network_obj
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
elif httplib.NOT_FOUND == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.NOT_FOUND
else:
DLOG.exception("Caught exception while trying to get a "
"network, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to get a network, "
"error=%s." % e)
finally:
callback.send(response)
callback.close()
def get_subnets(self, future, paging, callback):
"""
Get a list of subnets
"""
response = dict()
response['completed'] = False
response['reason'] = ''
response['page-request-id'] = paging.page_request_id
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._directory.get_service_info(OPENSTACK_SERVICE.NEUTRON) \
is None:
DLOG.info("Neutron service get-subnets not available.")
response['result-data'] = list()
response['completed'] = True
paging.next_page = None
return
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
return
self._token = future.result.data
DLOG.verbose("Subnet paging (before): %s" % paging)
future.work(neutron.get_subnets, self._token, paging.page_limit,
paging.next_page)
future.result = (yield)
if not future.result.is_complete():
return
subnet_data_list = future.result.data
subnet_objs = list()
for subnet_data in subnet_data_list['subnets']:
subnet = subnet_data['cidr'].split('/')
subnet_ip = subnet[0]
subnet_prefix = subnet[1]
subnet_obj = nfvi.objects.v1.Subnet(subnet_data['id'],
subnet_data['name'],
subnet_data['ip_version'],
subnet_ip, subnet_prefix,
subnet_data['gateway_ip'],
subnet_data['network_id'],
subnet_data['enable_dhcp'])
subnet_objs.append(subnet_obj)
paging.next_page = None
subnet_links = subnet_data_list.get('subnets_links', None)
if subnet_links is not None:
for subnet_link in subnet_links:
if 'next' == subnet_link['rel']:
paging.next_page = subnet_link['href']
break
DLOG.verbose("Subnet paging (after): %s" % paging)
response['result-data'] = subnet_objs
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
elif httplib.NOT_FOUND == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.NOT_FOUND
else:
DLOG.exception("Caught exception while trying to get list of "
"subnets, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to get subnet list, "
"error=%s." % e)
finally:
callback.send(response)
callback.close()
def create_subnet(self, future, network_uuid, subnet_name, ip_version,
subnet_ip, subnet_prefix, gateway_ip, dhcp_enabled,
callback):
"""
Create a subnet
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
return
self._token = future.result.data
cidr = "%s/%s" % (subnet_ip, subnet_prefix)
future.work(neutron.create_subnet, self._token, network_uuid,
subnet_name, ip_version, cidr, gateway_ip,
dhcp_enabled)
future.result = (yield)
if not future.result.is_complete():
return
subnet_data = future.result.data['subnet']
subnet = subnet_data['cidr'].split('/')
subnet_ip = subnet[0]
subnet_prefix = subnet[1]
subnet_obj = nfvi.objects.v1.Subnet(subnet_data['id'],
subnet_data['name'],
subnet_data['ip_version'],
subnet_ip, subnet_prefix,
subnet_data['gateway_ip'],
subnet_data['network_id'],
subnet_data['enable_dhcp'])
response['result-data'] = subnet_obj
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to create a "
"subnet, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to create a subnet, "
"error=%s." % e)
finally:
callback.send(response)
callback.close()
def update_subnet(self, future, subnet_uuid, gateway_ip, delete_gateway,
dhcp_enabled, callback):
"""
Update a subnet
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
return
self._token = future.result.data
future.work(neutron.update_subnet, self._token, subnet_uuid,
gateway_ip, dhcp_enabled, delete_gateway)
future.result = (yield)
if not future.result.is_complete():
return
subnet_data = future.result.data['subnet']
subnet = subnet_data['cidr'].split('/')
subnet_ip = subnet[0]
subnet_prefix = subnet[1]
subnet_obj = nfvi.objects.v1.Subnet(subnet_data['id'],
subnet_data['name'],
subnet_data['ip_version'],
subnet_ip, subnet_prefix,
subnet_data['gateway_ip'],
subnet_data['network_id'],
subnet_data['enable_dhcp'])
response['result-data'] = subnet_obj
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
else:
DLOG.exception("Caught exception while trying to update a "
"subnet, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to update a subnet, "
"error=%s." % e)
finally:
callback.send(response)
callback.close()
def delete_subnet(self, future, subnet_uuid, callback):
"""
Delete a subnet
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
return
self._token = future.result.data
future.work(neutron.delete_subnet, self._token, subnet_uuid)
future.result = (yield)
if not future.result.is_complete():
return
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
elif httplib.NOT_FOUND == e.http_status_code:
response['completed'] = True
else:
DLOG.exception("Caught exception while trying to delete a "
"subnet, error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to delete a subnet, "
"error=%s." % e)
finally:
callback.send(response)
callback.close()
def get_subnet(self, future, subnet_uuid, callback):
"""
Get a subnet
"""
response = dict()
response['completed'] = False
response['reason'] = ''
try:
future.set_timeouts(config.CONF.get('nfvi-timeouts', None))
if self._token is None or self._token.is_expired():
future.work(openstack.get_token, self._directory)
future.result = (yield)
if not future.result.is_complete():
return
self._token = future.result.data
future.work(neutron.get_subnet, self._token, subnet_uuid)
future.result = (yield)
if not future.result.is_complete():
return
subnet_data = future.result.data['subnet']
subnet = subnet_data['cidr'].split('/')
subnet_ip = subnet[0]
subnet_prefix = subnet[1]
subnet_obj = nfvi.objects.v1.Subnet(subnet_data['id'],
subnet_data['name'],
subnet_data['ip_version'],
subnet_ip, subnet_prefix,
subnet_data['gateway_ip'],
subnet_data['network_id'],
subnet_data['enable_dhcp'])
response['result-data'] = subnet_obj
response['completed'] = True
except exceptions.OpenStackRestAPIException as e:
if httplib.UNAUTHORIZED == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.TOKEN_EXPIRED
if self._token is not None:
self._token.set_expired()
elif httplib.NOT_FOUND == e.http_status_code:
response['error-code'] = nfvi.NFVI_ERROR_CODE.NOT_FOUND
else:
DLOG.exception("Caught exception while trying to get a subnet, "
"error=%s." % e)
except Exception as e:
DLOG.exception("Caught exception while trying to get a subnet, "
"error=%s." % e)
finally:
callback.send(response)
callback.close()
def initialize(self, config_file):
"""
Initialize the plugin
"""
config.load(config_file)
self._directory = openstack.get_directory(
config, openstack.SERVICE_CATEGORY.OPENSTACK)
def finalize(self):
"""
Finalize the plugin
"""
return