Merge "Fix for multiple failures in VNF lifecycle"

This commit is contained in:
Zuul 2020-12-23 07:47:53 +00:00 committed by Gerrit Code Review
commit 412ca5792b
13 changed files with 237 additions and 51 deletions

View File

@ -170,11 +170,11 @@ class ViewBuilder(base.BaseViewBuilder):
return { return {
'id': vnf_lcm_subscription.id, 'id': vnf_lcm_subscription.id,
'filter': filter_dict, 'filter': filter_dict,
'callbackUri': vnf_lcm_subscription.callback_uri.decode(), 'callbackUri': vnf_lcm_subscription.callback_uri,
} }
return { return {
'id': vnf_lcm_subscription.id, 'id': vnf_lcm_subscription.id,
'callbackUri': vnf_lcm_subscription.callback_uri.decode(), 'callbackUri': vnf_lcm_subscription.callback_uri,
} }
else: else:
return { return {

View File

@ -256,18 +256,10 @@ class VnfLcmController(wsgi.Controller):
raise webob.exc.HTTPBadRequest(explanation=msg) raise webob.exc.HTTPBadRequest(explanation=msg)
def _notification_process(self, context, vnf_instance, def _notification_process(self, context, vnf_instance,
lcm_operation, request, is_auto=False): lcm_operation, request, body, is_auto=False):
vnf_lcm_op_occs_id = uuidutils.generate_uuid() vnf_lcm_op_occs_id = uuidutils.generate_uuid()
error_point = 0 error_point = 0
if lcm_operation == fields.LcmOccsOperationType.HEAL: operation_params = jsonutils.dumps(body)
request_dict = {
'vnfc_instance_id': request.vnfc_instance_id,
'cause': request.cause
}
operation_params = str(request_dict)
else:
# lcm is instantiation by default
operation_params = str(request.additional_params)
try: try:
# call create lcm op occs here # call create lcm op occs here
LOG.debug('Create LCM OP OCCS') LOG.debug('Create LCM OP OCCS')
@ -466,8 +458,7 @@ class VnfLcmController(wsgi.Controller):
except nfvo.VimDefaultNotDefined as exc: except nfvo.VimDefaultNotDefined as exc:
raise webob.exc.HTTPBadRequest(explanation=str(exc)) raise webob.exc.HTTPBadRequest(explanation=str(exc))
except(sqlexc.SQLAlchemyError, Exception)\ except(sqlexc.SQLAlchemyError, Exception) as exc:
as exc:
raise webob.exc.HTTPInternalServerError( raise webob.exc.HTTPInternalServerError(
explanation=str(exc)) explanation=str(exc))
except webob.exc.HTTPNotFound as e: except webob.exc.HTTPNotFound as e:
@ -584,7 +575,7 @@ class VnfLcmController(wsgi.Controller):
vnf_lcm_op_occs_id = \ vnf_lcm_op_occs_id = \
self._notification_process(context, vnf_instance, self._notification_process(context, vnf_instance,
fields.LcmOccsOperationType.INSTANTIATE, fields.LcmOccsOperationType.INSTANTIATE,
instantiate_vnf_request) instantiate_vnf_request, request_body)
self.rpc_api.instantiate(context, vnf_instance, vnf, self.rpc_api.instantiate(context, vnf_instance, vnf,
instantiate_vnf_request, vnf_lcm_op_occs_id) instantiate_vnf_request, vnf_lcm_op_occs_id)
@ -618,7 +609,7 @@ class VnfLcmController(wsgi.Controller):
vnf_lcm_op_occs_id = \ vnf_lcm_op_occs_id = \
self._notification_process(context, vnf_instance, self._notification_process(context, vnf_instance,
fields.LcmOccsOperationType.TERMINATE, fields.LcmOccsOperationType.TERMINATE,
terminate_vnf_req) terminate_vnf_req, request_body)
self.rpc_api.terminate(context, vnf_instance, vnf, self.rpc_api.terminate(context, vnf_instance, vnf,
terminate_vnf_req, vnf_lcm_op_occs_id) terminate_vnf_req, vnf_lcm_op_occs_id)
@ -664,7 +655,7 @@ class VnfLcmController(wsgi.Controller):
vnf_lcm_op_occs_id = \ vnf_lcm_op_occs_id = \
self._notification_process(context, vnf_instance, self._notification_process(context, vnf_instance,
fields.LcmOccsOperationType.HEAL, fields.LcmOccsOperationType.HEAL,
heal_vnf_request) heal_vnf_request, request_body)
self.rpc_api.heal(context, vnf_instance, vnf_dict, heal_vnf_request, self.rpc_api.heal(context, vnf_instance, vnf_dict, heal_vnf_request,
vnf_lcm_op_occs_id) vnf_lcm_op_occs_id)
@ -1061,8 +1052,7 @@ class VnfLcmController(wsgi.Controller):
vnf_info['vnf_lcm_op_occ'] = vnf_lcm_op_occ vnf_info['vnf_lcm_op_occ'] = vnf_lcm_op_occ
vnf_info['after_scale_level'] = scale_level vnf_info['after_scale_level'] = scale_level
vnf_info['scale_level'] = current_level vnf_info['scale_level'] = current_level
vnf_info['instance_id'] = inst_vnf_info.instance_id
self.rpc_api.scale(context, vnf_info, vnf_instance, scale_vnf_request)
notification = {} notification = {}
notification['notificationType'] = \ notification['notificationType'] = \
@ -1079,9 +1069,9 @@ class VnfLcmController(wsgi.Controller):
notification['_links']['vnfInstance']['href'] = insta_url notification['_links']['vnfInstance']['href'] = insta_url
notification['_links']['vnfLcmOpOcc'] = {} notification['_links']['vnfLcmOpOcc'] = {}
notification['_links']['vnfLcmOpOcc']['href'] = vnflcm_url notification['_links']['vnfLcmOpOcc']['href'] = vnflcm_url
self.rpc_api.send_notification(context, notification)
vnf_info['notification'] = notification vnf_info['notification'] = notification
self.rpc_api.send_notification(context, notification)
self.rpc_api.scale(context, vnf_info, vnf_instance, scale_vnf_request)
res = webob.Response() res = webob.Response()
res.status_int = 202 res.status_int = 202
@ -1159,12 +1149,12 @@ class VnfLcmController(wsgi.Controller):
409, 409,
title='OperationState IS NOT FAILED_TEMP') title='OperationState IS NOT FAILED_TEMP')
if vnf_lcm_op_occs.operation != 'INSTANTIATION' \ if vnf_lcm_op_occs.operation != 'INSTANTIATE' \
and vnf_lcm_op_occs.operation != 'SCALE': and vnf_lcm_op_occs.operation != 'SCALE':
return self._make_problem_detail( return self._make_problem_detail(
'OPERATION IS NOT INSTANTIATION/SCALE', 'OPERATION IS NOT INSTANTIATE/SCALE',
409, 409,
title='OPERATION IS NOT INSTANTIATION/SCALE') title='OPERATION IS NOT INSTANTIATE/SCALE')
operation_params = jsonutils.loads( operation_params = jsonutils.loads(
vnf_lcm_op_occs.operation_params) vnf_lcm_op_occs.operation_params)
@ -1180,6 +1170,10 @@ class VnfLcmController(wsgi.Controller):
vnf_instance = self._get_vnf_instance( vnf_instance = self._get_vnf_instance(
context, vnf_lcm_op_occs.vnf_instance_id) context, vnf_lcm_op_occs.vnf_instance_id)
inst_vnf_info = vnf_instance.instantiated_vnf_info
if inst_vnf_info is not None:
vnf_info['instance_id'] = inst_vnf_info.instance_id
vnf_lcm_op_occs.changed_info = None vnf_lcm_op_occs.changed_info = None
vnf_info['vnf_lcm_op_occ'] = vnf_lcm_op_occs vnf_info['vnf_lcm_op_occ'] = vnf_lcm_op_occs
return self._rollback( return self._rollback(

View File

@ -641,8 +641,8 @@ class Conductor(manager.Manager):
updated_values['status'], vnf_model.status)) updated_values['status'], vnf_model.status))
vnf_model.update(updated_values) vnf_model.update(updated_values)
def _update_vnf_attributes(self, context, vnf_dict, current_statuses, def _update_vnf_attributes(self, context, vnf_instance, vnf_dict,
new_status): current_statuses, new_status):
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
try: try:
modified_attributes = {} modified_attributes = {}
@ -661,6 +661,12 @@ class Conductor(manager.Manager):
message='Cannot change status to {} while \ message='Cannot change status to {} while \
in {}'.format(updated_values['status'], in {}'.format(updated_values['status'],
vnf_model.status)) vnf_model.status))
if hasattr(vnf_instance.instantiated_vnf_info, 'instance_id'):
instance_id = \
vnf_instance.instantiated_vnf_info.instance_id
if instance_id:
# add instance_id info
updated_values.update({'instance_id': instance_id})
vnf_model.update(updated_values) vnf_model.update(updated_values)
for key, val in vnf_dict['attributes'].items(): for key, val in vnf_dict['attributes'].items():
@ -1025,6 +1031,7 @@ class Conductor(manager.Manager):
vim_info, context) vim_info, context)
if scale_vnf_request.type == 'SCALE_IN': if scale_vnf_request.type == 'SCALE_IN':
vnf_dict['action'] = 'in' vnf_dict['action'] = 'in'
vnf_dict['policy_name'] = scale_vnf_request.aspect_id
reverse = scale_vnf_request.additional_params.get('is_reverse') reverse = scale_vnf_request.additional_params.get('is_reverse')
region_name = vim_connection_info.access_info.get('region_name') region_name = vim_connection_info.access_info.get('region_name')
scale_id_list, scale_name_list, grp_id, res_num = \ scale_id_list, scale_name_list, grp_id, res_num = \
@ -1504,7 +1511,7 @@ class Conductor(manager.Manager):
auth_client = auth.auth_manager.get_auth_client( auth_client = auth.auth_manager.get_auth_client(
notification['subscriptionId']) notification['subscriptionId'])
response = auth_client.post( response = auth_client.post(
line.callback_uri.decode(), line.callback_uri,
data=json.dumps(notification)) data=json.dumps(notification))
if response.status_code == 204: if response.status_code == 204:
LOG.info( LOG.info(
@ -1517,7 +1524,7 @@ class Conductor(manager.Manager):
callback_uri[%s]" % callback_uri[%s]" %
(notification['id'], (notification['id'],
response.status_code, response.status_code,
line.callback_uri.decode())) line.callback_uri))
LOG.debug( LOG.debug(
"retry_wait %s" % "retry_wait %s" %
CONF.vnf_lcm.retry_wait) CONF.vnf_lcm.retry_wait)
@ -1580,7 +1587,7 @@ class Conductor(manager.Manager):
instantiate_vnf_req=instantiate_vnf) instantiate_vnf_req=instantiate_vnf)
vnf_dict['error_point'] = 7 vnf_dict['error_point'] = 7
self._update_vnf_attributes(context, vnf_dict, self._update_vnf_attributes(context, vnf_instance, vnf_dict,
_PENDING_STATUS, _ACTIVE_STATUS) _PENDING_STATUS, _ACTIVE_STATUS)
self.vnflcm_driver._vnf_instance_update(context, vnf_instance, self.vnflcm_driver._vnf_instance_update(context, vnf_instance,
instantiation_state=fields.VnfInstanceState. instantiation_state=fields.VnfInstanceState.
@ -1604,6 +1611,8 @@ class Conductor(manager.Manager):
self._build_instantiated_vnf_info(context, vnf_instance, self._build_instantiated_vnf_info(context, vnf_instance,
instantiate_vnf) instantiate_vnf)
self.vnflcm_driver._vnf_instance_update(context, vnf_instance,
task_state=None)
# Update vnf_lcm_op_occs table and send notification "FAILED_TEMP" # Update vnf_lcm_op_occs table and send notification "FAILED_TEMP"
self._send_lcm_op_occ_notification( self._send_lcm_op_occ_notification(

View File

@ -1 +1 @@
329cd1619d41 df26c5871f3c

View File

@ -81,5 +81,3 @@ def upgrade(active_plugins=None, options=None):
op.add_column('vnf_lcm_op_occs', op.add_column('vnf_lcm_op_occs',
sa.Column('deleted_at', sa.DateTime(), nullable=True)) sa.Column('deleted_at', sa.DateTime(), nullable=True))
pass

View File

@ -0,0 +1,66 @@
# Copyright 2020 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.
#
# flake8: noqa: E402
"""change_vnf_filter_column_definition
Revision ID: df26c5871f3c
Revises: 329cd1619d41
Create Date: 2020-11-13 18:32:46.703342
"""
# revision identifiers, used by Alembic.
revision = 'df26c5871f3c'
down_revision = '329cd1619d41'
from alembic import op
import sqlalchemy as sa
from tacker.db import migration
def upgrade(active_plugins=None, options=None):
# This migration file is to change syntax of "GENERATED ALWAYS AS"
# from 'filter' to `filter`
# TODO(esto-aln): (1) Need to fix SQL statement such that "mediumblob"
# is used instead of "text". Currently, "text" is used as a workaround.
# (2) Need to fix SQL statement to utilize sqlalchemy. Currently, we
# use raw SQL with op.exec as a workaround since op.alter_column does
# not work correctly.
alter_sql_notification_types = "ALTER TABLE vnf_lcm_filters CHANGE \
notification_types notification_types text GENERATED \
ALWAYS AS (json_unquote(json_extract(`filter`,\
'$.notificationTypes'))) VIRTUAL;"
alter_sql_notification_types_len = "ALTER TABLE vnf_lcm_filters CHANGE \
notification_types_len notification_types_len int(11) GENERATED \
ALWAYS AS (ifnull(json_length(`notification_types`),0)) VIRTUAL;"
alter_sql_operation_types = "ALTER TABLE vnf_lcm_filters CHANGE \
operation_types operation_types text GENERATED ALWAYS AS \
(json_unquote(json_extract(`filter`,'$.operationTypes'))) VIRTUAL;"
alter_sql_operation_types_len = "ALTER TABLE vnf_lcm_filters CHANGE \
operation_types_len operation_types_len int(11) GENERATED ALWAYS \
AS (ifnull(json_length(`operation_types`),0)) VIRTUAL;"
op.execute(alter_sql_notification_types)
op.execute(alter_sql_notification_types_len)
op.execute(alter_sql_operation_types)
op.execute(alter_sql_operation_types_len)

View File

@ -484,6 +484,7 @@ class VnfInstance(base.TackerObject, base.TackerPersistentObject,
'vnf_product_name': self.vnf_product_name, 'vnf_product_name': self.vnf_product_name,
'vnf_software_version': self.vnf_software_version, 'vnf_software_version': self.vnf_software_version,
'vnfd_version': self.vnfd_version, 'vnfd_version': self.vnfd_version,
'vnf_pkg_id': self.vnf_pkg_id,
'vnf_metadata': self.vnf_metadata} 'vnf_metadata': self.vnf_metadata}
if (self.instantiation_state == fields.VnfInstanceState.INSTANTIATED if (self.instantiation_state == fields.VnfInstanceState.INSTANTIATED

View File

@ -249,6 +249,7 @@ def _fake_vnf_instance_not_instantiated_response(
'vnfdId': uuidsentinel.vnfd_id, 'vnfdId': uuidsentinel.vnfd_id,
'vnfdVersion': '1.0', 'vnfdVersion': '1.0',
'vnfSoftwareVersion': '1.0', 'vnfSoftwareVersion': '1.0',
'vnfPkgId': uuidsentinel.vnf_pkg_id,
'id': uuidsentinel.vnf_instance_id, 'id': uuidsentinel.vnf_instance_id,
'metadata': {'key': 'value'} 'metadata': {'key': 'value'}
} }
@ -862,7 +863,7 @@ def vnflcm_rollback_insta(error_point=7):
start_time=datetime.datetime(2000, 1, 1, 1, 1, 1, start_time=datetime.datetime(2000, 1, 1, 1, 1, 1,
tzinfo=iso8601.UTC), tzinfo=iso8601.UTC),
vnf_instance_id=uuidsentinel.vnf_instance_id, vnf_instance_id=uuidsentinel.vnf_instance_id,
operation='INSTANTIATION', operation='INSTANTIATE',
operation_state='FAILED_TEMP', operation_state='FAILED_TEMP',
is_automatic_invocation=False, is_automatic_invocation=False,
operation_params='{}', operation_params='{}',

View File

@ -191,13 +191,22 @@ class TestOpenStack(base.FixturedTestCase):
grant_info=grant_info_test, grant_info=grant_info_test,
vnf_instance=vnf_instance) vnf_instance=vnf_instance)
@mock.patch('tacker.vnfm.vim_client.VimClient.get_vim')
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack' @mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
'.OpenStack._format_base_hot') '.OpenStack._format_base_hot')
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict') @mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
@mock.patch('tacker.common.clients.OpenstackClients') @mock.patch('tacker.common.clients.OpenstackClients')
def test_create_grant(self, mock_OpenstackClients_heat, def test_create_grant(self, mock_OpenstackClients_heat,
mock_get_base_hot_dict, mock_get_base_hot_dict,
mock_format_base_hot): mock_format_base_hot,
mock_get_vim):
mock_get_vim.return_value = {
'vim_id': uuidsentinel.vnfd_id,
'vim_type': 'test',
'vim_auth': {'username': 'test', 'password': 'test'},
'placement_attr': {'region': 'TestRegionOne'},
'tenant': 'test'
}
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid, vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
flavour='simple') flavour='simple')
vnf['placement_attr'] = {'region_name': 'dummy_region'} vnf['placement_attr'] = {'region_name': 'dummy_region'}

