From 17907186122ad2d147f0488878e0fa0761eaa829 Mon Sep 17 00:00:00 2001 From: gong yong sheng Date: Thu, 26 Nov 2015 13:42:07 +0800 Subject: [PATCH] Remove Service instance, context resources These resources are out of the scope of tacker (cherry picked from commit 5c7d475eb3489258586382979dd16f9a871f6823) Change-Id: Ib585e44e629908ca97c5ab67cdb8ed4375b61fe7 Closes-bug: 1519968 --- etc/tacker/tacker.conf | 18 - .../2774a42c7163_remove_service_related.py | 115 +++++ .../alembic_migrations/versions/HEAD | 2 +- tacker/db/vm/vm_db.py | 392 ------------------ tacker/extensions/vnfm.py | 45 +- tacker/tests/unit/db/utils.py | 2 +- tacker/vm/mgmt_drivers/abstract_driver.py | 53 --- tacker/vm/mgmt_drivers/noop.py | 11 - tacker/vm/mgmt_drivers/openwrt/openwrt.py | 11 - tacker/vm/plugin.py | 302 -------------- 10 files changed, 118 insertions(+), 833 deletions(-) create mode 100644 tacker/db/migration/alembic_migrations/versions/2774a42c7163_remove_service_related.py diff --git a/etc/tacker/tacker.conf b/etc/tacker/tacker.conf index 279e28ce6..5a9ff563a 100644 --- a/etc/tacker/tacker.conf +++ b/etc/tacker/tacker.conf @@ -415,21 +415,3 @@ auth_plugin = password heat_uri = http://localhost:8004/v1 stack_retries = 5 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 diff --git a/tacker/db/migration/alembic_migrations/versions/2774a42c7163_remove_service_related.py b/tacker/db/migration/alembic_migrations/versions/2774a42c7163_remove_service_related.py new file mode 100644 index 000000000..35d7b2dd7 --- /dev/null +++ b/tacker/db/migration/alembic_migrations/versions/2774a42c7163_remove_service_related.py @@ -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 ### diff --git a/tacker/db/migration/alembic_migrations/versions/HEAD b/tacker/db/migration/alembic_migrations/versions/HEAD index 30ab5ebf5..6fecb8157 100644 --- a/tacker/db/migration/alembic_migrations/versions/HEAD +++ b/tacker/db/migration/alembic_migrations/versions/HEAD @@ -1 +1 @@ -12a57080b278 \ No newline at end of file +2774a42c7163 \ No newline at end of file diff --git a/tacker/db/vm/vm_db.py b/tacker/db/vm/vm_db.py index 55ee9f55e..9da1bf0d2 100644 --- a/tacker/db/vm/vm_db.py +++ b/tacker/db/vm/vm_db.py @@ -118,9 +118,6 @@ class Device(model_base.BASE, models_v1.HasTenant): mgmt_url = sa.Column(sa.String(255), nullable=True) 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) @@ -138,133 +135,6 @@ class DeviceAttribute(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_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): @property @@ -287,8 +157,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): raise vnfm.DeviceTemplateNotFound(device_tempalte_id=id) elif issubclass(model, ServiceType): raise vnfm.ServiceTypeNotFound(service_type_id=id) - elif issubclass(model, ServiceInstance): - raise vnfm.ServiceInstanceNotFound(service_instance_id=id) if issubclass(model, Device): raise vnfm.DeviceNotFound(device_id=id) else: @@ -313,57 +181,22 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): 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_dev_attrs_dict(self, 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): LOG.debug(_('device_db %s'), device_db) LOG.debug(_('device_db attributes %s'), device_db.attributes) res = { - 'services': - self._make_services_list(getattr(device_db, 'services', [])), 'device_template': self._make_template_dict(device_db.template), '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', 'template_id', 'status', 'mgmt_url') 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_url', - 'status') - res.update((key, instance_db[key]) for key in key_list) - return self._fields(res, fields) - @staticmethod def _infra_driver_name(device_dict): return device_dict['device_template']['infra_driver'] @@ -376,9 +209,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): def _instance_id(device_dict): return device_dict['instance_id'] - ########################################################################### - # hosting device template - def create_device_template(self, context, device_template): template = device_template['device_template'] LOG.debug(_('template %s'), template) @@ -464,8 +294,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): self._make_template_dict, filters=filters, fields=fields) - # called internally, not by REST API - # need enhancement? def choose_device_template(self, context, service_type, required_attributes=None): required_attributes = required_attributes or [] @@ -490,9 +318,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): if template_db: return self._make_template_dict(template_db) - ########################################################################### - # hosting device - def _device_attribute_update_or_create( self, context, device_id, key, value): arg = (self._model_query(context, DeviceAttribute). @@ -515,7 +340,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): name = device.get('name') device_id = device.get('id') or str(uuid.uuid4()) attributes = device.get('attributes', {}) - service_context = device.get('service_context', []) with context.session.begin(subtransactions=True): template_db = self._get_resource(context, DeviceTemplate, template_id) @@ -533,22 +357,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): key=key, value=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 @@ -569,18 +377,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): self._device_attribute_update_or_create(context, device_id, 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): with context.session.begin(subtransactions=True): (self._model_query(context, Device). @@ -628,11 +424,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): 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 vnfm.DeviceInUse(device_id=device_id) device_db = self._get_device_db( context, device_id, _ACTIVE_UPDATE_ERROR_DEAD, constants.PENDING_DELETE) @@ -650,8 +441,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): else: (self._model_query(context, DeviceAttribute). filter(DeviceAttribute.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 @@ -749,187 +538,6 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin): update({'device_id': new_device_id})) 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): return self.get_devices(context, filters, fields) diff --git a/tacker/extensions/vnfm.py b/tacker/extensions/vnfm.py index a2e25b2c7..a428735ac 100644 --- a/tacker/extensions/vnfm.py +++ b/tacker/extensions/vnfm.py @@ -77,19 +77,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') - - class ParamYAMLNotWellFormed(exceptions.InvalidInput): 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 -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 = { @@ -277,13 +242,6 @@ RESOURCE_ATTRIBUTE_MAP = { 'is_visible': True, 'default': {}, }, - 'service_contexts': { - 'allow_post': True, - 'allow_put': False, - 'validate': {'type:service_context_list': None}, - 'is_visible': True, - 'default': [], - }, 'status': { 'allow_post': False, 'allow_put': False, @@ -449,7 +407,6 @@ class Vnfm(extensions.ExtensionDescriptor): plural_mappings = resource_helper.build_plural_mappings( special_mappings, RESOURCE_ATTRIBUTE_MAP) plural_mappings['service_types'] = 'service_type' - plural_mappings['service_contexts'] = 'service_context' attr.PLURALS.update(plural_mappings) return resource_helper.build_resource_info( plural_mappings, RESOURCE_ATTRIBUTE_MAP, constants.VNFM, diff --git a/tacker/tests/unit/db/utils.py b/tacker/tests/unit/db/utils.py index 5ee0afd58..e437bc17c 100644 --- a/tacker/tests/unit/db/utils.py +++ b/tacker/tests/unit/db/utils.py @@ -53,7 +53,7 @@ def get_dummy_vnf_obj(): return {'vnf': {'description': 'dummy_vnf_description', 'vnfd_id': u'eb094833-995e-49f0-a047-dfb56aaf7c4e', 'tenant_id': u'ad7ebc56538745a08ef7c5e97f8bd437', - 'name': 'dummy_vnf', 'service_contexts': [], + 'name': 'dummy_vnf', 'attributes': {}}} diff --git a/tacker/vm/mgmt_drivers/abstract_driver.py b/tacker/vm/mgmt_drivers/abstract_driver.py index a41dab6bd..142fc95e2 100644 --- a/tacker/vm/mgmt_drivers/abstract_driver.py +++ b/tacker/vm/mgmt_drivers/abstract_driver.py @@ -87,43 +87,6 @@ class DeviceMGMTAbstractDriver(extensions.PluginInterface): def mgmt_call(self, plugin, context, device, kwargs): 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): def mgmt_url(self, plugin, context, device): @@ -140,19 +103,3 @@ class DeviceMGMTByNetwork(DeviceMGMTAbstractDriver): mgmt_url['port_id'] = port['id'] mgmt_url['mac_address'] = port['mac_address'] 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) diff --git a/tacker/vm/mgmt_drivers/noop.py b/tacker/vm/mgmt_drivers/noop.py index 7051e07d0..dffb74c5f 100644 --- a/tacker/vm/mgmt_drivers/noop.py +++ b/tacker/vm/mgmt_drivers/noop.py @@ -44,14 +44,3 @@ class DeviceMgmtNoop(abstract_driver.DeviceMGMTAbstractDriver): def mgmt_call(self, plugin, context, device, kwargs): LOG.debug(_('mgmt_device_call %(device)s %(kwargs)s'), {'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}) diff --git a/tacker/vm/mgmt_drivers/openwrt/openwrt.py b/tacker/vm/mgmt_drivers/openwrt/openwrt.py index 9daf003b5..0ec178a2a 100644 --- a/tacker/vm/mgmt_drivers/openwrt/openwrt.py +++ b/tacker/vm/mgmt_drivers/openwrt/openwrt.py @@ -90,14 +90,3 @@ class DeviceMgmtOpenWRT(abstract_driver.DeviceMGMTAbstractDriver): vdu) continue 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}) diff --git a/tacker/vm/plugin.py b/tacker/vm/plugin.py index d84d59010..7213539fd 100644 --- a/tacker/vm/plugin.py +++ b/tacker/vm/plugin.py @@ -25,7 +25,6 @@ import eventlet import inspect 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 @@ -100,59 +99,6 @@ class VNFMMgmtMixin(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 VNFMPlugin(vm_db.VNFMPluginDb, VNFMMgmtMixin): """ServiceVMPlugin which supports ServiceVM framework @@ -410,254 +356,6 @@ class VNFMPlugin(vm_db.VNFMPluginDb, VNFMMgmtMixin): 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_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): vnf['device'] = vnf.pop('vnf') vnf_attributes = vnf['device']