Remove deprecated nova infra driver
Change-Id: I0b5b729741999f6505d3c9e3c7d62566acc28786 Closes-bug: 1634011
This commit is contained in:
parent
ad1997684b
commit
70500539c5
@ -251,25 +251,6 @@ function configure_tacker {
|
||||
iniset $TACKER_CONF alarm_auth project_name "$SERVICE_PROJECT_NAME"
|
||||
iniset $TACKER_CONF alarm_auth url http://$SERVICE_HOST:35357/v3
|
||||
|
||||
# Configuration for tacker requests to nova.
|
||||
iniset $TACKER_CONF DEFAULT nova_url $TACKER_NOVA_URL
|
||||
iniset $TACKER_CONF DEFAULT nova_admin_user_name nova
|
||||
iniset $TACKER_CONF DEFAULT nova_admin_password $SERVICE_PASSWORD
|
||||
iniset $TACKER_CONF DEFAULT nova_admin_tenant_id $SERVICE_TENANT_NAME
|
||||
iniset $TACKER_CONF DEFAULT nova_admin_auth_url $KEYSTONE_AUTH_URI
|
||||
iniset $TACKER_CONF DEFAULT nova_ca_certificates_file $TACKER_NOVA_CA_CERTIFICATES_FILE
|
||||
iniset $TACKER_CONF DEFAULT nova_api_insecure $TACKER_NOVA_API_INSECURE
|
||||
iniset $TACKER_CONF DEFAULT nova_region_name $REGION_NAME
|
||||
|
||||
iniset $TACKER_CONF tacker_nova auth_plugin password
|
||||
iniset $TACKER_CONF tacker_nova auth_url $KEYSTONE_AUTH_URI
|
||||
iniset $TACKER_CONF tacker_nova username nova
|
||||
iniset $TACKER_CONF tacker_nova password $SERVICE_PASSWORD
|
||||
iniset $TACKER_CONF tacker_nova user_domain_id default
|
||||
iniset $TACKER_CONF tacker_nova project_name $SERVICE_TENANT_NAME
|
||||
iniset $TACKER_CONF tacker_nova project_domain_id default
|
||||
iniset $TACKER_CONF tacker_nova region_name $REGION_NAME
|
||||
|
||||
iniset $TACKER_CONF tacker_heat heat_uri http://$SERVICE_HOST:8004/v1
|
||||
iniset $TACKER_CONF tacker_heat stack_retries 60
|
||||
iniset $TACKER_CONF tacker_heat stack_retry_wait 5
|
||||
|
@ -206,10 +206,6 @@ d). Provide an endpoint to tacker service.
|
||||
[DATABASE]
|
||||
connection = mysql://tacker:<TACKERDB_PASSWORD>@<MYSQL_IP>:3306/tacker?charset=utf8
|
||||
...
|
||||
[tacker_nova]
|
||||
password = <NOVA_SERVICE_USER_PASSWORD>
|
||||
auth_url = http://<NOVA_IP>:35357
|
||||
...
|
||||
[tacker_heat]
|
||||
heat_uri = http://<HEAT_IP>:8004/v1
|
||||
..
|
||||
|
@ -51,7 +51,6 @@ tacker.openstack.common.cache.backends =
|
||||
memory = tacker.openstack.common.cache._backends.memory:MemoryBackend
|
||||
tacker.tacker.vnfm.drivers =
|
||||
noop = tacker.vnfm.infra_drivers.noop:DeviceNoop
|
||||
nova = tacker.vnfm.infra_drivers.nova.nova:DeviceNova
|
||||
heat = tacker.vnfm.infra_drivers.heat.heat:DeviceHeat
|
||||
openstack = tacker.vnfm.infra_drivers.openstack.openstack:OpenStack
|
||||
tacker.tacker.mgmt.drivers =
|
||||
|
@ -58,27 +58,6 @@ core_opts = [
|
||||
"means no limit")),
|
||||
cfg.StrOpt('host', default=utils.get_hostname(),
|
||||
help=_("The hostname Tacker is running on")),
|
||||
cfg.StrOpt('nova_url',
|
||||
default='http://127.0.0.1:8774/v2',
|
||||
help=_('URL for connection to nova')),
|
||||
cfg.StrOpt('nova_admin_username',
|
||||
help=_('Username for connecting to nova in admin context')),
|
||||
cfg.StrOpt('nova_admin_password',
|
||||
help=_('Password for connection to nova in admin context'),
|
||||
secret=True),
|
||||
cfg.StrOpt('nova_admin_tenant_id',
|
||||
help=_('The uuid of the admin nova tenant')),
|
||||
cfg.StrOpt('nova_admin_auth_url',
|
||||
default='http://localhost:5000/v2.0',
|
||||
help=_('Authorization URL for connecting to nova in admin '
|
||||
'context')),
|
||||
cfg.StrOpt('nova_ca_certificates_file',
|
||||
help=_('CA file for novaclient to verify server certificates')),
|
||||
cfg.BoolOpt('nova_api_insecure', default=False,
|
||||
help=_("If True, ignore any SSL validation issues")),
|
||||
cfg.StrOpt('nova_region_name',
|
||||
help=_('Name of nova region to use. Useful if keystone manages'
|
||||
' more than one region.')),
|
||||
]
|
||||
|
||||
core_cli_opts = [
|
||||
|
@ -59,7 +59,7 @@ class VNFD(model_base.BASE, models_v1.HasId, models_v1.HasTenant,
|
||||
# In future, single service VM may accomodate multiple services.
|
||||
service_types = orm.relationship('ServiceType', backref='vnfd')
|
||||
|
||||
# driver to create hosting vnf. e.g. noop, nova, heat, etc...
|
||||
# driver to create hosting vnf. e.g. noop, heat, etc...
|
||||
infra_driver = sa.Column(sa.String(255))
|
||||
|
||||
# driver to communicate with service managment
|
||||
@ -84,8 +84,7 @@ class ServiceType(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
|
||||
class VNFDAttribute(model_base.BASE, models_v1.HasId):
|
||||
"""Represents attributes necessary for spinning up VM in (key, value) pair
|
||||
|
||||
key value pair is adopted for being agnostic to actuall manager of VMs
|
||||
like nova, heat or others. e.g. image-id, flavor-id for Nova.
|
||||
key value pair is adopted for being agnostic to actuall manager of VMs.
|
||||
The interpretation is up to actual driver of hosting vnf.
|
||||
"""
|
||||
|
||||
@ -112,7 +111,7 @@ class VNF(model_base.BASE, models_v1.HasId, models_v1.HasTenant,
|
||||
description = sa.Column(sa.Text, nullable=True)
|
||||
|
||||
# sufficient information to uniquely identify hosting vnf.
|
||||
# In case of service VM, it's UUID of nova VM.
|
||||
# In case of openstack manager, it's UUID of heat stack.
|
||||
instance_id = sa.Column(sa.String(64), nullable=True)
|
||||
|
||||
# For a management tool to talk to manage this hosting vnf.
|
||||
@ -131,8 +130,7 @@ class VNF(model_base.BASE, models_v1.HasId, models_v1.HasTenant,
|
||||
class VNFAttribute(model_base.BASE, models_v1.HasId):
|
||||
"""Represents kwargs necessary for spinning up VM in (key, value) pair.
|
||||
|
||||
key value pair is adopted for being agnostic to actuall manager of VMs
|
||||
like nova, heat or others. e.g. image-id, flavor-id for Nova.
|
||||
key value pair is adopted for being agnostic to actuall manager of VMs.
|
||||
The interpretation is up to actual driver of hosting vnf.
|
||||
"""
|
||||
|
||||
|
@ -1,281 +0,0 @@
|
||||
# Copyright 2013, 2014 Intel Corporation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
#
|
||||
# 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 time
|
||||
|
||||
|
||||
from keystoneclient import auth as ks_auth
|
||||
from keystoneclient.auth.identity import v2 as v2_auth
|
||||
from keystoneclient import session as ks_session
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_log import versionutils
|
||||
from six import iteritems
|
||||
|
||||
from tacker.api.v1 import attributes
|
||||
from tacker._i18n import _LE, _LW
|
||||
from tacker.vnfm.infra_drivers import abstract_driver
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
NOVA_API_VERSION = "2"
|
||||
TACKER_NOVA_CONF_SECTION = 'tacker_nova'
|
||||
ks_session.Session.register_conf_options(cfg.CONF, TACKER_NOVA_CONF_SECTION)
|
||||
ks_auth.register_conf_options(cfg.CONF, TACKER_NOVA_CONF_SECTION)
|
||||
OPTS = [
|
||||
cfg.StrOpt('region_name',
|
||||
help=_('Name of nova region to use. Useful if keystone manages'
|
||||
' more than one region.')),
|
||||
]
|
||||
CONF.register_opts(OPTS, group=TACKER_NOVA_CONF_SECTION)
|
||||
_NICS = 'nics' # converted by novaclient => 'networks'
|
||||
_NET_ID = 'net-id' # converted by novaclient => 'uuid'
|
||||
_PORT_ID = 'port-id' # converted by novaclient => 'port'
|
||||
_FILES = 'files'
|
||||
|
||||
|
||||
class DefaultAuthPlugin(v2_auth.Password):
|
||||
"""A wrapper around standard v2 user/pass to handle bypass url.
|
||||
|
||||
This is only necessary because novaclient doesn't support endpoint_override
|
||||
yet - bug #1403329.
|
||||
|
||||
When this bug is fixed we can pass the endpoint_override to the client
|
||||
instead and remove this class.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self._endpoint_override = kwargs.pop('endpoint_override', None)
|
||||
super(DefaultAuthPlugin, self).__init__(**kwargs)
|
||||
|
||||
def get_endpoint(self, session, **kwargs):
|
||||
if self._endpoint_override:
|
||||
return self._endpoint_override
|
||||
|
||||
return super(DefaultAuthPlugin, self).get_endpoint(session, **kwargs)
|
||||
|
||||
|
||||
class DeviceNova(abstract_driver.DeviceAbstractDriver):
|
||||
|
||||
"""Nova driver of hosting vnf."""
|
||||
|
||||
@versionutils.deprecated(
|
||||
versionutils.deprecated.NEWTON,
|
||||
what='infra_driver nova',
|
||||
in_favor_of='infra_driver openstack',
|
||||
remove_in=+1)
|
||||
def __init__(self):
|
||||
super(DeviceNova, self).__init__()
|
||||
# avoid circular import
|
||||
from novaclient import client
|
||||
self._novaclient = client
|
||||
|
||||
def _nova_client(self, token=None):
|
||||
auth = ks_auth.load_from_conf_options(cfg.CONF,
|
||||
TACKER_NOVA_CONF_SECTION)
|
||||
endpoint_override = None
|
||||
|
||||
if not auth:
|
||||
LOG.warning(_LW('Authenticating to nova using nova_admin_* options'
|
||||
' is deprecated. This should be done using'
|
||||
' an auth plugin, like password'))
|
||||
|
||||
if cfg.CONF.nova_admin_tenant_id:
|
||||
endpoint_override = "%s/%s" % (cfg.CONF.nova_url,
|
||||
cfg.CONF.nova_admin_tenant_id)
|
||||
|
||||
auth = DefaultAuthPlugin(
|
||||
auth_url=cfg.CONF.nova_admin_auth_url,
|
||||
username=cfg.CONF.nova_admin_username,
|
||||
password=cfg.CONF.nova_admin_password,
|
||||
tenant_id=cfg.CONF.nova_admin_tenant_id,
|
||||
tenant_name=cfg.CONF.nova_admin_tenant_name,
|
||||
endpoint_override=endpoint_override)
|
||||
|
||||
session = ks_session.Session.load_from_conf_options(
|
||||
cfg.CONF, TACKER_NOVA_CONF_SECTION, auth=auth)
|
||||
novaclient_cls = self._novaclient.get_client_class(NOVA_API_VERSION)
|
||||
return novaclient_cls(session=session,
|
||||
region_name=cfg.CONF.tacker_nova.region_name)
|
||||
|
||||
def get_type(self):
|
||||
return 'nova'
|
||||
|
||||
def get_name(self):
|
||||
return 'nova'
|
||||
|
||||
def get_description(self):
|
||||
return 'VNF Nova driver'
|
||||
|
||||
@staticmethod
|
||||
def _safe_pop(d, name_list):
|
||||
res = None
|
||||
for name in name_list:
|
||||
if name in d:
|
||||
res = d.pop(name)
|
||||
break
|
||||
return res
|
||||
|
||||
def _create_port(self, plugin, context, tenant_id,
|
||||
network_id=None, subnet_id=None):
|
||||
# resolve subnet and create port
|
||||
LOG.debug(_('network_id %(network_id)s subnet_id %(subnet_id)s)'),
|
||||
{'network_id': network_id, 'subnet_id': subnet_id})
|
||||
if subnet_id:
|
||||
subnet = plugin._core_plugin.get_subnet(context, subnet_id)
|
||||
network_id = subnet['network_id']
|
||||
port_data = {
|
||||
'tenant_id': tenant_id,
|
||||
'network_id': network_id,
|
||||
'admin_state_up': True,
|
||||
'fixed_ips': attributes.ATTR_NOT_SPECIFIED,
|
||||
}
|
||||
if subnet_id:
|
||||
port_data['fixed_ips'] = [{'subnet_id': subnet_id}]
|
||||
|
||||
# See api.v2.base.prepare_request_body()
|
||||
for attr, attr_vals in iteritems(attributes.RESOURCE_ATTRIBUTE_MAP[
|
||||
attributes.PORTS]):
|
||||
if not attr_vals.get('allow_post', False):
|
||||
continue
|
||||
if attr in port_data:
|
||||
continue
|
||||
port_data[attr] = attr_vals['default']
|
||||
|
||||
LOG.debug(_('port_data %s'), port_data)
|
||||
port = plugin._core_plugin.create_port(context, {'port': port_data})
|
||||
LOG.debug(_('port %s'), port)
|
||||
return port['id']
|
||||
|
||||
def create(self, plugin, context, vnf):
|
||||
# typical required arguments are
|
||||
# 'name': name string
|
||||
# 'image': uuid
|
||||
# 'flavir': uuid
|
||||
#
|
||||
# for details, see the signature of
|
||||
# novaclient.v<version>.servers.SeverManager.create()
|
||||
|
||||
LOG.debug(_('vnf %s'), vnf)
|
||||
# flavor and image are specially treated by novaclient
|
||||
attributes = vnf['vnfd']['attributes'].copy()
|
||||
attributes.update(vnf['kwargs'])
|
||||
|
||||
name = self._safe_pop(attributes, ('name', ))
|
||||
if name is None:
|
||||
# TODO(yamahata): appropreate way to generate instance name
|
||||
name = (__name__ + ':' + self.__class__.__name__ + '-' +
|
||||
vnf['id'])
|
||||
image = self._safe_pop(attributes, ('image', 'imageRef'))
|
||||
flavor = self._safe_pop(attributes, ('flavor', 'flavorRef'))
|
||||
|
||||
files = plugin.mgmt_get_config(context, vnf)
|
||||
if files:
|
||||
attributes[_FILES] = files
|
||||
|
||||
LOG.debug(_('service_context: %s'), vnf.get('service_context', []))
|
||||
tenant_id = vnf['tenant_id']
|
||||
nics = []
|
||||
for sc_entry in vnf.get('service_context', []):
|
||||
LOG.debug(_('sc_entry: %s'), sc_entry)
|
||||
|
||||
# nova API doesn't return tacker port_id.
|
||||
# so create port if necessary by hand, and use it explicitly.
|
||||
if sc_entry['port_id']:
|
||||
LOG.debug(_('port_id %s specified'), sc_entry['port_id'])
|
||||
port_id = sc_entry['port_id']
|
||||
elif sc_entry['subnet_id']:
|
||||
LOG.debug(_('subnet_id %s specified'), sc_entry['subnet_id'])
|
||||
port_id = self._create_port(plugin, context, tenant_id,
|
||||
subnet_id=sc_entry['subnet_id'])
|
||||
elif sc_entry['network_id']:
|
||||
LOG.debug(_('network_id %s specified'), sc_entry['network_id'])
|
||||
port_id = self._create_port(plugin, context, tenant_id,
|
||||
network_id=sc_entry['network_id'])
|
||||
else:
|
||||
LOG.debug(_('skipping sc_entry %s'), sc_entry)
|
||||
continue
|
||||
|
||||
LOG.debug(_('port_id %s'), port_id)
|
||||
port = plugin._core_plugin.get_port(context, port_id)
|
||||
sc_entry['network_id'] = port['network_id']
|
||||
if not sc_entry['subnet_id'] and port['fixed_ips']:
|
||||
sc_entry['subnet_id'] = port['fixed_ips'][0]['subnet_id']
|
||||
sc_entry['port_id'] = port_id
|
||||
|
||||
nics.append({_PORT_ID: port_id})
|
||||
|
||||
if nics:
|
||||
attributes[_NICS] = nics
|
||||
LOG.debug(_('nics %(nics)s attributes %(attributes)s'),
|
||||
{'nics': nics, 'attributes': attributes})
|
||||
|
||||
nova = self._nova_client()
|
||||
instance = nova.servers.create(name, image, flavor, **attributes)
|
||||
return instance.id
|
||||
|
||||
def create_wait(self, plugin, context, vnf_dict, vnf_id):
|
||||
nova = self._nova_client()
|
||||
instance = nova.servers.get(vnf_id)
|
||||
status = instance.status
|
||||
# TODO(yamahata): timeout and error
|
||||
while status == 'BUILD':
|
||||
time.sleep(5)
|
||||
instance = nova.servers.get(instance.id)
|
||||
status = instance.status
|
||||
LOG.debug(_('status: %s'), status)
|
||||
|
||||
LOG.debug(_('status: %s'), status)
|
||||
if status == 'ERROR':
|
||||
raise RuntimeError(_("creation of server %s failed") % vnf_id)
|
||||
|
||||
def update(self, plugin, context, vnf_id, vnf_dict, vnf):
|
||||
# do nothing but checking if the instance exists at the moment
|
||||
nova = self._nova_client()
|
||||
nova.servers.get(vnf_id)
|
||||
|
||||
def update_wait(self, plugin, context, vnf_id):
|
||||
# do nothing but checking if the instance exists at the moment
|
||||
nova = self._nova_client()
|
||||
nova.servers.get(vnf_id)
|
||||
|
||||
def delete(self, plugin, context, vnf_id):
|
||||
nova = self._nova_client()
|
||||
try:
|
||||
instance = nova.servers.get(vnf_id)
|
||||
except self._novaclient.exceptions.NotFound:
|
||||
LOG.error(_LE("server %s is not found") %
|
||||
vnf_id)
|
||||
return
|
||||
instance.delete()
|
||||
|
||||
def delete_wait(self, plugin, context, vnf_id):
|
||||
nova = self._nova_client()
|
||||
# TODO(yamahata): timeout and error
|
||||
while True:
|
||||
try:
|
||||
instance = nova.servers.get(vnf_id)
|
||||
LOG.debug(_('instance status %s'), instance.status)
|
||||
except self._novaclient.exceptions.NotFound:
|
||||
break
|
||||
if instance.status == 'ERROR':
|
||||
raise RuntimeError(_("deletion of server %s failed") %
|
||||
vnf_id)
|
||||
time.sleep(5)
|
||||
|
||||
def get_resource_info(self, plugin, context, vnf_info, auth_attr,
|
||||
region_name=None):
|
||||
pass
|
@ -114,7 +114,7 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
||||
"""
|
||||
OPTS = [
|
||||
cfg.ListOpt(
|
||||
'infra_driver', default=['nova', 'heat', 'noop', 'openstack'],
|
||||
'infra_driver', default=['heat', 'noop', 'openstack'],
|
||||
help=_('Hosting vnf drivers tacker plugin will use')),
|
||||
]
|
||||
cfg.CONF.register_opts(OPTS, 'tacker')
|
||||
|
Loading…
Reference in New Issue
Block a user