View File

@ -1294,3 +1294,80 @@ def update_nested_scaling_resources(nested_resources, mgmt_ports, metadata,
yaml.safe_dump(nested_resources_dict) yaml.safe_dump(nested_resources_dict)
return nested_tpl return nested_tpl
def get_policies_from_dict(vnfd_dict, policy_type=None):
final_policies = dict()
policies = vnfd_dict.get('topology_template', {}).get('policies', {})
for policy in policies:
for policy_name, policy_dict in policy.items():
if policy_type:
if policy_dict.get('type') == policy_type:
final_policies.update({policy_name: policy_dict})
else:
final_policies.update({policy_name: policy_dict})
return final_policies
@log.log
def get_scale_group(vnf_dict, vnfd_dict, inst_req_info):
scaling_group_dict = dict()
data_dict = dict()
if vnf_dict['attributes'].get('scaling_group_names'):
for policy_name, policy_dict in \
get_policies_from_dict(vnfd_dict,
ETSI_SCALING_ASPECT_DELTA).items():
aspect = policy_dict['properties']['aspect']
vdu = policy_dict['targets']
deltas = policy_dict['properties']['deltas']
for delta_key, delta_dict in deltas.items():
num = delta_dict['number_of_instances']
data_dict.update({
aspect: {
'vdu': vdu,
'num': num
}
})
for aspect_name, aspect_dict in data_dict.items():
aspect_policy = \
get_policies_from_dict(vnfd_dict, ETSI_SCALING_ASPECT)
for policy_name, policy_dict in aspect_policy.items():
aspect = policy_dict['properties']['aspects'][aspect_name]
max_level = aspect.get('max_scale_level')
data_dict[aspect_name].update({'maxLevel': max_level})
delta_policy = \
get_policies_from_dict(vnfd_dict, ETSI_INITIAL_DELTA)
for policy_name, policy_dict in delta_policy.items():
for target in policy_dict['targets']:
if target in aspect_dict['vdu']:
delta = policy_dict['properties']['initial_delta']
number_of_instances = delta['number_of_instances']
data_dict[aspect_name].update(
{'initialNum': number_of_instances})
level_policy = \
get_policies_from_dict(vnfd_dict, ETSI_INST_LEVEL)
for policy_name, policy_dict in level_policy.items():
instantiation_level_id = ""
if hasattr(inst_req_info, 'instantiation_level_id'):
instantiation_level_id = \
inst_req_info.instantiation_level_id
if not instantiation_level_id:
instantiation_level_id = \
policy_dict['properties']['default_level']
levels = policy_dict['properties']['levels']
scale_info = levels[instantiation_level_id]['scale_info']
initial_level = scale_info[aspect_name]['scale_level']
increase = aspect_dict['num'] * initial_level
default = aspect_dict['initialNum'] + increase
data_dict[aspect_name].update({'initialLevel': initial_level,
'default': default})
scaling_group_dict.update({'scaleGroupDict': data_dict})
return scaling_group_dict

View File

@ -273,7 +273,7 @@ def revert_to_error_rollback(function):
jsonutils.dump_as_bytes( jsonutils.dump_as_bytes(
resource_dict.get( resource_dict.get(
'affected_virtual_storages')) 'affected_virtual_storages'))
self.rpc_api.sendNotification(context, notification) self.rpc_api.send_notification(context, notification)
except Exception as e: except Exception as e:
LOG.warning("Failed to revert scale info for vnf " LOG.warning("Failed to revert scale info for vnf "
"instance %(id)s. Error: %(error)s", "instance %(id)s. Error: %(error)s",
@ -359,8 +359,9 @@ class VnfLcmDriver(abstract_driver.VnfInstanceAbstractDriver):
error=encodeutils.exception_to_unicode(exp)) error=encodeutils.exception_to_unicode(exp))
if vnf_instance.instantiated_vnf_info and\ if vnf_instance.instantiated_vnf_info and\
not vnf_instance.instantiated_vnf_info.instance_id: vnf_instance.instantiated_vnf_info.instance_id != instance_id:
vnf_instance.instantiated_vnf_info.instance_id = instance_id vnf_instance.instantiated_vnf_info.instance_id = instance_id
if vnf_dict['attributes'].get('scaling_group_names'): if vnf_dict['attributes'].get('scaling_group_names'):
vnf_instance.instantiated_vnf_info.scale_status = \ vnf_instance.instantiated_vnf_info.scale_status = \
vnf_dict['scale_status'] vnf_dict['scale_status']
@ -1330,14 +1331,18 @@ class VnfLcmDriver(abstract_driver.VnfInstanceAbstractDriver):
def _update_vnf_rollback(self, context, vnf_info, def _update_vnf_rollback(self, context, vnf_info,
vnf_instance, vnf_lcm_op_occs): vnf_instance, vnf_lcm_op_occs):
if vnf_lcm_op_occs.operation == 'SCALE':
status = 'ACTIVE'
else:
status = 'INACTIVE'
self._vnfm_plugin._update_vnf_rollback(context, vnf_info, self._vnfm_plugin._update_vnf_rollback(context, vnf_info,
'ERROR', 'ERROR',
'ACTIVE', status,
vnf_instance=vnf_instance, vnf_instance=vnf_instance,
vnf_lcm_op_occ=vnf_lcm_op_occs) vnf_lcm_op_occ=vnf_lcm_op_occs)
def _update_vnf_rollback_status_err(self, context, vnf_info): def _update_vnf_rollback_status_err(self, context, vnf_info):
self._vnfm_plugin._update_vnf_rollback_status_err(context, vnf_info) self._vnfm_plugin.update_vnf_rollback_status_err(context, vnf_info)
def _rollback_mgmt_call(self, context, vnf_info, kwargs): def _rollback_mgmt_call(self, context, vnf_info, kwargs):
self._vnfm_plugin.mgmt_call(context, vnf_info, kwargs) self._vnfm_plugin.mgmt_call(context, vnf_info, kwargs)

View File

@ -40,6 +40,7 @@ from tacker.extensions import vnfm
from tacker import objects from tacker import objects
from tacker.objects import fields from tacker.objects import fields
from tacker.plugins.common import constants from tacker.plugins.common import constants
from tacker.tosca import utils as tosca_utils
from tacker.tosca.utils import represent_odict from tacker.tosca.utils import represent_odict
from tacker.vnflcm import utils as vnflcm_utils from tacker.vnflcm import utils as vnflcm_utils
from tacker.vnfm.infra_drivers import abstract_driver from tacker.vnfm.infra_drivers import abstract_driver
@ -136,9 +137,14 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
LOG.debug('vnf %s', vnf) LOG.debug('vnf %s', vnf)
if vnf.get('grant'): if vnf.get('grant'):
if vnf['grant'].vim_connections: if vnf['grant'].vim_connections:
vim_con = vnf['grant'].vim_connections[0] vim_info = vnflcm_utils._get_vim(
auth_attr = vim_con.access_info context, vnf['grant'].vim_connections)
region_name = auth_attr.get('region') vim_connection_info = \
objects.VimConnectionInfo.obj_from_primitive(
vim_info, context)
auth_attr = vim_connection_info.access_info
region_name = \
vim_connection_info.access_info.get('region_name')
else: else:
region_name = vnf.get('placement_attr', {}).\ region_name = vnf.get('placement_attr', {}).\
get('region_name', None) get('region_name', None)
@ -183,6 +189,18 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
vnfd_dict = yaml.safe_load(vnfd_str) vnfd_dict = yaml.safe_load(vnfd_str)
LOG.debug('VNFD: %s', vnfd_dict) LOG.debug('VNFD: %s', vnfd_dict)
LOG.debug('VNF package path: %s', vnf_package_path) LOG.debug('VNF package path: %s', vnf_package_path)
scaling_group_dict = {}
for name, rsc in base_hot_dict.get('resources').items():
if rsc['type'] == 'OS::Heat::AutoScalingGroup':
key_name = name.replace('_group', '')
scaling_group_dict[key_name] = name
if scaling_group_dict:
vnf['attributes']['scaling_group_names'] = \
jsonutils.dump_as_bytes(scaling_group_dict)
scale_group_dict = \
tosca_utils.get_scale_group(vnf, vnfd_dict, inst_req_info)
vnf['attributes']['scale_group'] = \
jsonutils.dump_as_bytes(scale_group_dict)
sys.path.append(vnf_package_path) sys.path.append(vnf_package_path)
user_data_module = os.path.splitext( user_data_module = os.path.splitext(
user_data_path.lstrip('./'))[0].replace('/', '.') user_data_path.lstrip('./'))[0].replace('/', '.')
@ -236,12 +254,18 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
"is not in dict format.") "is not in dict format.")
raise vnfm.LCMUserDataFailed(reason=error_reason) raise vnfm.LCMUserDataFailed(reason=error_reason)
if vnf['attributes'].get('scale_group'): if scaling_group_dict:
scale_json = vnf['attributes']['scale_group'] scale_status_list = []
scaleGroupDict = jsonutils.loads(scale_json) for name, value in scale_group_dict['scaleGroupDict'].items():
for name, value in scaleGroupDict['scaleGroupDict'].items(): key_name = name + '_desired_capacity'
hot_param_dict[name + '_desired_capacity'] = \ if base_hot_dict.get('parameters') and \
value['default'] base_hot_dict['parameters'].get(key_name):
hot_param_dict[key_name] = value['default']
scale_status = objects.ScaleInfo(
aspect_id=name,
scale_level=value['initialLevel'])
scale_status_list.append(scale_status)
vnf['scale_status'] = scale_status_list
if vnf.get('grant'): if vnf.get('grant'):
grant = vnf['grant'] grant = vnf['grant']
ins_inf = vnf_instance.instantiated_vnf_info.vnfc_resource_info ins_inf = vnf_instance.instantiated_vnf_info.vnfc_resource_info
@ -635,8 +659,8 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
'status': rsc.resource_status} 'status': rsc.resource_status}
LOG.warning(error_reason) LOG.warning(error_reason)
raise vnfm.VNFScaleWaitFailed( raise vnfm.VNFScaleWaitFailed(
vnf_id=policy['vnf']['\ vnf_id=policy['vnf']['id'],
id'], reason=error_reason) reason=error_reason)
events = heatclient.resource_event_list( events = heatclient.resource_event_list(
stack_id, policy_name, limit=1, stack_id, policy_name, limit=1,
sort_dir='desc', sort_dir='desc',
@ -996,7 +1020,9 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
vnfc_res_info.compute_resource, pop_resources, vnfc_res_info.compute_resource, pop_resources,
vnfc_res_info.vdu_id, vim_connection_info) vnfc_res_info.vdu_id, vim_connection_info)
vnfc_res_info.metadata.update({"stack_id": stack_id}) if stack_id:
vnfc_res_info.metadata.update({"stack_id": stack_id})
_populate_virtual_storage(vnfc_res_info, pop_resources) _populate_virtual_storage(vnfc_res_info, pop_resources)
# Find out associated VLs, and CP used by vdu_id # Find out associated VLs, and CP used by vdu_id

View File

@ -197,7 +197,7 @@ class VnfPackageRequest:
for pipeline_type in cfg.CONF.connect_vnf_packages.pipeline: for pipeline_type in cfg.CONF.connect_vnf_packages.pipeline:
download_vnf_package(pipeline_type, vnf_package_zip) download_vnf_package(pipeline_type, vnf_package_zip)
zip_buffer.seek(0) zip_buffer.seek(0)
return zip_buffer return zip_buffer
@classmethod @classmethod