Remove Service instance, context resources
These resources are out of the scope of tacker
(cherry picked from commit 5c7d475eb3
)
Change-Id: Ib585e44e629908ca97c5ab67cdb8ed4375b61fe7
Closes-bug: 1519968
This commit is contained in:
parent
3d3360c0f0
commit
1790718612
@ -415,21 +415,3 @@ auth_plugin = password
|
|||||||
heat_uri = http://localhost:8004/v1
|
heat_uri = http://localhost:8004/v1
|
||||||
stack_retries = 5
|
stack_retries = 5
|
||||||
stack_retry_wait = 3
|
stack_retry_wait = 3
|
||||||
|
|
||||||
[servicevm_agent]
|
|
||||||
# VM agent requires that an interface driver be set. Choose the one that best
|
|
||||||
# matches your plugin.
|
|
||||||
# interface_driver =
|
|
||||||
|
|
||||||
# Example of interface_driver option for OVS based plugins (OVS, Ryu, NEC)
|
|
||||||
# that supports L3 agent
|
|
||||||
# interface_driver = tacker.agent.linux.interface.OVSInterfaceDriver
|
|
||||||
|
|
||||||
# Use veth for an OVS interface or not.
|
|
||||||
# Support kernels with limited namespace support
|
|
||||||
# (e.g. RHEL 6.5) so long as ovs_use_veth is set to True.
|
|
||||||
# ovs_use_veth = False
|
|
||||||
|
|
||||||
# Allow overlapping IP (Must have kernel build with CONFIG_NET_NS=y and
|
|
||||||
# iproute2 package that supports namespaces).
|
|
||||||
# use_namespaces = True
|
|
||||||
|
@ -0,0 +1,115 @@
|
|||||||
|
# Copyright 2015 OpenStack Foundation
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""remove service related
|
||||||
|
|
||||||
|
Revision ID: 2774a42c7163
|
||||||
|
Revises: 12a57080b278
|
||||||
|
Create Date: 2015-11-26 15:47:51.161749
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '2774a42c7163'
|
||||||
|
down_revision = '12a57080b278'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(active_plugins=None, options=None):
|
||||||
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_table('servicecontexts')
|
||||||
|
op.drop_table('deviceservicecontexts')
|
||||||
|
op.drop_table('servicedevicebindings')
|
||||||
|
op.drop_table('serviceinstances')
|
||||||
|
### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade(active_plugins=None, options=None):
|
||||||
|
### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table(
|
||||||
|
'deviceservicecontexts',
|
||||||
|
sa.Column('id', mysql.VARCHAR(length=36), nullable=False),
|
||||||
|
sa.Column('device_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('network_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('subnet_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('port_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('router_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('role', mysql.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('index', mysql.INTEGER(display_width=11),
|
||||||
|
autoincrement=False, nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['device_id'], [u'devices.id'],
|
||||||
|
name=u'deviceservicecontexts_ibfk_1'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
mysql_default_charset=u'utf8',
|
||||||
|
mysql_engine=u'InnoDB'
|
||||||
|
)
|
||||||
|
|
||||||
|
op.create_table(
|
||||||
|
'serviceinstances',
|
||||||
|
sa.Column('tenant_id', mysql.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('id', mysql.VARCHAR(length=36), nullable=False),
|
||||||
|
sa.Column('name', mysql.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('service_type_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('service_table_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('managed_by_user', mysql.TINYINT(display_width=1),
|
||||||
|
autoincrement=False, nullable=True),
|
||||||
|
sa.Column('mgmt_driver', mysql.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('mgmt_url', mysql.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('status', mysql.VARCHAR(length=255), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['service_type_id'], [u'servicetypes.id'],
|
||||||
|
name=u'serviceinstances_ibfk_1'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
mysql_default_charset=u'utf8',
|
||||||
|
mysql_engine=u'InnoDB'
|
||||||
|
)
|
||||||
|
|
||||||
|
op.create_table(
|
||||||
|
'servicedevicebindings',
|
||||||
|
sa.Column('service_instance_id', mysql.VARCHAR(length=36),
|
||||||
|
nullable=False),
|
||||||
|
sa.Column('device_id', mysql.VARCHAR(length=36), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['device_id'], [u'devices.id'],
|
||||||
|
name=u'servicedevicebindings_ibfk_1'),
|
||||||
|
sa.ForeignKeyConstraint(['service_instance_id'],
|
||||||
|
[u'serviceinstances.id'],
|
||||||
|
name=u'servicedevicebindings_ibfk_2'),
|
||||||
|
sa.PrimaryKeyConstraint('service_instance_id', 'device_id'),
|
||||||
|
mysql_default_charset=u'utf8',
|
||||||
|
mysql_engine=u'InnoDB'
|
||||||
|
)
|
||||||
|
|
||||||
|
op.create_table(
|
||||||
|
'servicecontexts',
|
||||||
|
sa.Column('id', mysql.VARCHAR(length=36), nullable=False),
|
||||||
|
sa.Column('service_instance_id', mysql.VARCHAR(length=36),
|
||||||
|
nullable=True),
|
||||||
|
sa.Column('network_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('subnet_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('port_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('router_id', mysql.VARCHAR(length=36), nullable=True),
|
||||||
|
sa.Column('role', mysql.VARCHAR(length=255), nullable=True),
|
||||||
|
sa.Column('index', mysql.INTEGER(display_width=11),
|
||||||
|
autoincrement=False, nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['service_instance_id'],
|
||||||
|
[u'serviceinstances.id'],
|
||||||
|
name=u'servicecontexts_ibfk_1'),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
mysql_default_charset=u'utf8',
|
||||||
|
mysql_engine=u'InnoDB'
|
||||||
|
)
|
||||||
|
### end Alembic commands ###
|
@ -1 +1 @@
|
|||||||
12a57080b278
|
2774a42c7163
|
@ -118,9 +118,6 @@ class Device(model_base.BASE, models_v1.HasTenant):
|
|||||||
mgmt_url = sa.Column(sa.String(255), nullable=True)
|
mgmt_url = sa.Column(sa.String(255), nullable=True)
|
||||||
attributes = orm.relationship("DeviceAttribute", backref="device")
|
attributes = orm.relationship("DeviceAttribute", backref="device")
|
||||||
|
|
||||||
service_context = orm.relationship('DeviceServiceContext')
|
|
||||||
services = orm.relationship('ServiceDeviceBinding', backref='device')
|
|
||||||
|
|
||||||
status = sa.Column(sa.String(255), nullable=False)
|
status = sa.Column(sa.String(255), nullable=False)
|
||||||
|
|
||||||
|
|
||||||
@ -138,133 +135,6 @@ class DeviceAttribute(model_base.BASE, models_v1.HasId):
|
|||||||
value = sa.Column(sa.String(4096), nullable=True)
|
value = sa.Column(sa.String(4096), nullable=True)
|
||||||
|
|
||||||
|
|
||||||
# TODO(yamahata): This is tentative.
|
|
||||||
# In the future, this will be replaced with db models of
|
|
||||||
# service insertion/chain.
|
|
||||||
# Since such models are under discussion/development as of
|
|
||||||
# this time, this models is just for lbaas driver of hosting
|
|
||||||
# device
|
|
||||||
# This corresponds to the instantiation of DP_IF_Types
|
|
||||||
class DeviceServiceContext(model_base.BASE, models_v1.HasId):
|
|
||||||
"""Represents service context of Device for scheduler.
|
|
||||||
This represents service insertion/chainging of a given device.
|
|
||||||
"""
|
|
||||||
device_id = sa.Column(sa.String(36), sa.ForeignKey('devices.id'))
|
|
||||||
network_id = sa.Column(sa.String(36), nullable=True)
|
|
||||||
subnet_id = sa.Column(sa.String(36), nullable=True)
|
|
||||||
port_id = sa.Column(sa.String(36), nullable=True)
|
|
||||||
router_id = sa.Column(sa.String(36), nullable=True)
|
|
||||||
|
|
||||||
role = sa.Column(sa.String(255), nullable=True)
|
|
||||||
# disambiguation between same roles
|
|
||||||
index = sa.Column(sa.Integer, nullable=True)
|
|
||||||
|
|
||||||
|
|
||||||
# this table corresponds to ServiceInstance of the original spec
|
|
||||||
class ServiceInstance(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
|
|
||||||
"""Represents logical service instance
|
|
||||||
This table is only to tell what logical service instances exists.
|
|
||||||
There will be service specific tables for each service types which holds
|
|
||||||
actuall parameters necessary for specific service type.
|
|
||||||
For example, tables for "Routers", "LBaaS", "FW", tables. which table
|
|
||||||
is implicitly determined by service_type_id.
|
|
||||||
"""
|
|
||||||
name = sa.Column(sa.String(255), nullable=True)
|
|
||||||
service_type_id = sa.Column(sa.String(36),
|
|
||||||
sa.ForeignKey('servicetypes.id'))
|
|
||||||
service_type = orm.relationship('ServiceType')
|
|
||||||
# points to row in service specific table if any.
|
|
||||||
service_table_id = sa.Column(sa.String(36), nullable=True)
|
|
||||||
|
|
||||||
# True: This service is managed by user so that user is able to
|
|
||||||
# change its configurations
|
|
||||||
# False: This service is manged by other tacker service like lbaas
|
|
||||||
# so that user can't change the configuration directly via
|
|
||||||
# servicevm API, but via API for the service.
|
|
||||||
managed_by_user = sa.Column(sa.Boolean(), default=False)
|
|
||||||
|
|
||||||
# mgmt driver to communicate with logical service instance in
|
|
||||||
# hosting device.
|
|
||||||
# e.g. noop, OpenStack MGMT, OpenStack notification, netconf, snmp,
|
|
||||||
# ssh, etc...
|
|
||||||
mgmt_driver = sa.Column(sa.String(255))
|
|
||||||
|
|
||||||
# For a management tool to talk to manage this service instance.
|
|
||||||
# opaque string. mgmt_driver interprets it.
|
|
||||||
mgmt_url = sa.Column(sa.String(255), nullable=True)
|
|
||||||
|
|
||||||
service_context = orm.relationship('ServiceContext')
|
|
||||||
devices = orm.relationship('ServiceDeviceBinding')
|
|
||||||
|
|
||||||
status = sa.Column(sa.String(255), nullable=False)
|
|
||||||
|
|
||||||
# TODO(yamahata): re-think the necessity of following columns
|
|
||||||
# They are all commented out for minimalism for now.
|
|
||||||
# They will be added when it is found really necessary.
|
|
||||||
#
|
|
||||||
# multi_tenant = sa.Column(sa.Boolean())
|
|
||||||
# state = sa.Column(sa.Enum('UP', 'DOWN',
|
|
||||||
# name='service_instance_state'))
|
|
||||||
# For a logical service instance in hosting device to recieve
|
|
||||||
# requests from management tools.
|
|
||||||
# opaque string. mgmt_driver interprets it.
|
|
||||||
# e.g. the name of the interface inside the VM + protocol
|
|
||||||
# vm_mgmt_if = sa.Column(sa.String(255), default=None, nullable=True)
|
|
||||||
# networks =
|
|
||||||
# obj_store =
|
|
||||||
# cost_factor =
|
|
||||||
|
|
||||||
|
|
||||||
# TODO(yamahata): This is tentative.
|
|
||||||
# In the future, this will be replaced with db models of
|
|
||||||
# service insertion/chain.
|
|
||||||
# Since such models are under discussion/development as of
|
|
||||||
# this time, this models is just for lbaas driver of hosting
|
|
||||||
# device
|
|
||||||
# This corresponds to networks of Logical Service Instance in the origianl spec
|
|
||||||
class ServiceContext(model_base.BASE, models_v1.HasId):
|
|
||||||
"""Represents service context of logical service instance.
|
|
||||||
This represents service insertion/chainging of a given device.
|
|
||||||
This is equal or subset of DeviceServiceContext of the
|
|
||||||
corresponding Device.
|
|
||||||
"""
|
|
||||||
service_instance_id = sa.Column(sa.String(36),
|
|
||||||
sa.ForeignKey('serviceinstances.id'))
|
|
||||||
network_id = sa.Column(sa.String(36), nullable=True)
|
|
||||||
subnet_id = sa.Column(sa.String(36), nullable=True)
|
|
||||||
port_id = sa.Column(sa.String(36), nullable=True)
|
|
||||||
router_id = sa.Column(sa.String(36), nullable=True)
|
|
||||||
|
|
||||||
role = sa.Column(sa.String(255), nullable=True)
|
|
||||||
index = sa.Column(sa.Integer, nullable=True) # disambiguation
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceDeviceBinding(model_base.BASE):
|
|
||||||
"""Represents binding with Device and LogicalResource.
|
|
||||||
Since Device can accomodate multiple services, it's many-to-one
|
|
||||||
relationship.
|
|
||||||
"""
|
|
||||||
service_instance_id = sa.Column(
|
|
||||||
sa.String(36), sa.ForeignKey('serviceinstances.id'), primary_key=True)
|
|
||||||
device_id = sa.Column(sa.String(36), sa.ForeignKey('devices.id'),
|
|
||||||
primary_key=True)
|
|
||||||
|
|
||||||
|
|
||||||
###########################################################################
|
|
||||||
# actual code to manage those tables
|
|
||||||
class ServiceContextEntry(dict):
|
|
||||||
@classmethod
|
|
||||||
def create(cls, network_id, subnet_id, port_id, router_id, role, index):
|
|
||||||
return cls({
|
|
||||||
'network_id': network_id,
|
|
||||||
'subnet_id': subnet_id,
|
|
||||||
'port_id': port_id,
|
|
||||||
'router_id': router_id,
|
|
||||||
'role': role,
|
|
||||||
'index': index,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -287,8 +157,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
raise vnfm.DeviceTemplateNotFound(device_tempalte_id=id)
|
raise vnfm.DeviceTemplateNotFound(device_tempalte_id=id)
|
||||||
elif issubclass(model, ServiceType):
|
elif issubclass(model, ServiceType):
|
||||||
raise vnfm.ServiceTypeNotFound(service_type_id=id)
|
raise vnfm.ServiceTypeNotFound(service_type_id=id)
|
||||||
elif issubclass(model, ServiceInstance):
|
|
||||||
raise vnfm.ServiceInstanceNotFound(service_instance_id=id)
|
|
||||||
if issubclass(model, Device):
|
if issubclass(model, Device):
|
||||||
raise vnfm.DeviceNotFound(device_id=id)
|
raise vnfm.DeviceNotFound(device_id=id)
|
||||||
else:
|
else:
|
||||||
@ -313,57 +181,22 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
res.update((key, template[key]) for key in key_list)
|
res.update((key, template[key]) for key in key_list)
|
||||||
return self._fields(res, fields)
|
return self._fields(res, fields)
|
||||||
|
|
||||||
def _make_services_list(self, binding_db):
|
|
||||||
return [binding.service_instance_id for binding in binding_db]
|
|
||||||
|
|
||||||
def _make_dev_attrs_dict(self, dev_attrs_db):
|
def _make_dev_attrs_dict(self, dev_attrs_db):
|
||||||
return dict((arg.key, arg.value) for arg in dev_attrs_db)
|
return dict((arg.key, arg.value) for arg in dev_attrs_db)
|
||||||
|
|
||||||
def _make_device_service_context_dict(self, service_context):
|
|
||||||
key_list = ('id', 'network_id', 'subnet_id', 'port_id', 'router_id',
|
|
||||||
'role', 'index')
|
|
||||||
return [self._fields(dict((key, entry[key]) for key in key_list), None)
|
|
||||||
for entry in service_context]
|
|
||||||
|
|
||||||
def _make_device_dict(self, device_db, fields=None):
|
def _make_device_dict(self, device_db, fields=None):
|
||||||
LOG.debug(_('device_db %s'), device_db)
|
LOG.debug(_('device_db %s'), device_db)
|
||||||
LOG.debug(_('device_db attributes %s'), device_db.attributes)
|
LOG.debug(_('device_db attributes %s'), device_db.attributes)
|
||||||
res = {
|
res = {
|
||||||
'services':
|
|
||||||
self._make_services_list(getattr(device_db, 'services', [])),
|
|
||||||
'device_template':
|
'device_template':
|
||||||
self._make_template_dict(device_db.template),
|
self._make_template_dict(device_db.template),
|
||||||
'attributes': self._make_dev_attrs_dict(device_db.attributes),
|
'attributes': self._make_dev_attrs_dict(device_db.attributes),
|
||||||
'service_context':
|
|
||||||
self._make_device_service_context_dict(device_db.service_context),
|
|
||||||
}
|
}
|
||||||
key_list = ('id', 'tenant_id', 'name', 'description', 'instance_id',
|
key_list = ('id', 'tenant_id', 'name', 'description', 'instance_id',
|
||||||
'template_id', 'status', 'mgmt_url')
|
'template_id', 'status', 'mgmt_url')
|
||||||
res.update((key, device_db[key]) for key in key_list)
|
res.update((key, device_db[key]) for key in key_list)
|
||||||
return self._fields(res, fields)
|
return self._fields(res, fields)
|
||||||
|
|
||||||
def _make_service_context_dict(self, service_context):
|
|
||||||
key_list = ('id', 'network_id', 'subnet_id', 'port_id', 'router_id',
|
|
||||||
'role', 'index')
|
|
||||||
return [self._fields(dict((key, entry[key]) for key in key_list), None)
|
|
||||||
for entry in service_context]
|
|
||||||
|
|
||||||
def _make_service_device_list(self, devices):
|
|
||||||
return [binding.device_id for binding in devices]
|
|
||||||
|
|
||||||
def _make_service_instance_dict(self, instance_db, fields=None):
|
|
||||||
res = {
|
|
||||||
'service_context':
|
|
||||||
self._make_service_context_dict(instance_db.service_context),
|
|
||||||
'devices':
|
|
||||||
self._make_service_device_list(instance_db.devices)
|
|
||||||
}
|
|
||||||
key_list = ('id', 'tenant_id', 'name', 'service_type_id',
|
|
||||||
'service_table_id', 'mgmt_driver', 'mgmt_url',
|
|
||||||
'status')
|
|
||||||
res.update((key, instance_db[key]) for key in key_list)
|
|
||||||
return self._fields(res, fields)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _infra_driver_name(device_dict):
|
def _infra_driver_name(device_dict):
|
||||||
return device_dict['device_template']['infra_driver']
|
return device_dict['device_template']['infra_driver']
|
||||||
@ -376,9 +209,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
def _instance_id(device_dict):
|
def _instance_id(device_dict):
|
||||||
return device_dict['instance_id']
|
return device_dict['instance_id']
|
||||||
|
|
||||||
###########################################################################
|
|
||||||
# hosting device template
|
|
||||||
|
|
||||||
def create_device_template(self, context, device_template):
|
def create_device_template(self, context, device_template):
|
||||||
template = device_template['device_template']
|
template = device_template['device_template']
|
||||||
LOG.debug(_('template %s'), template)
|
LOG.debug(_('template %s'), template)
|
||||||
@ -464,8 +294,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
self._make_template_dict,
|
self._make_template_dict,
|
||||||
filters=filters, fields=fields)
|
filters=filters, fields=fields)
|
||||||
|
|
||||||
# called internally, not by REST API
|
|
||||||
# need enhancement?
|
|
||||||
def choose_device_template(self, context, service_type,
|
def choose_device_template(self, context, service_type,
|
||||||
required_attributes=None):
|
required_attributes=None):
|
||||||
required_attributes = required_attributes or []
|
required_attributes = required_attributes or []
|
||||||
@ -490,9 +318,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
if template_db:
|
if template_db:
|
||||||
return self._make_template_dict(template_db)
|
return self._make_template_dict(template_db)
|
||||||
|
|
||||||
###########################################################################
|
|
||||||
# hosting device
|
|
||||||
|
|
||||||
def _device_attribute_update_or_create(
|
def _device_attribute_update_or_create(
|
||||||
self, context, device_id, key, value):
|
self, context, device_id, key, value):
|
||||||
arg = (self._model_query(context, DeviceAttribute).
|
arg = (self._model_query(context, DeviceAttribute).
|
||||||
@ -515,7 +340,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
name = device.get('name')
|
name = device.get('name')
|
||||||
device_id = device.get('id') or str(uuid.uuid4())
|
device_id = device.get('id') or str(uuid.uuid4())
|
||||||
attributes = device.get('attributes', {})
|
attributes = device.get('attributes', {})
|
||||||
service_context = device.get('service_context', [])
|
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
template_db = self._get_resource(context, DeviceTemplate,
|
template_db = self._get_resource(context, DeviceTemplate,
|
||||||
template_id)
|
template_id)
|
||||||
@ -533,22 +357,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
key=key, value=value)
|
key=key, value=value)
|
||||||
context.session.add(arg)
|
context.session.add(arg)
|
||||||
|
|
||||||
LOG.debug(_('service_context %s'), service_context)
|
|
||||||
for sc_entry in service_context:
|
|
||||||
LOG.debug(_('sc_entry %s'), sc_entry)
|
|
||||||
network_id = sc_entry.get('network_id')
|
|
||||||
subnet_id = sc_entry.get('subnet_id')
|
|
||||||
port_id = sc_entry.get('port_id')
|
|
||||||
router_id = sc_entry.get('router_id')
|
|
||||||
role = sc_entry.get('role')
|
|
||||||
index = sc_entry.get('index')
|
|
||||||
network_binding = DeviceServiceContext(
|
|
||||||
id=str(uuid.uuid4()), device_id=device_id,
|
|
||||||
network_id=network_id, subnet_id=subnet_id,
|
|
||||||
port_id=port_id, router_id=router_id, role=role,
|
|
||||||
index=index)
|
|
||||||
context.session.add(network_binding)
|
|
||||||
|
|
||||||
return self._make_device_dict(device_db)
|
return self._make_device_dict(device_db)
|
||||||
|
|
||||||
# called internally, not by REST API
|
# called internally, not by REST API
|
||||||
@ -569,18 +377,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
self._device_attribute_update_or_create(context, device_id,
|
self._device_attribute_update_or_create(context, device_id,
|
||||||
key, value)
|
key, value)
|
||||||
|
|
||||||
for sc_entry in device_dict['service_context']:
|
|
||||||
# some member of service context is determined during
|
|
||||||
# creating hosting device.
|
|
||||||
(self._model_query(context, DeviceServiceContext).
|
|
||||||
filter(DeviceServiceContext.id == sc_entry['id']).
|
|
||||||
update({'network_id': sc_entry['network_id'],
|
|
||||||
'subnet_id': sc_entry['subnet_id'],
|
|
||||||
'port_id': sc_entry['port_id'],
|
|
||||||
'router_id': sc_entry['router_id'],
|
|
||||||
'role': sc_entry['role'],
|
|
||||||
'index': sc_entry['index']}))
|
|
||||||
|
|
||||||
def _create_device_status(self, context, device_id, new_status):
|
def _create_device_status(self, context, device_id, new_status):
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
(self._model_query(context, Device).
|
(self._model_query(context, Device).
|
||||||
@ -628,11 +424,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
|
|
||||||
def _delete_device_pre(self, context, device_id):
|
def _delete_device_pre(self, context, device_id):
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
# TODO(yamahata): race. keep others from inserting new binding
|
|
||||||
binding_db = (context.session.query(ServiceDeviceBinding).
|
|
||||||
filter_by(device_id=device_id).first())
|
|
||||||
if binding_db is not None:
|
|
||||||
raise vnfm.DeviceInUse(device_id=device_id)
|
|
||||||
device_db = self._get_device_db(
|
device_db = self._get_device_db(
|
||||||
context, device_id, _ACTIVE_UPDATE_ERROR_DEAD,
|
context, device_id, _ACTIVE_UPDATE_ERROR_DEAD,
|
||||||
constants.PENDING_DELETE)
|
constants.PENDING_DELETE)
|
||||||
@ -650,8 +441,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
else:
|
else:
|
||||||
(self._model_query(context, DeviceAttribute).
|
(self._model_query(context, DeviceAttribute).
|
||||||
filter(DeviceAttribute.device_id == device_id).delete())
|
filter(DeviceAttribute.device_id == device_id).delete())
|
||||||
(self._model_query(context, DeviceServiceContext).
|
|
||||||
filter(DeviceServiceContext.device_id == device_id).delete())
|
|
||||||
query.delete()
|
query.delete()
|
||||||
|
|
||||||
# reference implementation. needs to be overrided by subclass
|
# reference implementation. needs to be overrided by subclass
|
||||||
@ -749,187 +538,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
|
|||||||
update({'device_id': new_device_id}))
|
update({'device_id': new_device_id}))
|
||||||
context.session.delete(device_db)
|
context.session.delete(device_db)
|
||||||
|
|
||||||
###########################################################################
|
|
||||||
# logical service instance
|
|
||||||
|
|
||||||
# called internally, not by REST API
|
|
||||||
def _create_service_instance(self, context, device_id,
|
|
||||||
service_instance_param, managed_by_user):
|
|
||||||
"""
|
|
||||||
:param service_instance_param: dictionary to create
|
|
||||||
instance of ServiceInstance. The following keys are used.
|
|
||||||
name, service_type_id, service_table_id, mgmt_driver, mgmt_url
|
|
||||||
mgmt_driver, mgmt_url can be determined later.
|
|
||||||
"""
|
|
||||||
name = service_instance_param['name']
|
|
||||||
service_type_id = service_instance_param['service_type_id']
|
|
||||||
service_table_id = service_instance_param['service_table_id']
|
|
||||||
mgmt_driver = service_instance_param.get('mgmt_driver')
|
|
||||||
mgmt_url = service_instance_param.get('mgmt_url')
|
|
||||||
|
|
||||||
service_instance_id = str(uuid.uuid4())
|
|
||||||
LOG.debug('service_instance_id %s device_id %s',
|
|
||||||
service_instance_id, device_id)
|
|
||||||
with context.session.begin(subtransactions=True):
|
|
||||||
# TODO(yamahata): race. prevent modifying/deleting service_type
|
|
||||||
# with_lockmode("update")
|
|
||||||
device_db = self._get_resource(context, Device, device_id)
|
|
||||||
device_dict = self._make_device_dict(device_db)
|
|
||||||
tenant_id = self._get_tenant_id_for_create(context, device_dict)
|
|
||||||
instance_db = ServiceInstance(
|
|
||||||
id=service_instance_id,
|
|
||||||
tenant_id=tenant_id,
|
|
||||||
name=name,
|
|
||||||
service_type_id=service_type_id,
|
|
||||||
service_table_id=service_table_id,
|
|
||||||
managed_by_user=managed_by_user,
|
|
||||||
status=constants.PENDING_CREATE,
|
|
||||||
mgmt_driver=mgmt_driver,
|
|
||||||
mgmt_url=mgmt_url)
|
|
||||||
context.session.add(instance_db)
|
|
||||||
context.session.flush()
|
|
||||||
|
|
||||||
binding_db = ServiceDeviceBinding(
|
|
||||||
service_instance_id=service_instance_id, device_id=device_id)
|
|
||||||
context.session.add(binding_db)
|
|
||||||
|
|
||||||
return self._make_service_instance_dict(instance_db)
|
|
||||||
|
|
||||||
# reference implementation. must be overriden by subclass
|
|
||||||
def create_service_instance(self, context, service_instance):
|
|
||||||
self._create_service_instance(
|
|
||||||
context, service_instance['service_instance'], True)
|
|
||||||
|
|
||||||
def _update_service_instance_mgmt(self, context, service_instance_id,
|
|
||||||
mgmt_driver, mgmt_url):
|
|
||||||
with context.session.begin(subtransactions=True):
|
|
||||||
(self._model_query(context, ServiceInstance).
|
|
||||||
filter(ServiceInstance.id == service_instance_id).
|
|
||||||
filter(ServiceInstance.status == constants.PENDING_CREATE).
|
|
||||||
one().
|
|
||||||
update({'mgmt_driver': mgmt_driver,
|
|
||||||
'mgmt_url': mgmt_url}))
|
|
||||||
|
|
||||||
def _update_service_instance_pre(self, context, service_instance_id,
|
|
||||||
service_instance):
|
|
||||||
with context.session.begin(subtransactions=True):
|
|
||||||
instance_db = (
|
|
||||||
self._model_query(context, ServiceInstance).
|
|
||||||
filter(ServiceInstance.id == service_instance_id).
|
|
||||||
filter(Device.status == constants.ACTIVE).
|
|
||||||
with_lockmode('update').one())
|
|
||||||
instance_db.update(service_instance)
|
|
||||||
instance_db.update({'status': constants.PENDING_UPDATE})
|
|
||||||
return self._make_service_instance_dict(instance_db)
|
|
||||||
|
|
||||||
def _update_service_instance_post(self, context, service_instance_id,
|
|
||||||
status):
|
|
||||||
with context.session.begin(subtransactions=True):
|
|
||||||
(self._model_query(context, ServiceInstance).
|
|
||||||
filter(ServiceInstance.id == service_instance_id).
|
|
||||||
filter(ServiceInstance.status.in_(
|
|
||||||
[constants.PENDING_CREATE, constants.PENDING_UPDATE])).one().
|
|
||||||
update({'status': status}))
|
|
||||||
|
|
||||||
# reference implementation
|
|
||||||
def update_service_instance(self, context, service_instance_id,
|
|
||||||
service_instance):
|
|
||||||
service_instance_dict = self._update_service_instance_pre(
|
|
||||||
context, service_instance_id, service_instance)
|
|
||||||
self._update_service_instance_post(
|
|
||||||
context, service_instance_id, service_instance, constants.ACTIVE)
|
|
||||||
return service_instance_dict
|
|
||||||
|
|
||||||
def _delete_service_instance_pre(self, context, service_instance_id,
|
|
||||||
managed_by_user):
|
|
||||||
with context.session.begin(subtransactions=True):
|
|
||||||
service_instance = (
|
|
||||||
self._model_query(context, ServiceInstance).
|
|
||||||
filter(ServiceInstance.id == service_instance_id).
|
|
||||||
filter(ServiceInstance.status == constants.ACTIVE).
|
|
||||||
with_lockmode('update').one())
|
|
||||||
|
|
||||||
if service_instance.managed_by_user != managed_by_user:
|
|
||||||
raise vnfm.ServiceInstanceNotManagedByUser(
|
|
||||||
service_instance_id=service_instance_id)
|
|
||||||
|
|
||||||
service_instance.status = constants.PENDING_DELETE
|
|
||||||
|
|
||||||
binding_db = (
|
|
||||||
self._model_query(context, ServiceDeviceBinding).
|
|
||||||
filter(ServiceDeviceBinding.service_instance_id ==
|
|
||||||
service_instance_id).
|
|
||||||
all())
|
|
||||||
assert binding_db
|
|
||||||
# check only. _post method will delete it.
|
|
||||||
if len(binding_db) > 1:
|
|
||||||
raise vnfm.ServiceInstanceInUse(
|
|
||||||
service_instance_id=service_instance_id)
|
|
||||||
|
|
||||||
def _delete_service_instance_post(self, context, service_instance_id):
|
|
||||||
with context.session.begin(subtransactions=True):
|
|
||||||
binding_db = (
|
|
||||||
self._model_query(context, ServiceDeviceBinding).
|
|
||||||
filter(ServiceDeviceBinding. service_instance_id ==
|
|
||||||
service_instance_id).
|
|
||||||
all())
|
|
||||||
assert binding_db
|
|
||||||
assert len(binding_db) == 1
|
|
||||||
context.session.delete(binding_db[0])
|
|
||||||
|
|
||||||
(self._model_query(context, ServiceInstance).
|
|
||||||
filter(ServiceInstance.id == service_instance_id).
|
|
||||||
filter(ServiceInstance.status == constants.PENDING_DELETE).
|
|
||||||
delete())
|
|
||||||
|
|
||||||
# reference implementation. needs to be overriden by subclass
|
|
||||||
def _delete_service_instance(self, context, service_instance_id,
|
|
||||||
managed_by_user):
|
|
||||||
self._delete_service_instance_pre(context, service_instance_id,
|
|
||||||
managed_by_user)
|
|
||||||
self._delete_service_instance_post(context, service_instance_id)
|
|
||||||
|
|
||||||
# reference implementation. needs to be overriden by subclass
|
|
||||||
def delete_service_instance(self, context, service_instance_id):
|
|
||||||
self._delete_service_instance(context, service_instance_id, True)
|
|
||||||
|
|
||||||
def get_by_service_table_id(self, context, service_table_id):
|
|
||||||
with context.session.begin(subtransactions=True):
|
|
||||||
instance_db = (self._model_query(context, ServiceInstance).
|
|
||||||
filter(ServiceInstance.service_table_id ==
|
|
||||||
service_table_id).one())
|
|
||||||
device_db = (
|
|
||||||
self._model_query(context, Device).
|
|
||||||
filter(sa.exists().where(sa.and_(
|
|
||||||
ServiceDeviceBinding.device_id == Device.id,
|
|
||||||
ServiceDeviceBinding.service_instance_id ==
|
|
||||||
instance_db.id))).one())
|
|
||||||
return (self._make_device_dict(device_db),
|
|
||||||
self._make_service_instance_dict(instance_db))
|
|
||||||
|
|
||||||
def get_by_service_instance_id(self, context, service_instance_id):
|
|
||||||
with context.session.begin(subtransactions=True):
|
|
||||||
instance_db = self._get_resource(context, ServiceInstance,
|
|
||||||
service_instance_id)
|
|
||||||
device_db = (
|
|
||||||
self._model_query(context, Device).
|
|
||||||
filter(sa.exists().where(sa.and_(
|
|
||||||
ServiceDeviceBinding.device_id == Device.id,
|
|
||||||
ServiceDeviceBinding.service_instance_id ==
|
|
||||||
instance_db.id))).one())
|
|
||||||
return (self._make_device_dict(device_db),
|
|
||||||
self._make_service_instance_dict(instance_db))
|
|
||||||
|
|
||||||
def get_service_instance(self, context, service_instance_id, fields=None):
|
|
||||||
instance_db = self._get_resource(context, ServiceInstance,
|
|
||||||
service_instance_id)
|
|
||||||
return self._make_service_instance_dict(instance_db, fields)
|
|
||||||
|
|
||||||
def get_service_instances(self, context, filters=None, fields=None):
|
|
||||||
return self._get_collection(
|
|
||||||
context, ServiceInstance, self._make_service_instance_dict,
|
|
||||||
filters=filters, fields=fields)
|
|
||||||
|
|
||||||
def get_vnfs(self, context, filters=None, fields=None):
|
def get_vnfs(self, context, filters=None, fields=None):
|
||||||
return self.get_devices(context, filters, fields)
|
return self.get_devices(context, filters, fields)
|
||||||
|
|
||||||
|
@ -77,19 +77,6 @@ class DeviceNotFound(exceptions.NotFound):
|
|||||||
message = _('device %(device_id)s could not be found')
|
message = _('device %(device_id)s could not be found')
|
||||||
|
|
||||||
|
|
||||||
class ServiceInstanceNotManagedByUser(exceptions.InUse):
|
|
||||||
message = _('service instance %(service_instance_id)s is '
|
|
||||||
'managed by other service')
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceInstanceInUse(exceptions.InUse):
|
|
||||||
message = _('service instance %(service_instance_id)s is still in use')
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceInstanceNotFound(exceptions.NotFound):
|
|
||||||
message = _('service instance %(service_instance_id)s could not be found')
|
|
||||||
|
|
||||||
|
|
||||||
class ParamYAMLNotWellFormed(exceptions.InvalidInput):
|
class ParamYAMLNotWellFormed(exceptions.InvalidInput):
|
||||||
message = _("Parameter YAML not well formed - %(error_msg_details)s")
|
message = _("Parameter YAML not well formed - %(error_msg_details)s")
|
||||||
|
|
||||||
@ -135,30 +122,8 @@ def _validate_service_type_list(data, valid_values=None):
|
|||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
||||||
def _validate_service_context_list(data, valid_values=None):
|
|
||||||
if not isinstance(data, list):
|
|
||||||
msg = _("invalid data format for service context list: '%s'") % data
|
|
||||||
LOG.debug(msg)
|
|
||||||
return msg
|
|
||||||
|
|
||||||
key_specs = {
|
|
||||||
'network_id': {'type:uuid': None},
|
|
||||||
'subnet_id': {'type:uuid': None},
|
|
||||||
'port_id': {'type:uuid': None},
|
|
||||||
'router_id': {'type:uuid': None},
|
|
||||||
'role': {'type:string': None},
|
|
||||||
'index': {'type:non_negative': None,
|
|
||||||
'convert_to': attr.convert_to_int},
|
|
||||||
}
|
|
||||||
for sc_entry in data:
|
|
||||||
msg = attr._validate_dict_or_empty(sc_entry, key_specs=key_specs)
|
|
||||||
if msg:
|
|
||||||
LOG.debug(msg)
|
|
||||||
return msg
|
|
||||||
|
|
||||||
|
|
||||||
attr.validators['type:service_type_list'] = _validate_service_type_list
|
attr.validators['type:service_type_list'] = _validate_service_type_list
|
||||||
attr.validators['type:service_context_list'] = _validate_service_context_list
|
|
||||||
|
|
||||||
RESOURCE_ATTRIBUTE_MAP = {
|
RESOURCE_ATTRIBUTE_MAP = {
|
||||||
|
|
||||||
@ -277,13 +242,6 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||||||
'is_visible': True,
|
'is_visible': True,
|
||||||
'default': {},
|
'default': {},
|
||||||
},
|
},
|
||||||
'service_contexts': {
|
|
||||||
'allow_post': True,
|
|
||||||
'allow_put': False,
|
|
||||||
'validate': {'type:service_context_list': None},
|
|
||||||
'is_visible': True,
|
|
||||||
'default': [],
|
|
||||||
},
|
|
||||||
'status': {
|
'status': {
|
||||||
'allow_post': False,
|
'allow_post': False,
|
||||||
'allow_put': False,
|
'allow_put': False,
|
||||||
@ -449,7 +407,6 @@ class Vnfm(extensions.ExtensionDescriptor):
|
|||||||
plural_mappings = resource_helper.build_plural_mappings(
|
plural_mappings = resource_helper.build_plural_mappings(
|
||||||
special_mappings, RESOURCE_ATTRIBUTE_MAP)
|
special_mappings, RESOURCE_ATTRIBUTE_MAP)
|
||||||
plural_mappings['service_types'] = 'service_type'
|
plural_mappings['service_types'] = 'service_type'
|
||||||
plural_mappings['service_contexts'] = 'service_context'
|
|
||||||
attr.PLURALS.update(plural_mappings)
|
attr.PLURALS.update(plural_mappings)
|
||||||
return resource_helper.build_resource_info(
|
return resource_helper.build_resource_info(
|
||||||
plural_mappings, RESOURCE_ATTRIBUTE_MAP, constants.VNFM,
|
plural_mappings, RESOURCE_ATTRIBUTE_MAP, constants.VNFM,
|
||||||
|
@ -53,7 +53,7 @@ def get_dummy_vnf_obj():
|
|||||||
return {'vnf': {'description': 'dummy_vnf_description',
|
return {'vnf': {'description': 'dummy_vnf_description',
|
||||||
'vnfd_id': u'eb094833-995e-49f0-a047-dfb56aaf7c4e',
|
'vnfd_id': u'eb094833-995e-49f0-a047-dfb56aaf7c4e',
|
||||||
'tenant_id': u'ad7ebc56538745a08ef7c5e97f8bd437',
|
'tenant_id': u'ad7ebc56538745a08ef7c5e97f8bd437',
|
||||||
'name': 'dummy_vnf', 'service_contexts': [],
|
'name': 'dummy_vnf',
|
||||||
'attributes': {}}}
|
'attributes': {}}}
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,43 +87,6 @@ class DeviceMGMTAbstractDriver(extensions.PluginInterface):
|
|||||||
def mgmt_call(self, plugin, context, device, kwargs):
|
def mgmt_call(self, plugin, context, device, kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def mgmt_service_driver(self, plugin, context, device, service_instance):
|
|
||||||
# use same mgmt driver to communicate with service
|
|
||||||
return self.get_name()
|
|
||||||
|
|
||||||
def mgmt_service_create_pre(self, plugin, context, device,
|
|
||||||
service_instance):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def mgmt_service_create_post(self, plugin, context, device,
|
|
||||||
service_instance):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def mgmt_service_update_pre(self, plugin, context, device,
|
|
||||||
service_instance):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def mgmt_service_update_post(self, plugin, context, device,
|
|
||||||
service_instance):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def mgmt_service_delete_pre(self, plugin, context, device,
|
|
||||||
service_instance):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def mgmt_service_delete_post(self, plugin, context, device,
|
|
||||||
service_instance):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def mgmt_service_address(self, plugin, context, device, service_instance):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def mgmt_service_call(self, plugin, context, device,
|
|
||||||
service_instance, kwargs):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceMGMTByNetwork(DeviceMGMTAbstractDriver):
|
class DeviceMGMTByNetwork(DeviceMGMTAbstractDriver):
|
||||||
def mgmt_url(self, plugin, context, device):
|
def mgmt_url(self, plugin, context, device):
|
||||||
@ -140,19 +103,3 @@ class DeviceMGMTByNetwork(DeviceMGMTAbstractDriver):
|
|||||||
mgmt_url['port_id'] = port['id']
|
mgmt_url['port_id'] = port['id']
|
||||||
mgmt_url['mac_address'] = port['mac_address']
|
mgmt_url['mac_address'] = port['mac_address']
|
||||||
return jsonutils.dumps(mgmt_url)
|
return jsonutils.dumps(mgmt_url)
|
||||||
|
|
||||||
def mgmt_service_address(self, plugin, context, device, service_instance):
|
|
||||||
mgmt_entries = [sc_entry for sc_entry
|
|
||||||
in service_instance.service_context
|
|
||||||
if (sc_entry.role == constants.ROLE_MGMT and
|
|
||||||
sc_entry.port_id)]
|
|
||||||
if not mgmt_entries:
|
|
||||||
return
|
|
||||||
port = plugin._core_plugin.get_port(context, mgmt_entries[0].port_id)
|
|
||||||
if not port:
|
|
||||||
return
|
|
||||||
mgmt_url = port['fixed_ips'][0] # subnet_id and ip_address
|
|
||||||
mgmt_url['network_id'] = port['network_id']
|
|
||||||
mgmt_url['port_id'] = port['id']
|
|
||||||
mgmt_url['mac_address'] = port['mac_address']
|
|
||||||
return jsonutils.dumps(mgmt_url)
|
|
||||||
|
@ -44,14 +44,3 @@ class DeviceMgmtNoop(abstract_driver.DeviceMGMTAbstractDriver):
|
|||||||
def mgmt_call(self, plugin, context, device, kwargs):
|
def mgmt_call(self, plugin, context, device, kwargs):
|
||||||
LOG.debug(_('mgmt_device_call %(device)s %(kwargs)s'),
|
LOG.debug(_('mgmt_device_call %(device)s %(kwargs)s'),
|
||||||
{'device': device, 'kwargs': kwargs})
|
{'device': device, 'kwargs': kwargs})
|
||||||
|
|
||||||
def mgmt_service_address(self, plugin, context,
|
|
||||||
device, service_instance):
|
|
||||||
LOG.debug(_('mgmt_service_address %(device)s %(service_instance)s'),
|
|
||||||
{'device': device, 'service_instance': service_instance})
|
|
||||||
return 'noop-mgmt-service-address'
|
|
||||||
|
|
||||||
def mgmt_service_call(self, plugin, context, device,
|
|
||||||
service_instance, kwargs):
|
|
||||||
LOG.debug(_('mgmt_service_call %(device)s %(service_instance)s'),
|
|
||||||
{'device': device, 'service_instance': service_instance})
|
|
||||||
|
@ -90,14 +90,3 @@ class DeviceMgmtOpenWRT(abstract_driver.DeviceMGMTAbstractDriver):
|
|||||||
vdu)
|
vdu)
|
||||||
continue
|
continue
|
||||||
self._config_service(mgmt_ip_address, key, conf_value)
|
self._config_service(mgmt_ip_address, key, conf_value)
|
||||||
|
|
||||||
def mgmt_service_address(self, plugin, context,
|
|
||||||
device, service_instance):
|
|
||||||
LOG.debug(_('mgmt_service_address %(device)s %(service_instance)s'),
|
|
||||||
{'device': device, 'service_instance': service_instance})
|
|
||||||
return 'noop-mgmt-service-address'
|
|
||||||
|
|
||||||
def mgmt_service_call(self, plugin, context, device,
|
|
||||||
service_instance, kwargs):
|
|
||||||
LOG.debug(_('mgmt_service_call %(device)s %(service_instance)s'),
|
|
||||||
{'device': device, 'service_instance': service_instance})
|
|
||||||
|
@ -25,7 +25,6 @@ import eventlet
|
|||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from sqlalchemy.orm import exc as orm_exc
|
|
||||||
|
|
||||||
from tacker.api.v1 import attributes
|
from tacker.api.v1 import attributes
|
||||||
from tacker.common import driver_manager
|
from tacker.common import driver_manager
|
||||||
@ -100,59 +99,6 @@ class VNFMMgmtMixin(object):
|
|||||||
device_dict, plugin=self, context=context, device=device_dict,
|
device_dict, plugin=self, context=context, device=device_dict,
|
||||||
kwargs=kwargs)
|
kwargs=kwargs)
|
||||||
|
|
||||||
def mgmt_service_driver(self, context, device_dict, service_instance_dict):
|
|
||||||
return self._invoke(
|
|
||||||
device_dict, plugin=self, context=context, device=device_dict,
|
|
||||||
service_instance=service_instance_dict)
|
|
||||||
|
|
||||||
def mgmt_service_create_pre(self, context, device_dict,
|
|
||||||
service_instance_dict):
|
|
||||||
return self._invoke(
|
|
||||||
device_dict, plugin=self, context=context, device=device_dict,
|
|
||||||
service_instance=service_instance_dict)
|
|
||||||
|
|
||||||
def mgmt_service_create_post(self, context, device_dict,
|
|
||||||
service_instance_dict):
|
|
||||||
return self._invoke(
|
|
||||||
device_dict, plugin=self, context=context, device=device_dict,
|
|
||||||
service_instance=service_instance_dict)
|
|
||||||
|
|
||||||
def mgmt_service_update_pre(self, context, device_dict,
|
|
||||||
service_instance_dict):
|
|
||||||
return self._invoke(
|
|
||||||
device_dict, plugin=self, context=context, device=device_dict,
|
|
||||||
service_instance=service_instance_dict)
|
|
||||||
|
|
||||||
def mgmt_service_update_post(self, context, device_dict,
|
|
||||||
service_instance_dict):
|
|
||||||
return self._invoke(
|
|
||||||
device_dict, plugin=self, context=context, device=device_dict,
|
|
||||||
service_instance=service_instance_dict)
|
|
||||||
|
|
||||||
def mgmt_service_delete_pre(self, context, device_dict,
|
|
||||||
service_instance_dict):
|
|
||||||
return self._invoke(
|
|
||||||
device_dict, plugin=self, context=context, device=device_dict,
|
|
||||||
service_instance=service_instance_dict)
|
|
||||||
|
|
||||||
def mgmt_service_delete_post(self, context, device_dict,
|
|
||||||
service_instance_dict):
|
|
||||||
return self._invoke(
|
|
||||||
device_dict, plugin=self, context=context, device=device_dict,
|
|
||||||
service_instance=service_instance_dict)
|
|
||||||
|
|
||||||
def mgmt_service_address(self, context, device_dict,
|
|
||||||
service_instance_dict):
|
|
||||||
return self._invoke(
|
|
||||||
device_dict, plugin=self, context=context, device=device_dict,
|
|
||||||
service_instance=service_instance_dict)
|
|
||||||
|
|
||||||
def mgmt_service_call(self, context, device_dict, service_instance_dict,
|
|
||||||
kwargs):
|
|
||||||
return self._invoke(
|
|
||||||
device_dict, plugin=self, context=context, device=device_dict,
|
|
||||||
service_instance=service_instance_dict, kwargs=kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class VNFMPlugin(vm_db.VNFMPluginDb, VNFMMgmtMixin):
|
class VNFMPlugin(vm_db.VNFMPluginDb, VNFMMgmtMixin):
|
||||||
"""ServiceVMPlugin which supports ServiceVM framework
|
"""ServiceVMPlugin which supports ServiceVM framework
|
||||||
@ -410,254 +356,6 @@ class VNFMPlugin(vm_db.VNFMPluginDb, VNFMMgmtMixin):
|
|||||||
self._delete_device_post(context, device_id, None)
|
self._delete_device_post(context, device_id, None)
|
||||||
self.spawn_n(self._delete_device_wait, context, device_dict)
|
self.spawn_n(self._delete_device_wait, context, device_dict)
|
||||||
|
|
||||||
###########################################################################
|
|
||||||
# logical service instance
|
|
||||||
#
|
|
||||||
def _create_service_instance_mgmt(
|
|
||||||
self, context, device_dict, service_instance_dict):
|
|
||||||
kwargs = {
|
|
||||||
mgmt_constants.KEY_ACTION: mgmt_constants.ACTION_CREATE_SERVICE,
|
|
||||||
mgmt_constants.KEY_KWARGS: {
|
|
||||||
'device': device_dict,
|
|
||||||
'service_instance': service_instance_dict,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
self.mgmt_call(context, device_dict, kwargs)
|
|
||||||
|
|
||||||
mgmt_driver = self.mgmt_service_driver(
|
|
||||||
context, device_dict, service_instance_dict)
|
|
||||||
service_instance_dict['mgmt_driver'] = mgmt_driver
|
|
||||||
mgmt_url = self.mgmt_service_address(
|
|
||||||
context, device_dict, service_instance_dict)
|
|
||||||
service_instance_dict['mgmt_url'] = mgmt_url
|
|
||||||
LOG.debug(_('service_instance_dict '
|
|
||||||
'%(service_instance_dict)s '
|
|
||||||
'mgmt_driver %(mgmt_driver)s '
|
|
||||||
'mgmt_url %(mgmt_url)s'),
|
|
||||||
{'service_instance_dict':
|
|
||||||
service_instance_dict,
|
|
||||||
'mgmt_driver': mgmt_driver, 'mgmt_url': mgmt_url})
|
|
||||||
self._update_service_instance_mgmt(
|
|
||||||
context, service_instance_dict['id'], mgmt_driver, mgmt_url)
|
|
||||||
|
|
||||||
self.mgmt_service_create_pre(
|
|
||||||
context, device_dict, service_instance_dict)
|
|
||||||
self.mgmt_service_call(
|
|
||||||
context, device_dict, service_instance_dict, kwargs)
|
|
||||||
|
|
||||||
def _create_service_instance_db(self, context, device_id,
|
|
||||||
service_instance_param, managed_by_user):
|
|
||||||
return super(VNFMPlugin, self)._create_service_instance(
|
|
||||||
context, device_id, service_instance_param, managed_by_user)
|
|
||||||
|
|
||||||
def _create_service_instance_by_type(
|
|
||||||
self, context, device_dict,
|
|
||||||
name, service_type, service_table_id):
|
|
||||||
LOG.debug(_('device_dict %(device_dict)s '
|
|
||||||
'service_type %(service_type)s'),
|
|
||||||
{'device_dict': device_dict,
|
|
||||||
'service_type': service_type})
|
|
||||||
service_type_id = [
|
|
||||||
s['id'] for s in
|
|
||||||
device_dict['device_template']['service_types']
|
|
||||||
if s['service_type'].upper() == service_type.upper()][0]
|
|
||||||
|
|
||||||
service_instance_param = {
|
|
||||||
'name': name,
|
|
||||||
'service_table_id': service_table_id,
|
|
||||||
'service_type': service_type,
|
|
||||||
'service_type_id': service_type_id,
|
|
||||||
}
|
|
||||||
service_instance_dict = self._create_service_instance_db(
|
|
||||||
context, device_dict['id'], service_instance_param, False)
|
|
||||||
|
|
||||||
new_status = constants.ACTIVE
|
|
||||||
try:
|
|
||||||
self._create_service_instance_mgmt(
|
|
||||||
context, device_dict, service_instance_dict)
|
|
||||||
except Exception:
|
|
||||||
LOG.exception(_('_create_service_instance_by_type'))
|
|
||||||
new_status = constants.ERROR
|
|
||||||
raise
|
|
||||||
finally:
|
|
||||||
service_instance_dict['status'] = new_status
|
|
||||||
self.mgmt_service_create_post(
|
|
||||||
context, device_dict, service_instance_dict)
|
|
||||||
self._update_service_instance_post(
|
|
||||||
context, service_instance_dict['id'], new_status)
|
|
||||||
return service_instance_dict
|
|
||||||
|
|
||||||
# for service drivers. e.g. hosting_driver of loadbalancer
|
|
||||||
def create_service_instance_by_type(self, context, device_dict,
|
|
||||||
name, service_type, service_table_id):
|
|
||||||
self._update_device_pre(context, device_dict['id'])
|
|
||||||
new_status = constants.ACTIVE
|
|
||||||
try:
|
|
||||||
return self._create_service_instance_by_type(
|
|
||||||
context, device_dict, name, service_type,
|
|
||||||
service_table_id)
|
|
||||||
except Exception:
|
|
||||||
LOG.exception(_('create_service_instance_by_type'))
|
|
||||||
new_status = constants.ERROR
|
|
||||||
finally:
|
|
||||||
self._update_device_post(context, device_dict['id'], new_status)
|
|
||||||
|
|
||||||
def _create_service_instance_wait(self, context, device_id,
|
|
||||||
service_instance_dict):
|
|
||||||
device_dict = self.get_device(context, device_id)
|
|
||||||
|
|
||||||
new_status = constants.ACTIVE
|
|
||||||
try:
|
|
||||||
self._create_service_instance_mgmt(
|
|
||||||
context, device_dict, service_instance_dict)
|
|
||||||
except Exception:
|
|
||||||
LOG.exception(_('_create_service_instance_mgmt'))
|
|
||||||
new_status = constants.ERROR
|
|
||||||
service_instance_dict['status'] = new_status
|
|
||||||
self.mgmt_service_create_post(
|
|
||||||
context, device_dict, service_instance_dict)
|
|
||||||
self._update_service_instance_post(
|
|
||||||
context, service_instance_dict['id'], new_status)
|
|
||||||
|
|
||||||
# for service drivers. e.g. hosting_driver of loadbalancer
|
|
||||||
def _create_service_instance(self, context, device_id,
|
|
||||||
service_instance_param, managed_by_user):
|
|
||||||
service_instance_dict = self._create_service_instance_db(
|
|
||||||
context, device_id, service_instance_param, managed_by_user)
|
|
||||||
self.spawn_n(self._create_service_instance_wait, context,
|
|
||||||
device_id, service_instance_dict)
|
|
||||||
return service_instance_dict
|
|
||||||
|
|
||||||
def create_service_instance(self, context, service_instance):
|
|
||||||
service_instance_param = service_instance['service_instance'].copy()
|
|
||||||
device = service_instance_param.pop('devices')
|
|
||||||
device_id = device[0]
|
|
||||||
service_instance_dict = self._create_service_instance(
|
|
||||||
context, device_id, service_instance_param, True)
|
|
||||||
return service_instance_dict
|
|
||||||
|
|
||||||
def _update_service_instance_wait(self, context, service_instance_dict,
|
|
||||||
mgmt_kwargs, callback, errorback):
|
|
||||||
devices = service_instance_dict['devices']
|
|
||||||
assert len(devices) == 1
|
|
||||||
device_dict = self.get_device(context, devices[0])
|
|
||||||
kwargs = {
|
|
||||||
mgmt_constants.KEY_ACTION: mgmt_constants.ACTION_UPDATE_SERVICE,
|
|
||||||
mgmt_constants.KEY_KWARGS: {
|
|
||||||
'device': device_dict,
|
|
||||||
'service_instance': service_instance_dict,
|
|
||||||
mgmt_constants.KEY_KWARGS: mgmt_kwargs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
self.mgmt_call(context, device_dict, kwargs)
|
|
||||||
self.mgmt_service_update_pre(context, device_dict,
|
|
||||||
service_instance_dict)
|
|
||||||
self.mgmt_service_call(context, device_dict,
|
|
||||||
service_instance_dict, kwargs)
|
|
||||||
except Exception:
|
|
||||||
LOG.exception(_('mgmt call failed %s'), kwargs)
|
|
||||||
service_instance_dict['status'] = constants.ERROR
|
|
||||||
self.mgmt_service_update_post(context, device_dict,
|
|
||||||
service_instance_dict)
|
|
||||||
self._update_service_instance_post(
|
|
||||||
context, service_instance_dict['id'], constants.ERROR)
|
|
||||||
if errorback:
|
|
||||||
errorback()
|
|
||||||
else:
|
|
||||||
service_instance_dict['status'] = constants.ACTIVE
|
|
||||||
self.mgmt_service_update_post(context, device_dict,
|
|
||||||
service_instance_dict)
|
|
||||||
self._update_service_instance_post(
|
|
||||||
context, service_instance_dict['id'], constants.ACTIVE)
|
|
||||||
if callback:
|
|
||||||
callback()
|
|
||||||
|
|
||||||
# for service drivers. e.g. hosting_driver of loadbalancer
|
|
||||||
def _update_service_instance(self, context, service_instance_id,
|
|
||||||
mgmt_kwargs, callback, errorback):
|
|
||||||
service_instance_dict = self._update_service_instance_pre(
|
|
||||||
context, service_instance_id, {})
|
|
||||||
self.spawn_n(self._update_service_instance_wait, context,
|
|
||||||
service_instance_dict, mgmt_kwargs, callback, errorback)
|
|
||||||
|
|
||||||
# for service drivers. e.g. hosting_driver of loadbalancer
|
|
||||||
def _update_service_table_instance(
|
|
||||||
self, context, service_table_id, mgmt_kwargs, callback, errorback):
|
|
||||||
_device_dict, service_instance_dict = self.get_by_service_table_id(
|
|
||||||
context, service_table_id)
|
|
||||||
service_instance_dict = self._update_service_instance_pre(
|
|
||||||
context, service_instance_dict['id'], {})
|
|
||||||
self.spawn_n(self._update_service_instance_wait, context,
|
|
||||||
service_instance_dict, mgmt_kwargs, callback, errorback)
|
|
||||||
|
|
||||||
def update_service_instance(self, context, service_instance_id,
|
|
||||||
service_instance):
|
|
||||||
mgmt_kwargs = service_instance['service_instance'].get('kwarg', {})
|
|
||||||
service_instance_dict = self._update_service_instance_pre(
|
|
||||||
context, service_instance_id, service_instance)
|
|
||||||
|
|
||||||
self.spawn_n(self._update_service_instance_wait, context,
|
|
||||||
service_instance_dict, mgmt_kwargs, None, None)
|
|
||||||
return service_instance_dict
|
|
||||||
|
|
||||||
def _delete_service_instance_wait(self, context, device, service_instance,
|
|
||||||
mgmt_kwargs, callback, errorback):
|
|
||||||
service_instance_id = service_instance['id']
|
|
||||||
kwargs = {
|
|
||||||
mgmt_constants.KEY_ACTION: mgmt_constants.ACTION_DELETE_SERVICE,
|
|
||||||
mgmt_constants.KEY_KWARGS: {
|
|
||||||
'device': device,
|
|
||||||
'service_instance': service_instance,
|
|
||||||
mgmt_constants.KEY_KWARGS: mgmt_kwargs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
self.mgmt_service_delete_pre(context, device, service_instance)
|
|
||||||
self.mgmt_service_call(context, device, service_instance, kwargs)
|
|
||||||
self.mgmt_call(context, device, kwargs)
|
|
||||||
except Exception:
|
|
||||||
LOG.exception(_('mgmt call failed %s'), kwargs)
|
|
||||||
service_instance['status'] = constants.ERROR
|
|
||||||
self.mgmt_service_delete_post(context, device, service_instance)
|
|
||||||
self._update_service_instance_post(context, service_instance_id,
|
|
||||||
constants.ERROR)
|
|
||||||
if errorback:
|
|
||||||
errorback()
|
|
||||||
else:
|
|
||||||
service_instance['status'] = constants.ACTIVE
|
|
||||||
self.mgmt_service_delete_post(context, device, service_instance)
|
|
||||||
self._delete_service_instance_post(context, service_instance_id)
|
|
||||||
if callback:
|
|
||||||
callback()
|
|
||||||
|
|
||||||
# for service drivers. e.g. hosting_driver of loadbalancer
|
|
||||||
def _delete_service_table_instance(
|
|
||||||
self, context, service_table_instance_id,
|
|
||||||
mgmt_kwargs, callback, errorback):
|
|
||||||
try:
|
|
||||||
device, service_instance = self.get_by_service_table_id(
|
|
||||||
context, service_table_instance_id)
|
|
||||||
except orm_exc.NoResultFound:
|
|
||||||
# there are no entry for some reason.
|
|
||||||
# e.g. partial creation due to error
|
|
||||||
callback()
|
|
||||||
return
|
|
||||||
self._delete_service_instance_pre(context, service_instance['id'],
|
|
||||||
False)
|
|
||||||
self.spawn_n(
|
|
||||||
self._delete_service_instance_wait, context, device,
|
|
||||||
service_instance, mgmt_kwargs, callback, errorback)
|
|
||||||
|
|
||||||
def delete_service_instance(self, context, service_instance_id):
|
|
||||||
# mgmt_kwargs is needed?
|
|
||||||
device, service_instance = self.get_by_service_instance_id(
|
|
||||||
context, service_instance_id)
|
|
||||||
self._delete_service_instance_pre(context, service_instance_id, True)
|
|
||||||
self.spawn_n(
|
|
||||||
self._delete_service_instance_wait, context, device,
|
|
||||||
service_instance, {}, None, None)
|
|
||||||
|
|
||||||
def create_vnf(self, context, vnf):
|
def create_vnf(self, context, vnf):
|
||||||
vnf['device'] = vnf.pop('vnf')
|
vnf['device'] = vnf.pop('vnf')
|
||||||
vnf_attributes = vnf['device']
|
vnf_attributes = vnf['device']
|
||||||
|
Loading…
Reference in New Issue
Block a user