drop service instance rest resources and drop related codes
As the consensus at this moment, service instance resource should be dropped. At least at this stage. If it is found needed later, it could be added later. Change-Id: I7ffe45f5e6f1891cd6bb29625791c977798b77e0
This commit is contained in:
parent
d23b6ce94f
commit
885387a4da
|
@ -18,8 +18,6 @@
|
|||
import netaddr
|
||||
import webob.exc
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from tacker.api import api_common
|
||||
from tacker.api.v1 import attributes
|
||||
from tacker.api.v1 import resource as wsgi_resource
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright 2014 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.
|
||||
#
|
||||
|
||||
"""empty message
|
||||
|
||||
Revision ID: 4c31092895b8
|
||||
Revises: 81ffa86020d
|
||||
Create Date: 2014-08-01 11:48:10.319498
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '4c31092895b8'
|
||||
down_revision = '81ffa86020d'
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
||||
def upgrade(active_plugins=None, options=None):
|
||||
op.drop_column('devicetameplates', 'service_types')
|
||||
|
||||
op.drop_table('servicetypes')
|
||||
op.drop_table('deviceservicecontexts')
|
||||
op.drop_table('serviceinstances')
|
||||
op.drop_table('servicecontexts')
|
||||
op.drop_table('servicedevicebindings')
|
||||
|
||||
|
||||
def downgrade(active_plugins=None, options=None):
|
||||
raise NotImplementedError()
|
|
@ -1 +1 @@
|
|||
81ffa86020d
|
||||
4c31092895b8
|
|
@ -44,9 +44,6 @@ _ACTIVE_UPDATE = (constants.ACTIVE, constants.PENDING_UPDATE)
|
|||
###########################################################################
|
||||
# db tables
|
||||
|
||||
# This table corresponds to SeviceVM of the origial spec of Blueprint
|
||||
# https://docs.google.com/document/d/
|
||||
# 1pwFVV8UavvQkBz92bT-BweBAiIZoMJP0NPAO4-60XFY/edit?pli=1
|
||||
class DeviceTemplate(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
|
||||
"""Represents template to create hosting device
|
||||
"""
|
||||
|
@ -54,11 +51,6 @@ class DeviceTemplate(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
|
|||
name = sa.Column(sa.String(255))
|
||||
description = sa.Column(sa.String(255))
|
||||
|
||||
# service type that this service vm provides.
|
||||
# At first phase, this includes only single service
|
||||
# In future, single service VM may accomodate multiple services.
|
||||
service_types = orm.relationship('ServiceType', backref='template')
|
||||
|
||||
# driver to create hosting device. e.g. noop, nova, heat, etc...
|
||||
device_driver = sa.Column(sa.String(255))
|
||||
|
||||
|
@ -95,19 +87,6 @@ class DeviceTemplate(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
|
|||
# access_cred_passwd = sa.Column(sa.String(255), nullable=True)
|
||||
|
||||
|
||||
# this table corresponds to Service_Type in ServiceVM of the original spec
|
||||
# TODO(yamahata): reach consensus for naming.
|
||||
# 'service' might be too generic terminology.
|
||||
class ServiceType(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
|
||||
"""Represents service type which hosting device provides.
|
||||
Since a device may provide many services, This is one-to-many
|
||||
relationship.
|
||||
"""
|
||||
template_id = sa.Column(sa.String(36), sa.ForeignKey('devicetemplates.id'),
|
||||
nullable=False)
|
||||
service_type = sa.Column(sa.String(255), nullable=False)
|
||||
|
||||
|
||||
# this table corresponds to image, flavor in ServiceVM of the original spec
|
||||
# Or just string long enough?
|
||||
class DeviceTemplateAttribute(model_base.BASE, models_v1.HasId):
|
||||
|
@ -139,9 +118,6 @@ class Device(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
|
|||
# e.g. (driver, mgmt_address) = (ssh, ip address), ...
|
||||
mgmt_address = sa.Column(sa.String(255), nullable=True)
|
||||
|
||||
service_context = orm.relationship('DeviceServiceContext')
|
||||
services = orm.relationship('ServiceDeviceBinding', backref='device')
|
||||
|
||||
status = sa.Column(sa.String(255), nullable=False)
|
||||
|
||||
|
||||
|
@ -160,132 +136,8 @@ class DeviceArg(model_base.BASE, models_v1.HasId):
|
|||
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_address = 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 ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
||||
db_base.CommonDbMixin):
|
||||
|
@ -308,10 +160,6 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
except orm_exc.NoResultFound:
|
||||
if issubclass(model, DeviceTemplate):
|
||||
raise servicevm.DeviceTemplateNotFound(device_tempalte_id=id)
|
||||
elif issubclass(model, ServiceType):
|
||||
raise servicevm.ServiceTypeNotFound(service_type_id=id)
|
||||
elif issubclass(model, ServiceInstance):
|
||||
raise servicevm.ServiceInstanceNotFound(service_instance_id=id)
|
||||
if issubclass(model, Device):
|
||||
raise servicevm.DeviceNotFound(device_id=id)
|
||||
else:
|
||||
|
@ -320,11 +168,6 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
def _make_attributes_dict(self, attributes_db):
|
||||
return dict((attr.key, attr.value) for attr in attributes_db)
|
||||
|
||||
def _make_service_types_list(self, service_types):
|
||||
return [{'id': service_type.id,
|
||||
'service_type': service_type.service_type}
|
||||
for service_type in service_types]
|
||||
|
||||
def _make_template_dict(self, template, fields=None):
|
||||
res = {
|
||||
'attributes': self._make_attributes_dict(template['attributes']),
|
||||
|
@ -336,56 +179,21 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
res.update((key, template[key]) for key in key_list)
|
||||
return self._fields(res, fields)
|
||||
|
||||
def _make_services_list(self, binding_db):
|
||||
return [binding.service_instance_id for binding in binding_db]
|
||||
|
||||
def _make_kwargs_dict(self, kwargs_db):
|
||||
return dict((arg.key, jsonutils.loads(arg.value)) for arg in kwargs_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):
|
||||
LOG.debug(_('device_db %s'), device_db)
|
||||
res = {
|
||||
'services':
|
||||
self._make_services_list(getattr(device_db, 'services', [])),
|
||||
'device_template':
|
||||
self._make_template_dict(device_db.template),
|
||||
'kwargs': self._make_kwargs_dict(device_db.kwargs),
|
||||
'service_context':
|
||||
self._make_device_service_context_dict(device_db.service_context),
|
||||
}
|
||||
key_list = ('id', 'tenant_id', 'instance_id', 'template_id', 'status',
|
||||
'mgmt_address')
|
||||
res.update((key, device_db[key]) for key in key_list)
|
||||
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_address',
|
||||
'status')
|
||||
res.update((key, instance_db[key]) for key in key_list)
|
||||
return self._fields(res, fields)
|
||||
|
||||
@staticmethod
|
||||
def _device_driver_name(device_dict):
|
||||
return device_dict['device_template']['device_driver']
|
||||
|
@ -411,7 +219,6 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
tenant_id = self._get_tenant_id_for_create(context, template)
|
||||
device_driver = template.get('device_driver')
|
||||
mgmt_driver = template.get('mgmt_driver')
|
||||
service_types = template.get('service_types')
|
||||
|
||||
if (not attributes.is_attr_set(device_driver)):
|
||||
LOG.debug(_('hosting device driver unspecified'))
|
||||
|
@ -419,9 +226,6 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
if (not attributes.is_attr_set(mgmt_driver)):
|
||||
LOG.debug(_('mgmt driver unspecified'))
|
||||
raise servicevm.MGMTDriverNotSpecified()
|
||||
if (not attributes.is_attr_set(service_types)):
|
||||
LOG.debug(_('service types unspecified'))
|
||||
raise servicevm.SeviceTypesNotSpecified()
|
||||
|
||||
with context.session.begin(subtransactions=True):
|
||||
template_id = str(uuid.uuid4())
|
||||
|
@ -440,14 +244,6 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
key=key,
|
||||
value=value)
|
||||
context.session.add(attribute_db)
|
||||
for service_type in (item['service_type']
|
||||
for item in template['service_types']):
|
||||
service_type_db = ServiceType(
|
||||
id=str(uuid.uuid4()),
|
||||
tenant_id=tenant_id,
|
||||
template_id=template_id,
|
||||
service_type=service_type)
|
||||
context.session.add(service_type_db)
|
||||
|
||||
LOG.debug(_('template_db %(template_db)s %(attributes)s '
|
||||
'%(service_types)s'),
|
||||
|
@ -474,8 +270,6 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
raise servicevm.DeviceTemplateInUse(
|
||||
device_template_id=device_template_id)
|
||||
|
||||
context.session.query(ServiceType).filter_by(
|
||||
template_id=device_template_id).delete()
|
||||
context.session.query(DeviceTemplateAttribute).filter_by(
|
||||
template_id=device_template_id).delete()
|
||||
template_db = self._get_resource(context, DeviceTemplate,
|
||||
|
@ -494,18 +288,11 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
|
||||
# called internally, not by REST API
|
||||
# need enhancement?
|
||||
def choose_device_template(self, context, service_type,
|
||||
required_attributes=None):
|
||||
def choose_device_template(self, context, required_attributes=None):
|
||||
required_attributes = required_attributes or []
|
||||
LOG.debug(_('required_attributes %s'), required_attributes)
|
||||
with context.session.begin(subtransactions=True):
|
||||
query = (
|
||||
context.session.query(DeviceTemplate).
|
||||
filter(
|
||||
sa.exists().
|
||||
where(sa.and_(
|
||||
DeviceTemplate.id == ServiceType.template_id,
|
||||
ServiceType.service_type == service_type))))
|
||||
query = context.session.query(DeviceTemplate)
|
||||
for key in required_attributes:
|
||||
query = query.filter(
|
||||
sa.exists().
|
||||
|
@ -529,7 +316,6 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
template_id = device['template_id']
|
||||
device_id = str(uuid.uuid4())
|
||||
kwargs = device.get('kwargs', {})
|
||||
service_context = device.get('service_context', [])
|
||||
with context.session.begin(subtransactions=True):
|
||||
device_db = Device(id=device_id,
|
||||
tenant_id=tenant_id,
|
||||
|
@ -542,28 +328,12 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
key=key, value=jsonutils.dumps(value))
|
||||
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)
|
||||
|
||||
# called internally, not by REST API
|
||||
# intsance_id = None means error on creation
|
||||
def _create_device_post(self, context, device_id, instance_id,
|
||||
mgmt_address, service_context):
|
||||
mgmt_address):
|
||||
with context.session.begin(subtransactions=True):
|
||||
query = (self._model_query(context, Device).
|
||||
filter(Device.id == device_id).
|
||||
|
@ -574,18 +344,6 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
if instance_id is None:
|
||||
query.update({'status': constants.ERROR})
|
||||
|
||||
for sc_entry in 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):
|
||||
with context.session.begin(subtransactions=True):
|
||||
(self._model_query(context, Device).
|
||||
|
@ -623,11 +381,6 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
|
||||
def _delete_device_pre(self, context, device_id):
|
||||
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 servicevm.DeviceInUse(device_id=device_id)
|
||||
device_db = self._get_device_db(context, device_id,
|
||||
constants.PENDING_DELETE)
|
||||
|
||||
|
@ -644,8 +397,6 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
else:
|
||||
(self._model_query(context, DeviceArg).
|
||||
filter(DeviceArg.device_id == device_id).delete())
|
||||
(self._model_query(context, DeviceServiceContext).
|
||||
filter(DeviceServiceContext.device_id == device_id).delete())
|
||||
query.delete()
|
||||
|
||||
# reference implementation. needs to be overrided by subclass
|
||||
|
@ -656,8 +407,7 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
# by another thread if it takes a while.
|
||||
instance_id = str(uuid.uuid4())
|
||||
device_dict['instance_id'] = instance_id
|
||||
self._create_device_post(context, device_dict['id'], instance_id, None,
|
||||
device_dict['service_context'])
|
||||
self._create_device_post(context, device_dict['id'], instance_id, None)
|
||||
self._create_device_status(context, device_dict['id'],
|
||||
constants.ACTIVE)
|
||||
return device_dict
|
||||
|
@ -686,184 +436,3 @@ class ServiceResourcePluginDb(servicevm.ServiceVMPluginBase,
|
|||
def get_devices(self, context, filters=None, fields=None):
|
||||
return self._get_collection(context, Device, self._make_device_dict,
|
||||
filters=filters, fields=fields)
|
||||
|
||||
###########################################################################
|
||||
# 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_address
|
||||
mgmt_driver, mgmt_address 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_address = service_instance_param.get('mgmt_address')
|
||||
|
||||
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_address=mgmt_address)
|
||||
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_address):
|
||||
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_address': mgmt_address}))
|
||||
|
||||
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 servicevm.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 servicevm.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)
|
||||
|
|
|
@ -44,10 +44,6 @@ class MgmtDriverNotSpecified(exceptions.InvalidInput):
|
|||
message = _('management driver is not speicfied')
|
||||
|
||||
|
||||
class ServiceTypesNotSpecified(exceptions.InvalidInput):
|
||||
message = _('service types are not speicfied')
|
||||
|
||||
|
||||
class DeviceTemplateInUse(exceptions.InUse):
|
||||
message = _('device template %(device_template_id)s is still in use')
|
||||
|
||||
|
@ -92,66 +88,6 @@ class DeviceNotFound(exceptions.NotFound):
|
|||
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')
|
||||
|
||||
|
||||
def _validate_service_type_list(data, valid_values=None):
|
||||
if not isinstance(data, list):
|
||||
msg = _("invalid data format for service list: '%s'") % data
|
||||
LOG.debug(msg)
|
||||
return msg
|
||||
if not data:
|
||||
msg = _("empty list is not allowed for service list. '%s'") % data
|
||||
LOG.debug(msg)
|
||||
return msg
|
||||
key_specs = {
|
||||
'service_type': {
|
||||
'type:string': None,
|
||||
}
|
||||
}
|
||||
for service in data:
|
||||
msg = attr._validate_dict(service, key_specs)
|
||||
if msg:
|
||||
LOG.debug(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_context_list'] = _validate_service_context_list
|
||||
|
||||
|
||||
RESOURCE_ATTRIBUTE_MAP = {
|
||||
|
||||
'device_templates': {
|
||||
|
@ -183,14 +119,6 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||
'is_visible': True,
|
||||
'default': '',
|
||||
},
|
||||
'service_types': {
|
||||
'allow_post': True,
|
||||
'allow_put': False,
|
||||
'convert_to': attr.convert_to_list,
|
||||
'validate': {'type:service_type_list': None},
|
||||
'is_visible': True,
|
||||
'default': attr.ATTR_NOT_SPECIFIED,
|
||||
},
|
||||
'device_driver': {
|
||||
'allow_post': True,
|
||||
'allow_put': False,
|
||||
|
@ -255,96 +183,12 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||
'is_visible': True,
|
||||
'default': {},
|
||||
},
|
||||
'service_contexts': {
|
||||
'allow_post': True,
|
||||
'allow_put': False,
|
||||
'validate': {'type:service_context_list': None},
|
||||
'is_visible': True,
|
||||
},
|
||||
'services': {
|
||||
'allow_post': False,
|
||||
'allow_put': False,
|
||||
'validate': {'type:uuid': None},
|
||||
'is_visible': True,
|
||||
},
|
||||
'status': {
|
||||
'allow_post': False,
|
||||
'allow_put': False,
|
||||
'is_visible': True,
|
||||
},
|
||||
},
|
||||
|
||||
'service_instances': {
|
||||
'id': {
|
||||
'allow_post': False,
|
||||
'allow_put': False,
|
||||
'validate': {'type:uuid': None},
|
||||
'is_visible': True,
|
||||
'primary_key': True
|
||||
},
|
||||
'tenant_id': {
|
||||
'allow_post': True,
|
||||
'allow_put': False,
|
||||
'validate': {'type:string': None},
|
||||
'required_by_policy': True,
|
||||
'is_visible': True
|
||||
},
|
||||
'name': {
|
||||
'allow_post': True,
|
||||
'allow_put': True,
|
||||
'validate': {'type:string': None},
|
||||
'is_visible': True,
|
||||
},
|
||||
'service_type_id': {
|
||||
'allow_post': True,
|
||||
'allow_put': False,
|
||||
'validate': {'type:uuid': None},
|
||||
'is_visible': True,
|
||||
},
|
||||
'service_table_id': {
|
||||
'allow_post': True,
|
||||
'allow_put': False,
|
||||
'validate': {'type:string': None},
|
||||
'is_visible': True,
|
||||
},
|
||||
'mgmt_driver': {
|
||||
'allow_post': True,
|
||||
'allow_put': False,
|
||||
'validate': {'type:string': None},
|
||||
'is_visible': True,
|
||||
},
|
||||
'mgmt_address': {
|
||||
'allow_post': True,
|
||||
'allow_put': False,
|
||||
'validate': {'type:string': None},
|
||||
'is_visible': True,
|
||||
},
|
||||
'service_contexts': {
|
||||
'allow_post': True,
|
||||
'allow_put': False,
|
||||
'validate': {'type:service_context_list': None},
|
||||
'is_visible': True,
|
||||
},
|
||||
'devices': {
|
||||
'allow_post': True,
|
||||
'allow_put': False,
|
||||
'validate': {'type:uuid_list': None},
|
||||
'convert_to': attr.convert_to_list,
|
||||
'is_visible': True,
|
||||
},
|
||||
'status': {
|
||||
'allow_post': False,
|
||||
'allow_put': False,
|
||||
'is_visible': True,
|
||||
},
|
||||
'kwargs': {
|
||||
'allow_post': True,
|
||||
'allow_put': True,
|
||||
'validate': {'type:dict_or_none': None},
|
||||
'is_visible': True,
|
||||
'default': {},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
@ -375,9 +219,6 @@ class Servicevm(extensions.ExtensionDescriptor):
|
|||
plural_mappings = resource_helper.build_plural_mappings(
|
||||
special_mappings, RESOURCE_ATTRIBUTE_MAP)
|
||||
plural_mappings['devices'] = 'device'
|
||||
plural_mappings['service_types'] = 'service_type'
|
||||
plural_mappings['service_contexts'] = 'service_context'
|
||||
plural_mappings['services'] = 'service'
|
||||
attr.PLURALS.update(plural_mappings)
|
||||
return resource_helper.build_resource_info(
|
||||
plural_mappings, RESOURCE_ATTRIBUTE_MAP, constants.SERVICEVM,
|
||||
|
@ -437,23 +278,9 @@ class ServiceVMPluginBase(ServicePluginBase):
|
|||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_device(
|
||||
self, context, device_id, device):
|
||||
def update_device(self, context, device_id, device):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_device(self, context, device_id):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_service_instances(self, context, filters=None, fields=None):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_service_instance(self, context, service_instance_id, fields=None):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_service_instance(self, context, service_instance_id,
|
||||
service_instance):
|
||||
pass
|
||||
|
|
|
@ -20,7 +20,6 @@ from tacker.common import utils
|
|||
from tacker.openstack.common import importutils
|
||||
from tacker.openstack.common import log as logging
|
||||
from tacker.openstack.common import periodic_task
|
||||
from tacker.plugins.common import constants
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#
|
||||
# @author: Isaku Yamahata, Intel Corporation.
|
||||
|
||||
from tacker.common import topics
|
||||
from tacker.common import rpc_compat
|
||||
from tacker.common import topics
|
||||
from tacker.vm.mgmt_drivers import abstract_driver
|
||||
from tacker.vm.mgmt_drivers import constants
|
||||
|
||||
|
|
|
@ -24,12 +24,10 @@ import inspect
|
|||
|
||||
import eventlet
|
||||
from oslo.config import cfg
|
||||
from sqlalchemy.orm import exc as orm_exc
|
||||
|
||||
from tacker.api.v1 import attributes
|
||||
from tacker.common import driver_manager
|
||||
from tacker.common import topics
|
||||
from tacker.db.vm import proxy_db # noqa
|
||||
from tacker.db.vm import vm_db
|
||||
from tacker.extensions import servicevm
|
||||
from tacker.openstack.common import excutils
|
||||
|
@ -98,59 +96,6 @@ class ServiceVMMgmtMixin(object):
|
|||
device_dict, plugin=self, context=context, device=device_dict,
|
||||
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 ServiceVMPlugin(vm_db.ServiceResourcePluginDb, ServiceVMMgmtMixin):
|
||||
"""ServiceVMPlugin which supports ServiceVM framework
|
||||
|
@ -202,16 +147,6 @@ class ServiceVMPlugin(vm_db.ServiceResourcePluginDb, ServiceVMMgmtMixin):
|
|||
'drivers': cfg.CONF.servicevm.mgmt_driver})
|
||||
raise servicevm.InvalidMgmtDriver(mgmt_driver=mgmt_driver)
|
||||
|
||||
service_types = template.get('service_types')
|
||||
if not attributes.is_attr_set(service_types):
|
||||
LOG.debug(_('service type must be specified'))
|
||||
raise servicevm.ServiceTypesNotSpecified()
|
||||
for service_type in service_types:
|
||||
# TODO(yamahata):
|
||||
# framework doesn't know what services are valid for now.
|
||||
# so doesn't check it here yet.
|
||||
pass
|
||||
|
||||
return super(ServiceVMPlugin, self).create_device_template(
|
||||
context, device_template)
|
||||
|
||||
|
@ -281,14 +216,12 @@ class ServiceVMPlugin(vm_db.ServiceResourcePluginDb, ServiceVMMgmtMixin):
|
|||
return device_dict
|
||||
|
||||
# not for wsgi, but for service to creaste hosting device
|
||||
def create_device_sync(self, context, template_id, kwargs,
|
||||
service_context):
|
||||
def create_device_sync(self, context, template_id, kwargs):
|
||||
assert template_id is not None
|
||||
device = {
|
||||
'device': {
|
||||
'template_id': template_id,
|
||||
'kwargs': kwargs,
|
||||
'service_context': service_context,
|
||||
},
|
||||
}
|
||||
device_dict = self._create_device(context, device)
|
||||
|
@ -379,250 +312,3 @@ class ServiceVMPlugin(vm_db.ServiceResourcePluginDb, ServiceVMMgmtMixin):
|
|||
|
||||
self._delete_device_post(context, device_id, None)
|
||||
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_address = self.mgmt_service_address(
|
||||
context, device_dict, service_instance_dict)
|
||||
service_instance_dict['mgmt_address'] = mgmt_address
|
||||
LOG.debug(_('service_instance_dict '
|
||||
'%(service_instance_dict)s '
|
||||
'mgmt_driver %(mgmt_driver)s '
|
||||
'mgmt_address %(mgmt_address)s'),
|
||||
{'service_instance_dict':
|
||||
service_instance_dict,
|
||||
'mgmt_driver': mgmt_driver, 'mgmt_address': mgmt_address})
|
||||
self._update_service_instance_mgmt(
|
||||
context, service_instance_dict['id'], mgmt_driver, mgmt_address)
|
||||
|
||||
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(ServiceVMPlugin, 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:
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue