nfv/nfv/nfv-plugins/nfv_plugins/nfvi_plugins/nfvi_network_api.py
Bart Wensley e547b8c136 Add support for containerized keystone to VIM
Adding support to the VIM for containerized keystone. The
VIM will now support two keystone instances:
- platform: bare metal keystone used to authenticate with
  platform services (e.g. sysinv, patching)
- openstack: containerized keystone used to authenticate with
  openstack services (e.g. nova, neutron, cinder)

For now, the VIM will use the same baremetal keystone for both
the platform and openstack, because we still only deploy with
the baremetal keystone.

Story: 2002876
Task: 26872

Depends-On: If4bd46a4c14cc65978774001cb2887e5d3e3607b
Change-Id: Id1ec639aa347e0c4e4019576d3c36c8c72aefedf
2018-10-03 08:29:08 -05:00

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