Merge "Remove deprecated nova infra driver"

This commit is contained in:
Jenkins 2016-11-07 07:46:46 +00:00 committed by Gerrit Code Review
commit 96833007f2
8 changed files with 5 additions and 333 deletions

View File

@ -251,25 +251,6 @@ function configure_tacker {
iniset $TACKER_CONF alarm_auth project_name "$SERVICE_PROJECT_NAME" iniset $TACKER_CONF alarm_auth project_name "$SERVICE_PROJECT_NAME"
iniset $TACKER_CONF alarm_auth url http://$SERVICE_HOST:35357/v3 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 heat_uri http://$SERVICE_HOST:8004/v1
iniset $TACKER_CONF tacker_heat stack_retries 60 iniset $TACKER_CONF tacker_heat stack_retries 60
iniset $TACKER_CONF tacker_heat stack_retry_wait 5 iniset $TACKER_CONF tacker_heat stack_retry_wait 5

View File

@ -206,10 +206,6 @@ d). Provide an endpoint to tacker service.
[DATABASE] [DATABASE]
connection = mysql://tacker:<TACKERDB_PASSWORD>@<MYSQL_IP>:3306/tacker?charset=utf8 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] [tacker_heat]
heat_uri = http://<HEAT_IP>:8004/v1 heat_uri = http://<HEAT_IP>:8004/v1
.. ..

View File

@ -51,7 +51,6 @@ tacker.openstack.common.cache.backends =
memory = tacker.openstack.common.cache._backends.memory:MemoryBackend memory = tacker.openstack.common.cache._backends.memory:MemoryBackend
tacker.tacker.vnfm.drivers = tacker.tacker.vnfm.drivers =
noop = tacker.vnfm.infra_drivers.noop:DeviceNoop noop = tacker.vnfm.infra_drivers.noop:DeviceNoop
nova = tacker.vnfm.infra_drivers.nova.nova:DeviceNova
heat = tacker.vnfm.infra_drivers.heat.heat:DeviceHeat heat = tacker.vnfm.infra_drivers.heat.heat:DeviceHeat
openstack = tacker.vnfm.infra_drivers.openstack.openstack:OpenStack openstack = tacker.vnfm.infra_drivers.openstack.openstack:OpenStack
tacker.tacker.mgmt.drivers = tacker.tacker.mgmt.drivers =

View File

@ -58,27 +58,6 @@ core_opts = [
"means no limit")), "means no limit")),
cfg.StrOpt('host', default=utils.get_hostname(), cfg.StrOpt('host', default=utils.get_hostname(),
help=_("The hostname Tacker is running on")), 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 = [ core_cli_opts = [

View File

@ -59,7 +59,7 @@ class VNFD(model_base.BASE, models_v1.HasId, models_v1.HasTenant,
# In future, single service VM may accomodate multiple services. # In future, single service VM may accomodate multiple services.
service_types = orm.relationship('ServiceType', backref='vnfd') 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)) infra_driver = sa.Column(sa.String(255))
# driver to communicate with service managment # 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): class VNFDAttribute(model_base.BASE, models_v1.HasId):
"""Represents attributes necessary for spinning up VM in (key, value) pair """Represents attributes necessary for spinning up VM in (key, value) pair
key value pair is adopted for being agnostic to actuall manager of VMs 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.
The interpretation is up to actual driver of hosting vnf. 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) description = sa.Column(sa.Text, nullable=True)
# sufficient information to uniquely identify hosting vnf. # 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) instance_id = sa.Column(sa.String(64), nullable=True)
# For a management tool to talk to manage this hosting vnf. # 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): class VNFAttribute(model_base.BASE, models_v1.HasId):
"""Represents kwargs necessary for spinning up VM in (key, value) pair. """Represents kwargs necessary for spinning up VM in (key, value) pair.
key value pair is adopted for being agnostic to actuall manager of VMs 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.
The interpretation is up to actual driver of hosting vnf. The interpretation is up to actual driver of hosting vnf.
""" """

View File

@ -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

View File

@ -114,7 +114,7 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
""" """
OPTS = [ OPTS = [
cfg.ListOpt( cfg.ListOpt(
'infra_driver', default=['nova', 'heat', 'noop', 'openstack'], 'infra_driver', default=['heat', 'noop', 'openstack'],
help=_('Hosting vnf drivers tacker plugin will use')), help=_('Hosting vnf drivers tacker plugin will use')),
] ]
cfg.CONF.register_opts(OPTS, 'tacker') cfg.CONF.register_opts(OPTS, 'tacker')