support change_ext_conn v2 API
This patch implements change external VNF connectivity task defined in ETSI NFV-SOL003 v3.3.1 5.4.11. Functional tests will be provided with another patch. Implements: blueprint support-nfv-solv3-change-external-connectivity Change-Id: I3da41d31d79521907fc929497db327176d8ea8eb
This commit is contained in:
6
releasenotes/notes/add-v2-change_ext_conn-api-1fe3ca0e889eea93.yaml
Executable file
6
releasenotes/notes/add-v2-change_ext_conn-api-1fe3ca0e889eea93.yaml
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add the Version "2.0.0" of
|
||||||
|
Change external VNF connectivity API
|
||||||
|
based on ETSI NFV specifications.
|
@@ -111,6 +111,15 @@ rules = [
|
|||||||
'path': VNF_INSTANCES_ID_PATH + '/scale'}
|
'path': VNF_INSTANCES_ID_PATH + '/scale'}
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_NAME.format('change_ext_conn'),
|
||||||
|
check_str=RULE_ANY,
|
||||||
|
description="Change external vnf connectivity.",
|
||||||
|
operations=[
|
||||||
|
{'method': 'POST',
|
||||||
|
'path': VNF_INSTANCES_ID_PATH + '/change_ext_conn'}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
|
||||||
# TODO(oda-g): add more lcm operations etc when implemented.
|
# TODO(oda-g): add more lcm operations etc when implemented.
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@ class VnflcmAPIRouterV2(sol_wsgi.SolAPIRouter):
|
|||||||
("/vnf_instances/{id}/heal", {"POST": "heal"}),
|
("/vnf_instances/{id}/heal", {"POST": "heal"}),
|
||||||
("/vnf_instances/{id}/terminate", {"POST": "terminate"}),
|
("/vnf_instances/{id}/terminate", {"POST": "terminate"}),
|
||||||
("/vnf_instances/{id}/scale", {"POST": "scale"}),
|
("/vnf_instances/{id}/scale", {"POST": "scale"}),
|
||||||
|
("/vnf_instances/{id}/change_ext_conn", {"POST": "change_ext_conn"}),
|
||||||
("/api_versions", {"GET": "api_versions"}),
|
("/api_versions", {"GET": "api_versions"}),
|
||||||
("/subscriptions", {"GET": "subscription_list",
|
("/subscriptions", {"GET": "subscription_list",
|
||||||
"POST": "subscription_create"}),
|
"POST": "subscription_create"}),
|
||||||
|
@@ -93,6 +93,26 @@ ScaleVnfRequest_V200 = {
|
|||||||
'additionalProperties': True,
|
'additionalProperties': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# SOL003 5.5.2.11
|
||||||
|
ChangeExtVnfConnectivityRequest_V200 = {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'extVirtualLinks': {
|
||||||
|
'type': 'array',
|
||||||
|
'items': common_types.ExtVirtualLinkData
|
||||||
|
},
|
||||||
|
'vimConnectionInfo': {
|
||||||
|
'type': 'object',
|
||||||
|
'patternProperties': {
|
||||||
|
'^.*$': common_types.VimConnectionInfo
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'additionalParams': parameter_types.keyvalue_pairs,
|
||||||
|
},
|
||||||
|
'required': ['extVirtualLinks'],
|
||||||
|
'additionalProperties': True,
|
||||||
|
}
|
||||||
|
|
||||||
# SOL013 8.3.4
|
# SOL013 8.3.4
|
||||||
_SubscriptionAuthentication = {
|
_SubscriptionAuthentication = {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
|
@@ -329,7 +329,8 @@ def _change_vnf_info(lcmocc, inst_saved, inst):
|
|||||||
def update_lcmocc(lcmocc, inst_saved, inst):
|
def update_lcmocc(lcmocc, inst_saved, inst):
|
||||||
# if operation is MODIFY_INFO, make changedInfo of lcmocc.
|
# if operation is MODIFY_INFO, make changedInfo of lcmocc.
|
||||||
# for other operations, make ResourceChanges of lcmocc
|
# for other operations, make ResourceChanges of lcmocc
|
||||||
# from instantiatedVnfInfo.
|
# from instantiatedVnfInfo. In addition if operation is
|
||||||
|
# CHANGE_EXT_CONN, make changedExtConnectivity of lcmocc.
|
||||||
# NOTE: grant related info such as resourceDefinitionId, zoneId
|
# NOTE: grant related info such as resourceDefinitionId, zoneId
|
||||||
# and so on are not included in lcmocc since such info are not
|
# and so on are not included in lcmocc since such info are not
|
||||||
# included in instantiatedVnfInfo.
|
# included in instantiatedVnfInfo.
|
||||||
@@ -431,6 +432,53 @@ def update_lcmocc(lcmocc, inst_saved, inst):
|
|||||||
change_info.affectedExtLinkPorts = affected_ext_link_ports
|
change_info.affectedExtLinkPorts = affected_ext_link_ports
|
||||||
lcmocc.resourceChanges = change_info
|
lcmocc.resourceChanges = change_info
|
||||||
|
|
||||||
|
if lcmocc.operation == fields.LcmOperationType.CHANGE_EXT_CONN:
|
||||||
|
_, added_ext_vls, common_ext_vls = _calc_diff('extVirtualLinkInfo')
|
||||||
|
|
||||||
|
def _get_ext_vl(vl_id, vl_array):
|
||||||
|
for vl in vl_array:
|
||||||
|
if vl.id == vl_id:
|
||||||
|
return vl
|
||||||
|
|
||||||
|
chg_ext_conn = [_get_ext_vl(ext_vl_id, inst_info.extVirtualLinkInfo)
|
||||||
|
for ext_vl_id in added_ext_vls]
|
||||||
|
|
||||||
|
for ext_vl_id in common_ext_vls:
|
||||||
|
ext_vl = _get_ext_vl(ext_vl_id, inst_info.extVirtualLinkInfo)
|
||||||
|
ext_vl_saved = _get_ext_vl(ext_vl_id,
|
||||||
|
inst_info_saved.extVirtualLinkInfo)
|
||||||
|
cp_data = []
|
||||||
|
if ext_vl.obj_attr_is_set('currentVnfExtCpData'):
|
||||||
|
cp_data = sorted(ext_vl.to_dict()['currentVnfExtCpData'],
|
||||||
|
key=lambda x: x['cpdId'])
|
||||||
|
cp_data_saved = []
|
||||||
|
if ext_vl_saved.obj_attr_is_set('currentVnfExtCpData'):
|
||||||
|
cp_data_saved = sorted(
|
||||||
|
ext_vl_saved.to_dict()['currentVnfExtCpData'],
|
||||||
|
key=lambda x: x['cpdId'])
|
||||||
|
if cp_data != cp_data_saved:
|
||||||
|
chg_ext_conn.append(ext_vl)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# NOTE: For ports created by the heat, the id is not changed if
|
||||||
|
# its resourceId is not changed. But for ports given outside the
|
||||||
|
# heat, the resourceId may be changed without changing the id,
|
||||||
|
# so it is a policy to set changedExtConnectivity when there is
|
||||||
|
# a change in "id" or "resourceHandle.resourceId".
|
||||||
|
port_ids = set()
|
||||||
|
if ext_vl.obj_attr_is_set('extLinkPorts'):
|
||||||
|
port_ids = {(port.id, port.resourceHandle.resourceId)
|
||||||
|
for port in ext_vl.extLinkPorts}
|
||||||
|
port_ids_saved = set()
|
||||||
|
if ext_vl_saved.obj_attr_is_set('extLinkPorts'):
|
||||||
|
port_ids_saved = {(port.id, port.resourceHandle.resourceId)
|
||||||
|
for port in ext_vl_saved.extLinkPorts}
|
||||||
|
if port_ids != port_ids_saved:
|
||||||
|
chg_ext_conn.append(ext_vl)
|
||||||
|
|
||||||
|
if chg_ext_conn:
|
||||||
|
lcmocc.changedExtConnectivity = chg_ext_conn
|
||||||
|
|
||||||
|
|
||||||
def get_grant_req_and_grant(context, lcmocc):
|
def get_grant_req_and_grant(context, lcmocc):
|
||||||
if lcmocc.operation == fields.LcmOperationType.MODIFY_INFO:
|
if lcmocc.operation == fields.LcmOperationType.MODIFY_INFO:
|
||||||
|
@@ -47,10 +47,9 @@ def make_inst_links(inst, endpoint):
|
|||||||
else: # 'INSTANTIATED'
|
else: # 'INSTANTIATED'
|
||||||
links.terminate = objects.Link(href=self_href + "/terminate")
|
links.terminate = objects.Link(href=self_href + "/terminate")
|
||||||
links.scale = objects.Link(href=self_href + "/scale")
|
links.scale = objects.Link(href=self_href + "/scale")
|
||||||
|
links.changeExtConn = objects.Link(href=self_href + "/change_ext_conn")
|
||||||
# TODO(oda-g): add when the operation supported
|
# TODO(oda-g): add when the operation supported
|
||||||
# links.heal = objects.Link(href=self_href + "/heal")
|
# links.heal = objects.Link(href=self_href + "/heal")
|
||||||
# links.changeExtConn = objects.Link(
|
|
||||||
# href=self_href + "/change_ext_conn")
|
|
||||||
# etc.
|
# etc.
|
||||||
|
|
||||||
return links
|
return links
|
||||||
|
@@ -215,11 +215,12 @@ class ConductorV2(object):
|
|||||||
|
|
||||||
lcmocc.operationState = fields.LcmOperationStateType.ROLLED_BACK
|
lcmocc.operationState = fields.LcmOperationStateType.ROLLED_BACK
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
# it is not necessary to update inst DB because it was not
|
|
||||||
# changed when the operationState became FAILED_TEMP.
|
|
||||||
# NOTE: inst object may be changed in driver's rollback
|
|
||||||
# method temporary but must not save it.
|
|
||||||
lcmocc.update(context)
|
lcmocc.update(context)
|
||||||
|
# NOTE: Basically inst is not changed. But there is a case
|
||||||
|
# that VIM resources may be changed while rollback. Only
|
||||||
|
# change_ext_conn_rollback at the moment.
|
||||||
|
if lcmocc.operation == fields.LcmOperationType.CHANGE_EXT_CONN:
|
||||||
|
inst.update(context)
|
||||||
# grant_req and grant are not necessary any more.
|
# grant_req and grant are not necessary any more.
|
||||||
if grant_req is not None:
|
if grant_req is not None:
|
||||||
grant_req.delete(context)
|
grant_req.delete(context)
|
||||||
|
@@ -36,6 +36,11 @@ LOG = logging.getLogger(__name__)
|
|||||||
CONF = config.CONF
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
|
# sub method for making id
|
||||||
|
def _make_combination_id(a, b):
|
||||||
|
return '{}-{}'.format(a, b)
|
||||||
|
|
||||||
|
|
||||||
class VnfLcmDriverV2(object):
|
class VnfLcmDriverV2(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -256,7 +261,7 @@ class VnfLcmDriverV2(object):
|
|||||||
for cp_name in cp_names:
|
for cp_name in cp_names:
|
||||||
add_reses.append(
|
add_reses.append(
|
||||||
objects.ResourceDefinitionV1(
|
objects.ResourceDefinitionV1(
|
||||||
id="{}-{}".format(cp_name, vdu_res_id),
|
id=_make_combination_id(cp_name, vdu_res_id),
|
||||||
type='LINKPORT',
|
type='LINKPORT',
|
||||||
resourceTemplateId=cp_name
|
resourceTemplateId=cp_name
|
||||||
)
|
)
|
||||||
@@ -264,7 +269,7 @@ class VnfLcmDriverV2(object):
|
|||||||
for storage_name in storage_names:
|
for storage_name in storage_names:
|
||||||
add_reses.append(
|
add_reses.append(
|
||||||
objects.ResourceDefinitionV1(
|
objects.ResourceDefinitionV1(
|
||||||
id="{}-{}".format(storage_name, vdu_res_id),
|
id=_make_combination_id(storage_name, vdu_res_id),
|
||||||
type='STORAGE',
|
type='STORAGE',
|
||||||
resourceTemplateId=storage_name
|
resourceTemplateId=storage_name
|
||||||
)
|
)
|
||||||
@@ -427,7 +432,7 @@ class VnfLcmDriverV2(object):
|
|||||||
# deleted.
|
# deleted.
|
||||||
continue
|
continue
|
||||||
res_def = objects.ResourceDefinitionV1(
|
res_def = objects.ResourceDefinitionV1(
|
||||||
id="{}-{}".format(cp_info.cpdId, vdu_res_id),
|
id=_make_combination_id(cp_info.cpdId, vdu_res_id),
|
||||||
resourceTemplateId=cp_info.cpdId,
|
resourceTemplateId=cp_info.cpdId,
|
||||||
type='LINKPORT')
|
type='LINKPORT')
|
||||||
rm_reses.append(res_def)
|
rm_reses.append(res_def)
|
||||||
@@ -443,7 +448,8 @@ class VnfLcmDriverV2(object):
|
|||||||
str_name = inst_str.virtualStorageDescId
|
str_name = inst_str.virtualStorageDescId
|
||||||
rm_reses.append(
|
rm_reses.append(
|
||||||
objects.ResourceDefinitionV1(
|
objects.ResourceDefinitionV1(
|
||||||
id="{}-{}".format(str_name, vdu_res_id),
|
id=_make_combination_id(str_name,
|
||||||
|
vdu_res_id),
|
||||||
type='STORAGE',
|
type='STORAGE',
|
||||||
resourceTemplateId=str_name,
|
resourceTemplateId=str_name,
|
||||||
resource=inst_str.storageResource
|
resource=inst_str.storageResource
|
||||||
@@ -650,6 +656,17 @@ class VnfLcmDriverV2(object):
|
|||||||
setattr(inst, attr, inst_utils.json_merge_patch(
|
setattr(inst, attr, inst_utils.json_merge_patch(
|
||||||
base, getattr(req, attr)))
|
base, getattr(req, attr)))
|
||||||
|
|
||||||
|
def _merge_vim_connection_info(self, inst, req):
|
||||||
|
# used by MODIFY_INFO and CHANGE_EXT_CONN
|
||||||
|
# inst.vimConnectionInfo exists since req.vimConnectionInfo
|
||||||
|
# can be set only if vnf instance is INSTANTIATED.
|
||||||
|
inst_viminfo = inst.to_dict()['vimConnectionInfo']
|
||||||
|
req_viminfo = req.to_dict()['vimConnectionInfo']
|
||||||
|
merge = inst_utils.json_merge_patch(inst_viminfo, req_viminfo)
|
||||||
|
inst.vimConnectionInfo = {
|
||||||
|
key: objects.VimConnectionInfo.from_dict(value)
|
||||||
|
for key, value in merge.items()}
|
||||||
|
|
||||||
def modify_info_process(self, context, lcmocc, inst, grant_req,
|
def modify_info_process(self, context, lcmocc, inst, grant_req,
|
||||||
grant, vnfd):
|
grant, vnfd):
|
||||||
req = lcmocc.operationParams
|
req = lcmocc.operationParams
|
||||||
@@ -685,14 +702,7 @@ class VnfLcmDriverV2(object):
|
|||||||
self._modify_from_req(inst, req, attr)
|
self._modify_from_req(inst, req, attr)
|
||||||
|
|
||||||
if req.obj_attr_is_set('vimConnectionInfo'):
|
if req.obj_attr_is_set('vimConnectionInfo'):
|
||||||
# inst.vimConnectionInfo exists since req.vimConnectionInfo
|
self._merge_vim_connection_info(inst, req)
|
||||||
# can be set only if vnf instance is INSTANTIATED.
|
|
||||||
inst_viminfo = inst.to_dict()['vimConnectionInfo']
|
|
||||||
req_viminfo = req.to_dict()['vimConnectionInfo']
|
|
||||||
merge = inst_utils.json_merge_patch(inst_viminfo, req_viminfo)
|
|
||||||
inst.vimConnectionInfo = {
|
|
||||||
key: objects.VimConnectionInfo.from_dict(value)
|
|
||||||
for key, value in merge.items()}
|
|
||||||
|
|
||||||
if req.obj_attr_is_set('vnfcInfoModifications'):
|
if req.obj_attr_is_set('vnfcInfoModifications'):
|
||||||
for vnfc_mod in req.vnfcInfoModifications:
|
for vnfc_mod in req.vnfcInfoModifications:
|
||||||
@@ -712,3 +722,106 @@ class VnfLcmDriverV2(object):
|
|||||||
grant, vnfd):
|
grant, vnfd):
|
||||||
# DB is not updated, rollback does nothing and makes it successful.
|
# DB is not updated, rollback does nothing and makes it successful.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def change_ext_conn_grant(self, grant_req, req, inst, vnfd):
|
||||||
|
inst_info = inst.instantiatedVnfInfo
|
||||||
|
|
||||||
|
cp_names = set()
|
||||||
|
link_ports = set()
|
||||||
|
for ext_vl in req.extVirtualLinks:
|
||||||
|
for ext_cp in ext_vl.extCps:
|
||||||
|
cp_names.add(ext_cp.cpdId)
|
||||||
|
for cp_config in ext_cp.cpConfig.values():
|
||||||
|
if cp_config.obj_attr_is_set('linkPortId'):
|
||||||
|
link_ports.add(ext_cp.cpdId)
|
||||||
|
|
||||||
|
add_reses = []
|
||||||
|
rm_reses = []
|
||||||
|
update_reses = []
|
||||||
|
rm_vnfc_cps = {}
|
||||||
|
for inst_vnfc in inst_info.vnfcResourceInfo:
|
||||||
|
if not inst_vnfc.obj_attr_is_set('vnfcCpInfo'):
|
||||||
|
continue
|
||||||
|
vnfc_cps = {cp_info.cpdId for cp_info in inst_vnfc.vnfcCpInfo}
|
||||||
|
if not vnfc_cps & cp_names:
|
||||||
|
continue
|
||||||
|
|
||||||
|
old_vdu_res_id = uuidutils.generate_uuid()
|
||||||
|
new_vdu_res_id = uuidutils.generate_uuid()
|
||||||
|
update_reses.append(
|
||||||
|
objects.ResourceDefinitionV1(
|
||||||
|
id=new_vdu_res_id,
|
||||||
|
type='COMPUTE',
|
||||||
|
resourceTemplateId=inst_vnfc.vduId,
|
||||||
|
resource=inst_vnfc.computeResource
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for cp_info in inst_vnfc.vnfcCpInfo:
|
||||||
|
if cp_info.cpdId not in cp_names:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if cp_info.obj_attr_is_set('vnfExtCpId'):
|
||||||
|
# if there is not vnfExtCpId, it means extLinkPorts of
|
||||||
|
# extVirtualLinks was specified.
|
||||||
|
res_def = objects.ResourceDefinitionV1(
|
||||||
|
id=_make_combination_id(cp_info.cpdId, old_vdu_res_id),
|
||||||
|
resourceTemplateId=cp_info.cpdId,
|
||||||
|
type='LINKPORT')
|
||||||
|
rm_reses.append(res_def)
|
||||||
|
rm_vnfc_cps[cp_info.vnfExtCpId] = res_def
|
||||||
|
|
||||||
|
if cp_info.cpdId not in link_ports:
|
||||||
|
add_reses.append(
|
||||||
|
objects.ResourceDefinitionV1(
|
||||||
|
id=_make_combination_id(cp_info.cpdId,
|
||||||
|
new_vdu_res_id),
|
||||||
|
resourceTemplateId=cp_info.cpdId,
|
||||||
|
type='LINKPORT'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# fill resourceHandle of rm_reses
|
||||||
|
if inst_info.obj_attr_is_set('extVirtualLinkInfo'):
|
||||||
|
for ext_vl in inst_info.extVirtualLinkInfo:
|
||||||
|
if ext_vl.obj_attr_is_set('extLinkPorts'):
|
||||||
|
for port in ext_vl.extLinkPorts:
|
||||||
|
if (port.obj_attr_is_set('cpInstanceId') and
|
||||||
|
port.cpInstanceId in rm_vnfc_cps):
|
||||||
|
res_def = rm_vnfc_cps[port.cpInstanceId]
|
||||||
|
res_def.resource = port.resourceHandle
|
||||||
|
|
||||||
|
if add_reses:
|
||||||
|
grant_req.addResources = add_reses
|
||||||
|
if rm_reses:
|
||||||
|
grant_req.removeResources = rm_reses
|
||||||
|
if update_reses:
|
||||||
|
grant_req.updateResources = update_reses
|
||||||
|
|
||||||
|
if req.obj_attr_is_set('additionalParams'):
|
||||||
|
grant_req.additionalParams = req.additionalParams
|
||||||
|
|
||||||
|
def change_ext_conn_process(self, context, lcmocc, inst, grant_req,
|
||||||
|
grant, vnfd):
|
||||||
|
req = lcmocc.operationParams
|
||||||
|
if req.obj_attr_is_set('vimConnectionInfo'):
|
||||||
|
self._merge_vim_connection_info(inst, req)
|
||||||
|
|
||||||
|
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||||
|
if vim_info.vimType == 'ETSINFV.OPENSTACK_KEYSTONE.V_3':
|
||||||
|
driver = openstack.Openstack()
|
||||||
|
driver.change_ext_conn(req, inst, grant_req, grant, vnfd)
|
||||||
|
else:
|
||||||
|
# only support openstack at the moment
|
||||||
|
raise sol_ex.SolException(sol_detail='not support vim type')
|
||||||
|
|
||||||
|
def change_ext_conn_rollback(self, context, lcmocc, inst, grant_req,
|
||||||
|
grant, vnfd):
|
||||||
|
req = lcmocc.operationParams
|
||||||
|
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||||
|
if vim_info.vimType == 'ETSINFV.OPENSTACK_KEYSTONE.V_3':
|
||||||
|
driver = openstack.Openstack()
|
||||||
|
driver.change_ext_conn_rollback(req, inst, grant_req, grant, vnfd)
|
||||||
|
else:
|
||||||
|
# only support openstack at the moment
|
||||||
|
raise sol_ex.SolException(sol_detail='not support vim type')
|
||||||
|
@@ -321,6 +321,27 @@ class VnfLcmControllerV2(sol_wsgi.SolAPIController):
|
|||||||
|
|
||||||
return sol_wsgi.SolResponse(202, None, location=location)
|
return sol_wsgi.SolResponse(202, None, location=location)
|
||||||
|
|
||||||
|
@validator.schema(schema.ChangeExtVnfConnectivityRequest_V200, '2.0.0')
|
||||||
|
@coordinate.lock_vnf_instance('{id}')
|
||||||
|
def change_ext_conn(self, request, id, body):
|
||||||
|
context = request.context
|
||||||
|
inst = inst_utils.get_inst(context, id)
|
||||||
|
|
||||||
|
if inst.instantiationState != 'INSTANTIATED':
|
||||||
|
raise sol_ex.VnfInstanceIsNotInstantiated(inst_id=id)
|
||||||
|
|
||||||
|
lcmocc_utils.check_lcmocc_in_progress(context, id)
|
||||||
|
|
||||||
|
lcmocc = self._new_lcmocc(
|
||||||
|
id, v2fields.LcmOperationType.CHANGE_EXT_CONN, body)
|
||||||
|
lcmocc.create(context)
|
||||||
|
|
||||||
|
self.conductor_rpc.start_lcm_op(context, lcmocc.id)
|
||||||
|
|
||||||
|
location = lcmocc_utils.lcmocc_href(lcmocc.id, self.endpoint)
|
||||||
|
|
||||||
|
return sol_wsgi.SolResponse(202, None, location=location)
|
||||||
|
|
||||||
@validator.schema(schema.LccnSubscriptionRequest_V200, '2.0.0')
|
@validator.schema(schema.LccnSubscriptionRequest_V200, '2.0.0')
|
||||||
def subscription_create(self, request, body):
|
def subscription_create(self, request, body):
|
||||||
context = request.context
|
context = request.context
|
||||||
|
@@ -73,16 +73,15 @@ class Openstack(object):
|
|||||||
def instantiate(self, req, inst, grant_req, grant, vnfd):
|
def instantiate(self, req, inst, grant_req, grant, vnfd):
|
||||||
# make HOT
|
# make HOT
|
||||||
fields = self._make_hot(req, inst, grant_req, grant, vnfd)
|
fields = self._make_hot(req, inst, grant_req, grant, vnfd)
|
||||||
|
|
||||||
LOG.debug("stack fields: %s", fields)
|
LOG.debug("stack fields: %s", fields)
|
||||||
|
|
||||||
stack_name = fields['stack_name']
|
|
||||||
|
|
||||||
# create or update stack
|
# create or update stack
|
||||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||||
heat_client = heat_utils.HeatClient(vim_info)
|
heat_client = heat_utils.HeatClient(vim_info)
|
||||||
|
stack_name = heat_utils.get_stack_name(inst)
|
||||||
status, _ = heat_client.get_status(stack_name)
|
status, _ = heat_client.get_status(stack_name)
|
||||||
if status is None:
|
if status is None:
|
||||||
|
fields['stack_name'] = stack_name
|
||||||
heat_client.create_stack(fields)
|
heat_client.create_stack(fields)
|
||||||
else:
|
else:
|
||||||
heat_client.update_stack(stack_name, fields)
|
heat_client.update_stack(stack_name, fields)
|
||||||
@@ -127,15 +126,12 @@ class Openstack(object):
|
|||||||
return fields
|
return fields
|
||||||
|
|
||||||
def scale(self, req, inst, grant_req, grant, vnfd):
|
def scale(self, req, inst, grant_req, grant, vnfd):
|
||||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
|
||||||
heat_client = heat_utils.HeatClient(vim_info)
|
|
||||||
|
|
||||||
# make HOT
|
# make HOT
|
||||||
fields = self._make_hot(req, inst, grant_req, grant, vnfd)
|
fields = self._make_hot(req, inst, grant_req, grant, vnfd)
|
||||||
|
|
||||||
LOG.debug("stack fields: %s", fields)
|
LOG.debug("stack fields: %s", fields)
|
||||||
|
|
||||||
stack_name = fields.pop('stack_name')
|
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||||
|
heat_client = heat_utils.HeatClient(vim_info)
|
||||||
|
|
||||||
# mark unhealthy to servers to be removed if scale in
|
# mark unhealthy to servers to be removed if scale in
|
||||||
if req.type == 'SCALE_IN':
|
if req.type == 'SCALE_IN':
|
||||||
@@ -153,6 +149,7 @@ class Openstack(object):
|
|||||||
vnfc.metadata['parent_resource_name'])
|
vnfc.metadata['parent_resource_name'])
|
||||||
|
|
||||||
# update stack
|
# update stack
|
||||||
|
stack_name = heat_utils.get_stack_name(inst)
|
||||||
fields = self._update_nfv_dict(heat_client, stack_name, fields)
|
fields = self._update_nfv_dict(heat_client, stack_name, fields)
|
||||||
heat_client.update_stack(stack_name, fields)
|
heat_client.update_stack(stack_name, fields)
|
||||||
|
|
||||||
@@ -194,6 +191,40 @@ class Openstack(object):
|
|||||||
# NOTE: instantiatedVnfInfo is not necessary to update since it
|
# NOTE: instantiatedVnfInfo is not necessary to update since it
|
||||||
# should be same as before scale API started.
|
# should be same as before scale API started.
|
||||||
|
|
||||||
|
def change_ext_conn(self, req, inst, grant_req, grant, vnfd):
|
||||||
|
# make HOT
|
||||||
|
fields = self._make_hot(req, inst, grant_req, grant, vnfd)
|
||||||
|
LOG.debug("stack fields: %s", fields)
|
||||||
|
|
||||||
|
# update stack
|
||||||
|
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||||
|
heat_client = heat_utils.HeatClient(vim_info)
|
||||||
|
stack_name = heat_utils.get_stack_name(inst)
|
||||||
|
fields = self._update_nfv_dict(heat_client, stack_name, fields)
|
||||||
|
heat_client.update_stack(stack_name, fields)
|
||||||
|
|
||||||
|
# get stack resource
|
||||||
|
heat_reses = heat_client.get_resources(stack_name)
|
||||||
|
|
||||||
|
# make instantiated_vnf_info
|
||||||
|
self._make_instantiated_vnf_info(req, inst, grant_req, grant, vnfd,
|
||||||
|
heat_reses)
|
||||||
|
|
||||||
|
def change_ext_conn_rollback(self, req, inst, grant_req, grant, vnfd):
|
||||||
|
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||||
|
heat_client = heat_utils.HeatClient(vim_info)
|
||||||
|
stack_name = heat_utils.get_stack_name(inst)
|
||||||
|
fields = self._update_nfv_dict(heat_client, stack_name,
|
||||||
|
userdata_default.DefaultUserData.change_ext_conn_rollback(
|
||||||
|
req, inst, grant_req, grant, vnfd.csar_dir))
|
||||||
|
heat_client.update_stack(stack_name, fields)
|
||||||
|
|
||||||
|
# NOTE: it is necessary to re-create instantiatedVnfInfo because
|
||||||
|
# ports may be changed.
|
||||||
|
heat_reses = heat_client.get_resources(stack_name)
|
||||||
|
self._make_instantiated_vnf_info(req, inst, grant_req, grant, vnfd,
|
||||||
|
heat_reses)
|
||||||
|
|
||||||
def _make_hot(self, req, inst, grant_req, grant, vnfd):
|
def _make_hot(self, req, inst, grant_req, grant, vnfd):
|
||||||
if grant_req.operation == v2fields.LcmOperationType.INSTANTIATE:
|
if grant_req.operation == v2fields.LcmOperationType.INSTANTIATE:
|
||||||
flavour_id = req.flavourId
|
flavour_id = req.flavourId
|
||||||
@@ -248,8 +279,6 @@ class Openstack(object):
|
|||||||
|
|
||||||
fields = pickle.loads(out.stdout)
|
fields = pickle.loads(out.stdout)
|
||||||
|
|
||||||
stack_name = heat_utils.get_stack_name(inst)
|
|
||||||
fields['stack_name'] = stack_name
|
|
||||||
fields['timeout_mins'] = (
|
fields['timeout_mins'] = (
|
||||||
CONF.v2_vnfm.openstack_vim_stack_create_timeout)
|
CONF.v2_vnfm.openstack_vim_stack_create_timeout)
|
||||||
|
|
||||||
@@ -308,35 +337,11 @@ class Openstack(object):
|
|||||||
|
|
||||||
return proto_info
|
return proto_info
|
||||||
|
|
||||||
def _make_ext_vl_info_from_req(self, req, grant, ext_cp_infos):
|
def _make_link_ports(self, req_ext_vl, ext_cp_infos):
|
||||||
# make extVirtualLinkInfo
|
|
||||||
ext_vls = []
|
|
||||||
req_ext_vls = []
|
|
||||||
if grant.obj_attr_is_set('extVirtualLinks'):
|
|
||||||
req_ext_vls = grant.extVirtualLinks
|
|
||||||
elif req.obj_attr_is_set('extVirtualLinks'):
|
|
||||||
req_ext_vls = req.extVirtualLinks
|
|
||||||
|
|
||||||
for req_ext_vl in req_ext_vls:
|
|
||||||
ext_vl = objects.ExtVirtualLinkInfoV2(
|
|
||||||
id=req_ext_vl.id,
|
|
||||||
resourceHandle=objects.ResourceHandle(
|
|
||||||
resourceId=req_ext_vl.resourceId
|
|
||||||
),
|
|
||||||
currentVnfExtCpData=req_ext_vl.extCps
|
|
||||||
)
|
|
||||||
if req_ext_vl.obj_attr_is_set('vimConnectionId'):
|
|
||||||
ext_vl.resourceHandle.vimConnectionId = (
|
|
||||||
req_ext_vl.vimConnectionId)
|
|
||||||
if req_ext_vl.obj_attr_is_set('resourceProviderId'):
|
|
||||||
ext_vl.resourceHandle.resourceProviderId = (
|
|
||||||
req_ext_vl.resourceProviderId)
|
|
||||||
|
|
||||||
ext_vls.append(ext_vl)
|
|
||||||
|
|
||||||
if not req_ext_vl.obj_attr_is_set('extLinkPorts'):
|
|
||||||
continue
|
|
||||||
link_ports = []
|
link_ports = []
|
||||||
|
if not req_ext_vl.obj_attr_is_set('extLinkPorts'):
|
||||||
|
return link_ports
|
||||||
|
|
||||||
for req_link_port in req_ext_vl.extLinkPorts:
|
for req_link_port in req_ext_vl.extLinkPorts:
|
||||||
link_port = objects.ExtLinkPortInfoV2(
|
link_port = objects.ExtLinkPortInfoV2(
|
||||||
id=_make_link_port_id(req_link_port.id),
|
id=_make_link_port_id(req_link_port.id),
|
||||||
@@ -365,9 +370,47 @@ class Openstack(object):
|
|||||||
link_ports.append(link_port)
|
link_ports.append(link_port)
|
||||||
ext_cp_infos.append(ext_cp_info)
|
ext_cp_infos.append(ext_cp_info)
|
||||||
|
|
||||||
|
return link_ports
|
||||||
|
|
||||||
|
def _make_ext_vl_from_req(self, req_ext_vl, ext_cp_infos):
|
||||||
|
ext_vl = objects.ExtVirtualLinkInfoV2(
|
||||||
|
id=req_ext_vl.id,
|
||||||
|
resourceHandle=objects.ResourceHandle(
|
||||||
|
resourceId=req_ext_vl.resourceId
|
||||||
|
),
|
||||||
|
currentVnfExtCpData=req_ext_vl.extCps
|
||||||
|
)
|
||||||
|
if req_ext_vl.obj_attr_is_set('vimConnectionId'):
|
||||||
|
ext_vl.resourceHandle.vimConnectionId = (
|
||||||
|
req_ext_vl.vimConnectionId)
|
||||||
|
if req_ext_vl.obj_attr_is_set('resourceProviderId'):
|
||||||
|
ext_vl.resourceHandle.resourceProviderId = (
|
||||||
|
req_ext_vl.resourceProviderId)
|
||||||
|
|
||||||
|
link_ports = self._make_link_ports(req_ext_vl, ext_cp_infos)
|
||||||
|
if link_ports:
|
||||||
ext_vl.extLinkPorts = link_ports
|
ext_vl.extLinkPorts = link_ports
|
||||||
|
|
||||||
return ext_vls
|
ext_vl.extLinkPorts = link_ports
|
||||||
|
|
||||||
|
return ext_vl
|
||||||
|
|
||||||
|
def _make_ext_vl_info_from_req(self, req, grant, ext_cp_infos):
|
||||||
|
# make extVirtualLinkInfo
|
||||||
|
req_ext_vls = []
|
||||||
|
if grant.obj_attr_is_set('extVirtualLinks'):
|
||||||
|
req_ext_vls = grant.extVirtualLinks
|
||||||
|
elif req.obj_attr_is_set('extVirtualLinks'):
|
||||||
|
req_ext_vls = req.extVirtualLinks
|
||||||
|
|
||||||
|
return [self._make_ext_vl_from_req(req_ext_vl, ext_cp_infos)
|
||||||
|
for req_ext_vl in req_ext_vls]
|
||||||
|
|
||||||
|
def _find_ext_cp_info(self, link_port, ext_cp_infos):
|
||||||
|
for ext_cp in ext_cp_infos:
|
||||||
|
if ext_cp.id == link_port.cpInstanceId:
|
||||||
|
return ext_cp
|
||||||
|
# never reach here
|
||||||
|
|
||||||
def _make_ext_vl_info_from_inst(self, old_inst_vnf_info, ext_cp_infos):
|
def _make_ext_vl_info_from_inst(self, old_inst_vnf_info, ext_cp_infos):
|
||||||
# make extVirtualLinkInfo from old inst.extVirtualLinkInfo
|
# make extVirtualLinkInfo from old inst.extVirtualLinkInfo
|
||||||
@@ -384,20 +427,83 @@ class Openstack(object):
|
|||||||
continue
|
continue
|
||||||
new_link_ports = []
|
new_link_ports = []
|
||||||
for link_port in ext_vl.extLinkPorts:
|
for link_port in ext_vl.extLinkPorts:
|
||||||
if not _is_link_port(link_port.id):
|
if _is_link_port(link_port.id):
|
||||||
# port created by heat. re-create later
|
|
||||||
continue
|
|
||||||
|
|
||||||
new_link_ports.append(link_port)
|
new_link_ports.append(link_port)
|
||||||
for ext_cp in old_cp_infos:
|
ext_cp_infos.append(self._find_ext_cp_info(link_port,
|
||||||
if ext_cp.id == link_port.cpInstanceId:
|
old_cp_infos))
|
||||||
ext_cp_infos.append(ext_cp)
|
|
||||||
break
|
|
||||||
|
|
||||||
ext_vl.extLinkPorts = new_link_ports
|
ext_vl.extLinkPorts = new_link_ports
|
||||||
|
|
||||||
return ext_vls
|
return ext_vls
|
||||||
|
|
||||||
|
def _make_ext_vl_info_from_req_and_inst(self, req, grant, old_inst_info,
|
||||||
|
ext_cp_infos):
|
||||||
|
req_ext_vls = []
|
||||||
|
if grant.obj_attr_is_set('extVirtualLinks'):
|
||||||
|
req_ext_vls = grant.extVirtualLinks
|
||||||
|
elif req.obj_attr_is_set('extVirtualLinks'):
|
||||||
|
req_ext_vls = req.extVirtualLinks
|
||||||
|
|
||||||
|
req_ext_vl_ids = {ext_vl.id for ext_vl in req_ext_vls}
|
||||||
|
inst_ext_vl_ids = set()
|
||||||
|
if old_inst_info.obj_attr_is_set('extVirtualLinkInfo'):
|
||||||
|
inst_ext_vl_ids = {ext_vl.id
|
||||||
|
for ext_vl in old_inst_info.extVirtualLinkInfo}
|
||||||
|
|
||||||
|
added_ext_vl_ids = req_ext_vl_ids - inst_ext_vl_ids
|
||||||
|
req_all_cp_names = {ext_cp.cpdId
|
||||||
|
for req_ext_vl in req_ext_vls
|
||||||
|
for ext_cp in req_ext_vl.extCps}
|
||||||
|
|
||||||
|
ext_vls = [self._make_ext_vl_from_req(req_ext_vl, ext_cp_infos)
|
||||||
|
for req_ext_vl in req_ext_vls
|
||||||
|
# added ext_vls
|
||||||
|
if req_ext_vl.id in added_ext_vl_ids]
|
||||||
|
|
||||||
|
old_ext_vls = []
|
||||||
|
old_cp_infos = []
|
||||||
|
if old_inst_info.obj_attr_is_set('extVirtualLinkInfo'):
|
||||||
|
old_ext_vls = old_inst_info.extVirtualLinkInfo
|
||||||
|
if old_inst_info.obj_attr_is_set('extCpInfo'):
|
||||||
|
old_cp_infos = old_inst_info.extCpInfo
|
||||||
|
|
||||||
|
for ext_vl in old_ext_vls:
|
||||||
|
old_ext_cp_data = ext_vl.currentVnfExtCpData
|
||||||
|
old_link_ports = (ext_vl.extLinkPorts
|
||||||
|
if ext_vl.obj_attr_is_set('extLinkPorts') else [])
|
||||||
|
new_ext_cp_data = []
|
||||||
|
new_link_ports = []
|
||||||
|
|
||||||
|
for ext_cp_data in old_ext_cp_data:
|
||||||
|
if ext_cp_data.cpdId not in req_all_cp_names:
|
||||||
|
new_ext_cp_data.append(ext_cp_data)
|
||||||
|
|
||||||
|
for link_port in old_link_ports:
|
||||||
|
ext_cp = self._find_ext_cp_info(link_port, old_cp_infos)
|
||||||
|
if (ext_cp.cpdId not in req_all_cp_names and
|
||||||
|
_is_link_port(link_port.id)):
|
||||||
|
new_link_ports.append(link_port)
|
||||||
|
ext_cp_infos.append(ext_cp)
|
||||||
|
|
||||||
|
def _find_req_ext_vl(ext_vl):
|
||||||
|
for req_ext_vl in req_ext_vls:
|
||||||
|
if req_ext_vl.id == ext_vl.id:
|
||||||
|
return req_ext_vl
|
||||||
|
|
||||||
|
req_ext_vl = _find_req_ext_vl(ext_vl)
|
||||||
|
if req_ext_vl is not None:
|
||||||
|
new_ext_cp_data += req_ext_vl.extCps
|
||||||
|
new_link_ports += self._make_link_ports(req_ext_vl,
|
||||||
|
ext_cp_infos)
|
||||||
|
|
||||||
|
if new_ext_cp_data:
|
||||||
|
# if it is empty, it means all cps of this ext_vl are replaced
|
||||||
|
# by another ext_vl.
|
||||||
|
ext_vl.currentVnfExtCpData = new_ext_cp_data
|
||||||
|
ext_vl.extLinkPorts = new_link_ports
|
||||||
|
ext_vls.append(ext_vl)
|
||||||
|
|
||||||
|
return ext_vls
|
||||||
|
|
||||||
def _make_ext_mgd_vl_info_from_req(self, vnfd, flavour_id, req, grant):
|
def _make_ext_mgd_vl_info_from_req(self, vnfd, flavour_id, req, grant):
|
||||||
# make extManagedVirtualLinkInfo
|
# make extManagedVirtualLinkInfo
|
||||||
ext_mgd_vls = []
|
ext_mgd_vls = []
|
||||||
@@ -557,9 +663,8 @@ class Openstack(object):
|
|||||||
|
|
||||||
def _make_instantiated_vnf_info(self, req, inst, grant_req, grant, vnfd,
|
def _make_instantiated_vnf_info(self, req, inst, grant_req, grant, vnfd,
|
||||||
heat_reses):
|
heat_reses):
|
||||||
init = False
|
op = grant_req.operation
|
||||||
if grant_req.operation == v2fields.LcmOperationType.INSTANTIATE:
|
if op == v2fields.LcmOperationType.INSTANTIATE:
|
||||||
init = True
|
|
||||||
flavour_id = req.flavourId
|
flavour_id = req.flavourId
|
||||||
else:
|
else:
|
||||||
flavour_id = inst.instantiatedVnfInfo.flavourId
|
flavour_id = inst.instantiatedVnfInfo.flavourId
|
||||||
@@ -636,13 +741,17 @@ class Openstack(object):
|
|||||||
]
|
]
|
||||||
|
|
||||||
ext_cp_infos = []
|
ext_cp_infos = []
|
||||||
if init:
|
if op == v2fields.LcmOperationType.INSTANTIATE:
|
||||||
ext_vl_infos = self._make_ext_vl_info_from_req(
|
ext_vl_infos = self._make_ext_vl_info_from_req(
|
||||||
req, grant, ext_cp_infos)
|
req, grant, ext_cp_infos)
|
||||||
ext_mgd_vl_infos = self._make_ext_mgd_vl_info_from_req(vnfd,
|
ext_mgd_vl_infos = self._make_ext_mgd_vl_info_from_req(vnfd,
|
||||||
flavour_id, req, grant)
|
flavour_id, req, grant)
|
||||||
else:
|
else:
|
||||||
old_inst_vnf_info = inst.instantiatedVnfInfo
|
old_inst_vnf_info = inst.instantiatedVnfInfo
|
||||||
|
if op == v2fields.LcmOperationType.CHANGE_EXT_CONN:
|
||||||
|
ext_vl_infos = self._make_ext_vl_info_from_req_and_inst(
|
||||||
|
req, grant, old_inst_vnf_info, ext_cp_infos)
|
||||||
|
else:
|
||||||
ext_vl_infos = self._make_ext_vl_info_from_inst(
|
ext_vl_infos = self._make_ext_vl_info_from_inst(
|
||||||
old_inst_vnf_info, ext_cp_infos)
|
old_inst_vnf_info, ext_cp_infos)
|
||||||
ext_mgd_vl_infos = self._make_ext_mgd_vl_info_from_inst(
|
ext_mgd_vl_infos = self._make_ext_mgd_vl_info_from_inst(
|
||||||
@@ -701,7 +810,7 @@ class Openstack(object):
|
|||||||
# because the association of compute resource and port resource
|
# because the association of compute resource and port resource
|
||||||
# is not identified.
|
# is not identified.
|
||||||
|
|
||||||
# make new instatiatedVnfInfo and replace
|
# make new instantiatedVnfInfo and replace
|
||||||
inst_vnf_info = objects.VnfInstanceV2_InstantiatedVnfInfo(
|
inst_vnf_info = objects.VnfInstanceV2_InstantiatedVnfInfo(
|
||||||
flavourId=flavour_id,
|
flavourId=flavour_id,
|
||||||
vnfState='STARTED',
|
vnfState='STARTED',
|
||||||
|
@@ -144,3 +144,97 @@ class DefaultUserData(userdata_utils.AbstractUserData):
|
|||||||
fields = {'parameters': {'nfv': {'VDU': new_vdus}}}
|
fields = {'parameters': {'nfv': {'VDU': new_vdus}}}
|
||||||
|
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def change_ext_conn(req, inst, grant_req, grant, tmp_csar_dir):
|
||||||
|
# change_ext_conn is interested in 'CP' only.
|
||||||
|
# This method returns only 'CP' part in the 'nfv' dict from
|
||||||
|
# ChangeExtVnfConnectivityRequest.
|
||||||
|
# It is applied to json merge patch against the existing 'nfv'
|
||||||
|
# dict by the caller.
|
||||||
|
# NOTE: complete 'nfv' dict can not be made at the moment
|
||||||
|
# since InstantiateVnfRequest is necessary to make it.
|
||||||
|
|
||||||
|
vnfd = userdata_utils.get_vnfd(inst['vnfdId'], tmp_csar_dir)
|
||||||
|
flavour_id = inst['instantiatedVnfInfo']['flavourId']
|
||||||
|
|
||||||
|
hot_dict = vnfd.get_base_hot(flavour_id)
|
||||||
|
top_hot = hot_dict['template']
|
||||||
|
|
||||||
|
nfv_dict = userdata_utils.init_nfv_dict(top_hot)
|
||||||
|
|
||||||
|
cps = nfv_dict.get('CP', {})
|
||||||
|
new_cps = {}
|
||||||
|
for cp_name, cp_value in cps.items():
|
||||||
|
if 'network' in cp_value:
|
||||||
|
network = userdata_utils.get_param_network(cp_name, grant, req)
|
||||||
|
if network is None:
|
||||||
|
continue
|
||||||
|
new_cps.setdefault(cp_name, {})
|
||||||
|
new_cps[cp_name]['network'] = network
|
||||||
|
if 'fixed_ips' in cp_value:
|
||||||
|
ext_fixed_ips = userdata_utils.get_param_fixed_ips(
|
||||||
|
cp_name, grant, req)
|
||||||
|
fixed_ips = []
|
||||||
|
for i in range(len(ext_fixed_ips)):
|
||||||
|
if i not in cp_value['fixed_ips']:
|
||||||
|
break
|
||||||
|
ips_i = cp_value['fixed_ips'][i]
|
||||||
|
if 'subnet' in ips_i:
|
||||||
|
ips_i['subnet'] = ext_fixed_ips[i].get('subnet')
|
||||||
|
if 'ip_address' in ips_i:
|
||||||
|
ips_i['ip_address'] = ext_fixed_ips[i].get(
|
||||||
|
'ip_address')
|
||||||
|
fixed_ips.append(ips_i)
|
||||||
|
new_cps.setdefault(cp_name, {})
|
||||||
|
new_cps[cp_name]['fixed_ips'] = fixed_ips
|
||||||
|
|
||||||
|
fields = {'parameters': {'nfv': {'CP': new_cps}}}
|
||||||
|
|
||||||
|
return fields
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def change_ext_conn_rollback(req, inst, grant_req, grant, tmp_csar_dir):
|
||||||
|
# NOTE: This method is not called by a userdata script but
|
||||||
|
# is called by the openstack infra_driver directly now.
|
||||||
|
# It is thought that it is suitable that this method defines
|
||||||
|
# here since it is very likely to scale method above.
|
||||||
|
|
||||||
|
vnfd = userdata_utils.get_vnfd(inst['vnfdId'], tmp_csar_dir)
|
||||||
|
flavour_id = inst['instantiatedVnfInfo']['flavourId']
|
||||||
|
|
||||||
|
hot_dict = vnfd.get_base_hot(flavour_id)
|
||||||
|
top_hot = hot_dict['template']
|
||||||
|
|
||||||
|
nfv_dict = userdata_utils.init_nfv_dict(top_hot)
|
||||||
|
|
||||||
|
cps = nfv_dict.get('CP', {})
|
||||||
|
new_cps = {}
|
||||||
|
for cp_name, cp_value in cps.items():
|
||||||
|
if 'network' in cp_value:
|
||||||
|
network = userdata_utils.get_param_network_from_inst(
|
||||||
|
cp_name, inst)
|
||||||
|
if network is None:
|
||||||
|
continue
|
||||||
|
new_cps.setdefault(cp_name, {})
|
||||||
|
new_cps[cp_name]['network'] = network
|
||||||
|
if 'fixed_ips' in cp_value:
|
||||||
|
ext_fixed_ips = userdata_utils.get_param_fixed_ips_from_inst(
|
||||||
|
cp_name, inst)
|
||||||
|
fixed_ips = []
|
||||||
|
for i in range(len(ext_fixed_ips)):
|
||||||
|
if i not in cp_value['fixed_ips']:
|
||||||
|
break
|
||||||
|
ips_i = cp_value['fixed_ips'][i]
|
||||||
|
if 'subnet' in ips_i:
|
||||||
|
ips_i['subnet'] = ext_fixed_ips[i].get('subnet')
|
||||||
|
if 'ip_address' in ips_i:
|
||||||
|
ips_i['ip_address'] = ext_fixed_ips[i].get(
|
||||||
|
'ip_address')
|
||||||
|
fixed_ips.append(ips_i)
|
||||||
|
new_cps.setdefault(cp_name, {})
|
||||||
|
new_cps[cp_name]['fixed_ips'] = fixed_ips
|
||||||
|
|
||||||
|
fields = {'parameters': {'nfv': {'CP': new_cps}}}
|
||||||
|
|
||||||
|
return fields
|
||||||
|
@@ -45,6 +45,11 @@ class AbstractUserData(metaclass=abc.ABCMeta):
|
|||||||
def scale(req, inst, grant_req, grant, tmp_csar_dir):
|
def scale(req, inst, grant_req, grant, tmp_csar_dir):
|
||||||
raise sol_ex.UserDataClassNotImplemented()
|
raise sol_ex.UserDataClassNotImplemented()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@abc.abstractmethod
|
||||||
|
def change_ext_conn(req, inst, grant_req, grant, tmp_csar_dir):
|
||||||
|
raise sol_ex.UserDataClassNotImplemented()
|
||||||
|
|
||||||
|
|
||||||
def get_vnfd(vnfd_id, csar_dir):
|
def get_vnfd(vnfd_id, csar_dir):
|
||||||
vnfd = vnfd_utils.Vnfd(vnfd_id)
|
vnfd = vnfd_utils.Vnfd(vnfd_id)
|
||||||
@@ -210,6 +215,20 @@ def get_param_fixed_ips(cp_name, grant, req):
|
|||||||
return _get_fixed_ips_from_extcp(extcp)
|
return _get_fixed_ips_from_extcp(extcp)
|
||||||
|
|
||||||
|
|
||||||
|
def get_param_network_from_inst(cp_name, inst):
|
||||||
|
for vl in inst['instantiatedVnfInfo'].get('extVirtualLinkInfo', []):
|
||||||
|
for extcp in vl.get('currentVnfExtCpData', []):
|
||||||
|
if extcp['cpdId'] == cp_name:
|
||||||
|
return vl['resourceHandle']['resourceId']
|
||||||
|
|
||||||
|
|
||||||
|
def get_param_fixed_ips_from_inst(cp_name, inst):
|
||||||
|
for vl in inst['instantiatedVnfInfo'].get('extVirtualLinkInfo', []):
|
||||||
|
for extcp in vl.get('currentVnfExtCpData', []):
|
||||||
|
if extcp['cpdId'] == cp_name:
|
||||||
|
return _get_fixed_ips_from_extcp(extcp)
|
||||||
|
|
||||||
|
|
||||||
def apply_ext_managed_vls(hot_dict, req, grant):
|
def apply_ext_managed_vls(hot_dict, req, grant):
|
||||||
# see grant first then instantiateVnfRequest
|
# see grant first then instantiateVnfRequest
|
||||||
mgd_vls = (grant.get('extManagedVirtualLinks', []) +
|
mgd_vls = (grant.get('extManagedVirtualLinks', []) +
|
||||||
|
@@ -20,7 +20,7 @@ from tacker.sol_refactored.objects import fields
|
|||||||
# NFV-SOL 003
|
# NFV-SOL 003
|
||||||
# - v3.3.1 5.5.2.11 (API version: 2.0.0)
|
# - v3.3.1 5.5.2.11 (API version: 2.0.0)
|
||||||
@base.TackerObjectRegistry.register
|
@base.TackerObjectRegistry.register
|
||||||
class ChangeExtVnfConnectivityRequestV2(base.TackerObject,
|
class ChangeExtVnfConnectivityRequest(base.TackerObject,
|
||||||
base.TackerObjectDictCompat):
|
base.TackerObjectDictCompat):
|
||||||
|
|
||||||
# Version 1.0: Initial version
|
# Version 1.0: Initial version
|
||||||
|
@@ -100,6 +100,12 @@ class Client(object):
|
|||||||
path, "POST", body=req_body, version="2.0.0")
|
path, "POST", body=req_body, version="2.0.0")
|
||||||
self.print(resp, body)
|
self.print(resp, body)
|
||||||
|
|
||||||
|
def chg_ext_conn(self, id, req_body):
|
||||||
|
path = self.path + '/' + id + '/change_ext_conn'
|
||||||
|
resp, body = self.client.do_request(
|
||||||
|
path, "POST", body=req_body, version="2.0.0")
|
||||||
|
self.print(resp, body)
|
||||||
|
|
||||||
def retry(self, id):
|
def retry(self, id):
|
||||||
path = self.path + '/' + id + '/retry'
|
path = self.path + '/' + id + '/retry'
|
||||||
resp, body = self.client.do_request(path, "POST", version="2.0.0")
|
resp, body = self.client.do_request(path, "POST", version="2.0.0")
|
||||||
@@ -126,6 +132,7 @@ def usage():
|
|||||||
print(" inst inst {id} body(path of content)")
|
print(" inst inst {id} body(path of content)")
|
||||||
print(" inst term {id} body(path of content)")
|
print(" inst term {id} body(path of content)")
|
||||||
print(" inst scale {id} body(path of content)")
|
print(" inst scale {id} body(path of content)")
|
||||||
|
print(" inst chg_ext_conn {id} body(path of content)")
|
||||||
print(" subsc create body(path of content)")
|
print(" subsc create body(path of content)")
|
||||||
print(" subsc list [body(path of content)]")
|
print(" subsc list [body(path of content)]")
|
||||||
print(" subsc show {id}")
|
print(" subsc show {id}")
|
||||||
@@ -152,7 +159,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
if resource == "inst":
|
if resource == "inst":
|
||||||
if action not in ["create", "list", "show", "delete", "update",
|
if action not in ["create", "list", "show", "delete", "update",
|
||||||
"inst", "term", "scale"]:
|
"inst", "term", "scale", "chg_ext_conn"]:
|
||||||
usage()
|
usage()
|
||||||
client = Client("/vnflcm/v2/vnf_instances")
|
client = Client("/vnflcm/v2/vnf_instances")
|
||||||
elif resource == "subsc":
|
elif resource == "subsc":
|
||||||
@@ -202,6 +209,10 @@ if __name__ == '__main__':
|
|||||||
if len(sys.argv) != 5:
|
if len(sys.argv) != 5:
|
||||||
usage()
|
usage()
|
||||||
client.scale(sys.argv[3], get_body(sys.argv[4]))
|
client.scale(sys.argv[3], get_body(sys.argv[4]))
|
||||||
|
elif action == "chg_ext_conn":
|
||||||
|
if len(sys.argv) != 5:
|
||||||
|
usage()
|
||||||
|
client.chg_ext_conn(sys.argv[3], get_body(sys.argv[4]))
|
||||||
elif action == "retry":
|
elif action == "retry":
|
||||||
if len(sys.argv) != 4:
|
if len(sys.argv) != 4:
|
||||||
usage()
|
usage()
|
||||||
|
@@ -81,6 +81,109 @@ _inst_info_example_1 = {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
# "currentVnfExtCpData": omitted
|
# "currentVnfExtCpData": omitted
|
||||||
|
},
|
||||||
|
# following two data are for test_update_lcmocc_change_ext_conn
|
||||||
|
{
|
||||||
|
"id": "cba2e572-2cc5-4d11-af60-728615883206",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "4529d333-dbcc-4d93-9b64-210647712569"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [],
|
||||||
|
"currentVnfExtCpData": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP1_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP1_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
"10.10.0.102"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fc131806-8a4f-43a3-82c0-a38e87fe87bd",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "5529d333-dbcc-4d93-9b64-210647712569"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [],
|
||||||
|
"currentVnfExtCpData": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
"10.10.1.102"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"extManagedVirtualLinkInfo": [
|
"extManagedVirtualLinkInfo": [
|
||||||
@@ -616,6 +719,190 @@ _inst_info_example_2 = {
|
|||||||
# "vnfcInfo": omitted
|
# "vnfcInfo": omitted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# example_3 is changed external virtual link ports from example_1.
|
||||||
|
_inst_info_example_3 = {
|
||||||
|
# "flavourId", "vnfState", "scaleStatus", "maxScaleLevels" are omitted
|
||||||
|
# "extCpInfo": omitted
|
||||||
|
"extVirtualLinkInfo": [
|
||||||
|
{
|
||||||
|
"id": "bbf0932a-6142-4ea8-93cd-8059dba594a1",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "3529d333-dbcc-4d93-9b64-210647712569"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU1_CP1_1",
|
||||||
|
"resourceHandle": {
|
||||||
|
"vimConnectionId": "vim_connection_id",
|
||||||
|
"resourceId": "res_id_VDU1_CP1_1",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "cp-res_id_VDU1_CP1_1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
# "currentVnfExtCpData": omitted
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2ff742fc-da6d-423a-8fba-6aa6af8da6f2",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "9113aff7-9ba2-43f4-8b1e-fff80ae001c5"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU2_CP1_modified",
|
||||||
|
"resourceHandle": {
|
||||||
|
"vimConnectionId": "vim_connection_id",
|
||||||
|
"resourceId": "res_id_VDU2_CP1_modified",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "cp-res_id_VDU2_CP1"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
# "currentVnfExtCpData": omitted
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "790949df-c7b3-4926-a559-3895412f1dfe",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "367e5b3b-34dc-47f2-85b8-c39e3272893a"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU2_CP2",
|
||||||
|
"resourceHandle": {
|
||||||
|
"vimConnectionId": "vim_connection_id",
|
||||||
|
"resourceId": "res_id_VDU2_CP2",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "cp-res_id_VDU2_CP2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU1_CP2_1",
|
||||||
|
"resourceHandle": {
|
||||||
|
"vimConnectionId": "vim_connection_id",
|
||||||
|
"resourceId": "res_id_VDU1_CP2_1",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "cp-res_id_VDU1_CP2_1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
# "currentVnfExtCpData": omitted
|
||||||
|
},
|
||||||
|
{ # same as _inst_info_example_1
|
||||||
|
"id": "cba2e572-2cc5-4d11-af60-728615883206",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "4529d333-dbcc-4d93-9b64-210647712569"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [],
|
||||||
|
"currentVnfExtCpData": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP1_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP1_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
"10.10.0.102"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ # ip address of VDU2_CP2 is changed
|
||||||
|
"id": "fc131806-8a4f-43a3-82c0-a38e87fe87bd",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "5529d333-dbcc-4d93-9b64-210647712569"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [],
|
||||||
|
"currentVnfExtCpData": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
"10.10.1.103"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
# NOTE: vnfcCpInfo of VnfcResourceInfo is changed exactly, but it is
|
||||||
|
# not looked at lcmocc_update.
|
||||||
|
"vnfcResourceInfo": _inst_info_example_1["vnfcResourceInfo"],
|
||||||
|
# other members are same as example_1
|
||||||
|
"extManagedVirtualLinkInfo":
|
||||||
|
_inst_info_example_1["extManagedVirtualLinkInfo"],
|
||||||
|
"vnfVirtualLinkResourceInfo":
|
||||||
|
_inst_info_example_1["vnfVirtualLinkResourceInfo"],
|
||||||
|
"virtualStorageResourceInfo":
|
||||||
|
_inst_info_example_1["virtualStorageResourceInfo"],
|
||||||
|
# "vnfcInfo": omitted
|
||||||
|
}
|
||||||
|
|
||||||
# expected results
|
# expected results
|
||||||
_expected_resource_changes_instantiate = {
|
_expected_resource_changes_instantiate = {
|
||||||
"affectedVnfcs": [
|
"affectedVnfcs": [
|
||||||
@@ -1233,6 +1520,38 @@ _expected_changedInfo = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_expected_resource_changes_change_ext_conn = {
|
||||||
|
"affectedExtLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU2_CP1",
|
||||||
|
"changeType": "REMOVED",
|
||||||
|
"extCpInstanceId": "cp-res_id_VDU2_CP1",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP1",
|
||||||
|
"vimConnectionId": "vim_connection_id",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU2_CP1_modified",
|
||||||
|
"changeType": "ADDED",
|
||||||
|
"extCpInstanceId": "cp-res_id_VDU2_CP1",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP1_modified",
|
||||||
|
"vimConnectionId": "vim_connection_id",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
_expected_changed_ext_connectivity = [
|
||||||
|
# sort by id
|
||||||
|
_inst_info_example_3['extVirtualLinkInfo'][1],
|
||||||
|
_inst_info_example_3['extVirtualLinkInfo'][0],
|
||||||
|
_inst_info_example_3['extVirtualLinkInfo'][4]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class TestLcmOpOccUtils(base.BaseTestCase):
|
class TestLcmOpOccUtils(base.BaseTestCase):
|
||||||
|
|
||||||
@@ -1366,3 +1685,28 @@ class TestLcmOpOccUtils(base.BaseTestCase):
|
|||||||
# check changedInfo
|
# check changedInfo
|
||||||
lcmocc = lcmocc.to_dict()
|
lcmocc = lcmocc.to_dict()
|
||||||
self.assertEqual(_expected_changedInfo, lcmocc['changedInfo'])
|
self.assertEqual(_expected_changedInfo, lcmocc['changedInfo'])
|
||||||
|
|
||||||
|
def test_update_lcmocc_change_ext_conn(self):
|
||||||
|
# prepare
|
||||||
|
inst_saved = objects.VnfInstanceV2()
|
||||||
|
inst_saved.instantiatedVnfInfo = (
|
||||||
|
objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||||
|
_inst_info_example_1))
|
||||||
|
inst = objects.VnfInstanceV2()
|
||||||
|
inst.instantiatedVnfInfo = (
|
||||||
|
objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||||
|
_inst_info_example_3))
|
||||||
|
lcmocc = objects.VnfLcmOpOccV2(
|
||||||
|
operation=fields.LcmOperationType.CHANGE_EXT_CONN)
|
||||||
|
|
||||||
|
# execute update_lcmocc
|
||||||
|
lcmocc_utils.update_lcmocc(lcmocc, inst_saved, inst)
|
||||||
|
|
||||||
|
# check resourceChanges
|
||||||
|
lcmocc = lcmocc.to_dict()
|
||||||
|
self.assertEqual(
|
||||||
|
_expected_resource_changes_change_ext_conn,
|
||||||
|
self._sort_resource_changes(lcmocc['resourceChanges']))
|
||||||
|
self.assertEqual(
|
||||||
|
_expected_changed_ext_connectivity,
|
||||||
|
sorted(lcmocc['changedExtConnectivity'], key=lambda x: x['id']))
|
||||||
|
@@ -126,6 +126,46 @@ _inst_req_example = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ChangeExtVnfConnectivityRequest example for change_ext_conn grant test
|
||||||
|
_ext_vl_3 = {
|
||||||
|
"id": uuidutils.generate_uuid(),
|
||||||
|
"resourceId": 'net2_id',
|
||||||
|
"extCps": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP2_1": {
|
||||||
|
"cpProtocolData": [{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1,
|
||||||
|
"subnetId": 'subnet2_id'}]}}]}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP1_1": {
|
||||||
|
"linkPortId": "link_port_id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "link_port_id",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
_change_ext_conn_req_example = {
|
||||||
|
"extVirtualLinks": [_ext_vl_3]
|
||||||
|
}
|
||||||
|
|
||||||
# instantiatedVnfInfo example for terminate/scale grant test
|
# instantiatedVnfInfo example for terminate/scale grant test
|
||||||
# NOTE:
|
# NOTE:
|
||||||
# - some identifiers are modified to make check easy.
|
# - some identifiers are modified to make check easy.
|
||||||
@@ -1227,3 +1267,107 @@ class TestVnfLcmDriverV2(base.BaseTestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.assertEqual(expected_modify_result, inst)
|
self.assertEqual(expected_modify_result, inst)
|
||||||
|
|
||||||
|
@mock.patch.object(nfvo_client.NfvoClient, 'grant')
|
||||||
|
def test_change_ext_conn_grant(self, mocked_grant):
|
||||||
|
# prepare
|
||||||
|
req = objects.ChangeExtVnfConnectivityRequest.from_dict(
|
||||||
|
_change_ext_conn_req_example)
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
vnfdId=SAMPLE_VNFD_ID,
|
||||||
|
vnfProvider='provider',
|
||||||
|
vnfProductName='product name',
|
||||||
|
vnfSoftwareVersion='software version',
|
||||||
|
vnfdVersion='vnfd version',
|
||||||
|
instantiationState='INSTANTIATED'
|
||||||
|
)
|
||||||
|
inst_info = objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||||
|
_inst_info_example)
|
||||||
|
inst.instantiatedVnfInfo = inst_info
|
||||||
|
lcmocc = objects.VnfLcmOpOccV2(
|
||||||
|
# required fields
|
||||||
|
id=uuidutils.generate_uuid(),
|
||||||
|
operationState=fields.LcmOperationStateType.STARTING,
|
||||||
|
stateEnteredTime=datetime.utcnow(),
|
||||||
|
startTime=datetime.utcnow(),
|
||||||
|
vnfInstanceId=inst.id,
|
||||||
|
operation=fields.LcmOperationType.CHANGE_EXT_CONN,
|
||||||
|
isAutomaticInvocation=False,
|
||||||
|
isCancelPending=False,
|
||||||
|
operationParams=req
|
||||||
|
)
|
||||||
|
|
||||||
|
mocked_grant.return_value = objects.GrantV1()
|
||||||
|
|
||||||
|
# run change_ext_conn_grant
|
||||||
|
grant_req, _ = self.driver.grant(
|
||||||
|
self.context, lcmocc, inst, self.vnfd_1)
|
||||||
|
|
||||||
|
# check grant_req is constructed according to intention
|
||||||
|
grant_req = grant_req.to_dict()
|
||||||
|
expected_fixed_items = {
|
||||||
|
'vnfInstanceId': inst.id,
|
||||||
|
'vnfLcmOpOccId': lcmocc.id,
|
||||||
|
'vnfdId': SAMPLE_VNFD_ID,
|
||||||
|
'operation': 'CHANGE_EXT_CONN',
|
||||||
|
'isAutomaticInvocation': False,
|
||||||
|
'_links': self._grant_req_links(lcmocc.id, inst.id)
|
||||||
|
}
|
||||||
|
for key, value in expected_fixed_items.items():
|
||||||
|
self.assertEqual(value, grant_req[key])
|
||||||
|
|
||||||
|
# check updateResources
|
||||||
|
update_reses = grant_req['updateResources']
|
||||||
|
check_reses = {
|
||||||
|
'COMPUTE': {'VDU1': [], 'VDU2': []}
|
||||||
|
}
|
||||||
|
expected_res_ids = {
|
||||||
|
'COMPUTE': {
|
||||||
|
'VDU1': ['res_id_VDU1_1', 'res_id_VDU1_2'],
|
||||||
|
'VDU2': ['res_id_VDU2']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for res in update_reses:
|
||||||
|
check_reses[res['type']][res['resourceTemplateId']].append(
|
||||||
|
res['resource']['resourceId'])
|
||||||
|
|
||||||
|
for key, value in check_reses.items():
|
||||||
|
for name, ids in value.items():
|
||||||
|
self.assertEqual(expected_res_ids[key][name], ids)
|
||||||
|
|
||||||
|
# check removeResources
|
||||||
|
rm_reses = grant_req['removeResources']
|
||||||
|
check_reses = {
|
||||||
|
'LINKPORT': {'VDU1_CP2': [], 'VDU2_CP1': []}
|
||||||
|
}
|
||||||
|
expected_res_ids = {
|
||||||
|
'LINKPORT': {
|
||||||
|
'VDU1_CP2': ['res_id_VDU1_1_CP2', 'res_id_VDU1_2_CP2'],
|
||||||
|
'VDU2_CP1': ['res_id_VDU2_CP1']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for res in rm_reses:
|
||||||
|
check_reses[res['type']][res['resourceTemplateId']].append(
|
||||||
|
res['resource']['resourceId'])
|
||||||
|
|
||||||
|
for key, value in check_reses.items():
|
||||||
|
for name, ids in value.items():
|
||||||
|
self.assertEqual(expected_res_ids[key][name], ids)
|
||||||
|
|
||||||
|
# check addResources
|
||||||
|
add_reses = grant_req['addResources']
|
||||||
|
check_reses = {
|
||||||
|
'LINKPORT': {'VDU1_CP2': []}
|
||||||
|
}
|
||||||
|
expected_num = {
|
||||||
|
'LINKPORT': {'VDU1_CP2': 2}
|
||||||
|
}
|
||||||
|
for res in add_reses:
|
||||||
|
check_reses[res['type']][res['resourceTemplateId']].append(
|
||||||
|
res['id'])
|
||||||
|
|
||||||
|
for key, value in check_reses.items():
|
||||||
|
for name, ids in value.items():
|
||||||
|
self.assertEqual(expected_num[key][name], len(ids))
|
||||||
|
@@ -29,6 +29,34 @@ from tacker.sol_refactored.objects.v2 import fields
|
|||||||
from tacker.tests.unit.db import base as db_base
|
from tacker.tests.unit.db import base as db_base
|
||||||
|
|
||||||
|
|
||||||
|
_change_ext_conn_req_example = {
|
||||||
|
"extVirtualLinks": [
|
||||||
|
{
|
||||||
|
"id": "id_ext_vl_1",
|
||||||
|
"resourceId": "res_id_ext_vl_1",
|
||||||
|
"extCps": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"linkPortId": "link_port_id_VDU2_CP2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "link_port_id_VDU2_CP2",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestVnflcmV2(db_base.SqlTestCase):
|
class TestVnflcmV2(db_base.SqlTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@@ -459,3 +487,19 @@ class TestVnflcmV2(db_base.SqlTestCase):
|
|||||||
self.assertRaises(sol_ex.SolValidationError,
|
self.assertRaises(sol_ex.SolValidationError,
|
||||||
self.controller.update, request=self.request, id=inst.id,
|
self.controller.update, request=self.request, id=inst.id,
|
||||||
body=body)
|
body=body)
|
||||||
|
|
||||||
|
def test_change_ext_conn_not_instantiated(self):
|
||||||
|
inst_id, _ = self._create_inst_and_lcmocc('NOT_INSTANTIATED',
|
||||||
|
fields.LcmOperationStateType.COMPLETED)
|
||||||
|
|
||||||
|
self.assertRaises(sol_ex.VnfInstanceIsNotInstantiated,
|
||||||
|
self.controller.change_ext_conn, request=self.request, id=inst_id,
|
||||||
|
body=_change_ext_conn_req_example)
|
||||||
|
|
||||||
|
def test_change_ext_conn_lcmocc_in_progress(self):
|
||||||
|
inst_id, _ = self._create_inst_and_lcmocc('INSTANTIATED',
|
||||||
|
fields.LcmOperationStateType.FAILED_TEMP)
|
||||||
|
|
||||||
|
self.assertRaises(sol_ex.OtherOperationInProgress,
|
||||||
|
self.controller.change_ext_conn, request=self.request, id=inst_id,
|
||||||
|
body=_change_ext_conn_req_example)
|
||||||
|
@@ -142,7 +142,84 @@ _instantiate_req_example = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# heat resources example
|
# ChangeExtVnfConnectivityRequest example
|
||||||
|
_change_ext_conn_req_example = {
|
||||||
|
"extVirtualLinks": [
|
||||||
|
{
|
||||||
|
"id": "id_ext_vl_3",
|
||||||
|
"resourceId": "res_id_ext_vl_3",
|
||||||
|
"extCps": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP1_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
"20.10.0.102"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "id_ext_vl_4",
|
||||||
|
"resourceId": "res_id_id_ext_vl_4",
|
||||||
|
"extCps": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1,
|
||||||
|
"subnetId": "res_id_subnet_4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"linkPortId": "link_port_id_VDU2_CP2_modified"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "link_port_id_VDU2_CP2_modified",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP2_modified"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# heat resources examples
|
||||||
# NOTE:
|
# NOTE:
|
||||||
# - following attributes which are not related to tests are omitted.
|
# - following attributes which are not related to tests are omitted.
|
||||||
# updated_time, logical_resource_id, resource_status, resource_status_reason
|
# updated_time, logical_resource_id, resource_status, resource_status_reason
|
||||||
@@ -169,7 +246,7 @@ _stack_id_VDU1_2 = (
|
|||||||
"myet4efobvvp-aptv6apap2h5/dd94d2ae-a02b-4fab-a492-514c422299ec")
|
"myet4efobvvp-aptv6apap2h5/dd94d2ae-a02b-4fab-a492-514c422299ec")
|
||||||
_href_VDU1_2 = "".join((_url, _stack_id_VDU1_2))
|
_href_VDU1_2 = "".join((_url, _stack_id_VDU1_2))
|
||||||
|
|
||||||
_heat_reses_example = [
|
_heat_reses_example_base = [
|
||||||
{
|
{
|
||||||
"creation_time": "2021-12-10T00:40:46Z",
|
"creation_time": "2021-12-10T00:40:46Z",
|
||||||
"resource_name": "VDU2",
|
"resource_name": "VDU2",
|
||||||
@@ -183,21 +260,6 @@ _heat_reses_example = [
|
|||||||
],
|
],
|
||||||
"required_by": []
|
"required_by": []
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"creation_time": "2021-12-10T00:40:46Z",
|
|
||||||
"resource_name": "VDU2_CP1",
|
|
||||||
"physical_resource_id": "res_id_VDU2_CP1",
|
|
||||||
"resource_type": "OS::Neutron::Port",
|
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": _href,
|
|
||||||
"rel": "stack"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"required_by": [
|
|
||||||
"VDU2"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"creation_time": "2021-12-10T00:40:47Z",
|
"creation_time": "2021-12-10T00:40:47Z",
|
||||||
"resource_name": "VDU2_CP5",
|
"resource_name": "VDU2_CP5",
|
||||||
@@ -437,22 +499,6 @@ _heat_reses_example = [
|
|||||||
],
|
],
|
||||||
"parent_resource": "bemybz4ugeso"
|
"parent_resource": "bemybz4ugeso"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"creation_time": "2021-12-10T00:41:45Z",
|
|
||||||
"resource_name": "VDU1_CP2",
|
|
||||||
"physical_resource_id": "res_id_VDU1_CP2_1",
|
|
||||||
"resource_type": "OS::Neutron::Port",
|
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": _href_VDU1_1,
|
|
||||||
"rel": "stack"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"required_by": [
|
|
||||||
"VDU1"
|
|
||||||
],
|
|
||||||
"parent_resource": "bemybz4ugeso"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"creation_time": "2021-12-10T00:41:45Z",
|
"creation_time": "2021-12-10T00:41:45Z",
|
||||||
"resource_name": "VDU1_CP1",
|
"resource_name": "VDU1_CP1",
|
||||||
@@ -564,22 +610,6 @@ _heat_reses_example = [
|
|||||||
],
|
],
|
||||||
"parent_resource": "myet4efobvvp"
|
"parent_resource": "myet4efobvvp"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"creation_time": "2021-12-10T01:03:53Z",
|
|
||||||
"resource_name": "VDU1_CP2",
|
|
||||||
"physical_resource_id": "res_id_VDU1_CP2_2",
|
|
||||||
"resource_type": "OS::Neutron::Port",
|
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"href": _href_VDU1_2,
|
|
||||||
"rel": "stack"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"required_by": [
|
|
||||||
"VDU1"
|
|
||||||
],
|
|
||||||
"parent_resource": "myet4efobvvp"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"creation_time": "2021-12-10T01:03:53Z",
|
"creation_time": "2021-12-10T01:03:53Z",
|
||||||
"resource_name": "VDU1_CP1",
|
"resource_name": "VDU1_CP1",
|
||||||
@@ -647,7 +677,115 @@ _heat_reses_example = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
# expected results
|
_heat_reses_example_cps_before = [
|
||||||
|
{
|
||||||
|
"creation_time": "2021-12-10T00:40:46Z",
|
||||||
|
"resource_name": "VDU2_CP1",
|
||||||
|
"physical_resource_id": "res_id_VDU2_CP1",
|
||||||
|
"resource_type": "OS::Neutron::Port",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": _href,
|
||||||
|
"rel": "stack"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"required_by": [
|
||||||
|
"VDU2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"creation_time": "2021-12-10T00:41:45Z",
|
||||||
|
"resource_name": "VDU1_CP2",
|
||||||
|
"physical_resource_id": "res_id_VDU1_CP2_1",
|
||||||
|
"resource_type": "OS::Neutron::Port",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": _href_VDU1_1,
|
||||||
|
"rel": "stack"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"required_by": [
|
||||||
|
"VDU1"
|
||||||
|
],
|
||||||
|
"parent_resource": "bemybz4ugeso"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"creation_time": "2021-12-10T01:03:53Z",
|
||||||
|
"resource_name": "VDU1_CP2",
|
||||||
|
"physical_resource_id": "res_id_VDU1_CP2_2",
|
||||||
|
"resource_type": "OS::Neutron::Port",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": _href_VDU1_2,
|
||||||
|
"rel": "stack"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"required_by": [
|
||||||
|
"VDU1"
|
||||||
|
],
|
||||||
|
"parent_resource": "myet4efobvvp"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
_heat_reses_example_cps_after = [
|
||||||
|
{
|
||||||
|
"creation_time": "2021-12-10T00:40:46Z",
|
||||||
|
"resource_name": "VDU2_CP1",
|
||||||
|
"physical_resource_id": "res_id_VDU2_CP1_modified",
|
||||||
|
"resource_type": "OS::Neutron::Port",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": _href,
|
||||||
|
"rel": "stack"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"required_by": [
|
||||||
|
"VDU2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"creation_time": "2021-12-10T00:41:45Z",
|
||||||
|
"resource_name": "VDU1_CP2",
|
||||||
|
"physical_resource_id": "res_id_VDU1_CP2_1_modified",
|
||||||
|
"resource_type": "OS::Neutron::Port",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": _href_VDU1_1,
|
||||||
|
"rel": "stack"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"required_by": [
|
||||||
|
"VDU1"
|
||||||
|
],
|
||||||
|
"parent_resource": "bemybz4ugeso"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"creation_time": "2021-12-10T01:03:53Z",
|
||||||
|
"resource_name": "VDU1_CP2",
|
||||||
|
"physical_resource_id": "res_id_VDU1_CP2_2_modified",
|
||||||
|
"resource_type": "OS::Neutron::Port",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": _href_VDU1_2,
|
||||||
|
"rel": "stack"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"required_by": [
|
||||||
|
"VDU1"
|
||||||
|
],
|
||||||
|
"parent_resource": "myet4efobvvp"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
# heat resources example for other than change_ext_conn
|
||||||
|
_heat_reses_example = (
|
||||||
|
_heat_reses_example_base + _heat_reses_example_cps_before)
|
||||||
|
|
||||||
|
# heat resources example after executing change_ext_conn
|
||||||
|
_heat_reses_example_change_ext_conn = (
|
||||||
|
_heat_reses_example_base + _heat_reses_example_cps_after)
|
||||||
|
|
||||||
|
# expected results (other than change_ext_conn)
|
||||||
_expected_inst_info = {
|
_expected_inst_info = {
|
||||||
"flavourId": "simple",
|
"flavourId": "simple",
|
||||||
"vnfState": "STARTED",
|
"vnfState": "STARTED",
|
||||||
@@ -1228,6 +1366,417 @@ _expected_inst_info_vnfc_updated["vnfcInfo"] = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# expected results for change_ext_conn
|
||||||
|
_expected_inst_info_change_ext_conn = {
|
||||||
|
"flavourId": "simple",
|
||||||
|
"vnfState": "STARTED",
|
||||||
|
"extCpInfo": [
|
||||||
|
{
|
||||||
|
'id': 'cp-req-link_port_id_VDU2_CP2_modified',
|
||||||
|
'cpdId': 'VDU2_CP2',
|
||||||
|
'cpConfigId': 'VDU2_CP2_1',
|
||||||
|
'extLinkPortId': 'req-link_port_id_VDU2_CP2_modified',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cp-res_id_VDU1_CP1_1",
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"cpConfigId": "VDU1_CP1_1",
|
||||||
|
"cpProtocolInfo": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"isDynamic": True
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extLinkPortId": "res_id_VDU1_CP1_1",
|
||||||
|
"associatedVnfcCpId": "VDU1_CP1-res_id_VDU1_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cp-res_id_VDU1_CP1_2",
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"cpConfigId": "VDU1_CP1_1",
|
||||||
|
"cpProtocolInfo": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"isDynamic": True
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extLinkPortId": "res_id_VDU1_CP1_2",
|
||||||
|
"associatedVnfcCpId": "VDU1_CP1-res_id_VDU1_2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cp-res_id_VDU1_CP2_1_modified",
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfigId": "VDU1_CP2_1",
|
||||||
|
"cpProtocolInfo": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"isDynamic": True,
|
||||||
|
"subnetId": "res_id_subnet_4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extLinkPortId": "res_id_VDU1_CP2_1_modified",
|
||||||
|
"associatedVnfcCpId": "VDU1_CP2-res_id_VDU1_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cp-res_id_VDU1_CP2_2_modified",
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfigId": "VDU1_CP2_1",
|
||||||
|
"cpProtocolInfo": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"isDynamic": True,
|
||||||
|
"subnetId": "res_id_subnet_4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extLinkPortId": "res_id_VDU1_CP2_2_modified",
|
||||||
|
"associatedVnfcCpId": "VDU1_CP2-res_id_VDU1_2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cp-res_id_VDU2_CP1_modified",
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"cpConfigId": "VDU2_CP1_1",
|
||||||
|
"cpProtocolInfo": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"addresses": [
|
||||||
|
"20.10.0.102"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extLinkPortId": "res_id_VDU2_CP1_modified",
|
||||||
|
"associatedVnfcCpId": "VDU2_CP1-res_id_VDU2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extVirtualLinkInfo": [
|
||||||
|
{
|
||||||
|
"id": "id_ext_vl_1",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_ext_vl_1"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU1_CP1_1",
|
||||||
|
"resourceHandle": {
|
||||||
|
"vimConnectionId": "vim_id_1",
|
||||||
|
"resourceId": "res_id_VDU1_CP1_1",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "cp-res_id_VDU1_CP1_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU1_CP1_2",
|
||||||
|
"resourceHandle": {
|
||||||
|
"vimConnectionId": "vim_id_1",
|
||||||
|
"resourceId": "res_id_VDU1_CP1_2",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "cp-res_id_VDU1_CP1_2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"currentVnfExtCpData": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP1_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "id_ext_vl_3",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_ext_vl_3"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU2_CP1_modified",
|
||||||
|
"resourceHandle": {
|
||||||
|
"vimConnectionId": "vim_id_1",
|
||||||
|
"resourceId": "res_id_VDU2_CP1_modified",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "cp-res_id_VDU2_CP1_modified"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"currentVnfExtCpData": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP1_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
"20.10.0.102"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "id_ext_vl_4",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_id_ext_vl_4"
|
||||||
|
},
|
||||||
|
"extLinkPorts": [
|
||||||
|
{
|
||||||
|
"id": "req-link_port_id_VDU2_CP2_modified",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "res_id_VDU2_CP2_modified",
|
||||||
|
},
|
||||||
|
"cpInstanceId": "cp-req-link_port_id_VDU2_CP2_modified"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU1_CP2_1_modified",
|
||||||
|
"resourceHandle": {
|
||||||
|
"vimConnectionId": "vim_id_1",
|
||||||
|
"resourceId": "res_id_VDU1_CP2_1_modified",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "cp-res_id_VDU1_CP2_1_modified"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU1_CP2_2_modified",
|
||||||
|
"resourceHandle": {
|
||||||
|
"vimConnectionId": "vim_id_1",
|
||||||
|
"resourceId": "res_id_VDU1_CP2_2_modified",
|
||||||
|
"vimLevelResourceType": "OS::Neutron::Port"
|
||||||
|
},
|
||||||
|
"cpInstanceId": "cp-res_id_VDU1_CP2_2_modified"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"currentVnfExtCpData": [
|
||||||
|
{
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU1_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"numDynamicAddresses": 1,
|
||||||
|
"subnetId": "res_id_subnet_4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"linkPortId": "link_port_id_VDU2_CP2_modified"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"vnfcResourceInfo": [
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU1_2",
|
||||||
|
"vduId": "VDU1",
|
||||||
|
"computeResource": {
|
||||||
|
"vimConnectionId": "vim_id_1",
|
||||||
|
"resourceId": "res_id_VDU1_2",
|
||||||
|
"vimLevelResourceType": "OS::Nova::Server"
|
||||||
|
},
|
||||||
|
"storageResourceIds": [
|
||||||
|
"res_id_VirtualStorage_2"
|
||||||
|
],
|
||||||
|
"vnfcCpInfo": [
|
||||||
|
{
|
||||||
|
"id": "VDU1_CP1-res_id_VDU1_2",
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"vnfExtCpId": "cp-res_id_VDU1_CP1_2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU1_CP2-res_id_VDU1_2",
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"vnfExtCpId": "cp-res_id_VDU1_CP2_2_modified"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU1_CP3-res_id_VDU1_2",
|
||||||
|
"cpdId": "VDU1_CP3",
|
||||||
|
"vnfLinkPortId": "res_id_VDU1_CP3_2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU1_CP4-res_id_VDU1_2",
|
||||||
|
"cpdId": "VDU1_CP4",
|
||||||
|
"vnfLinkPortId": "res_id_VDU1_CP4_2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU1_CP5-res_id_VDU1_2",
|
||||||
|
"cpdId": "VDU1_CP5",
|
||||||
|
"vnfLinkPortId": "res_id_VDU1_CP5_2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"creation_time": "2021-12-10T01:03:49Z",
|
||||||
|
"parent_stack_id": _stack_id_VDU1_scale,
|
||||||
|
"parent_resource_name": "myet4efobvvp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU1_1",
|
||||||
|
"vduId": "VDU1",
|
||||||
|
"computeResource": {
|
||||||
|
"vimConnectionId": "vim_id_1",
|
||||||
|
"resourceId": "res_id_VDU1_1",
|
||||||
|
"vimLevelResourceType": "OS::Nova::Server"
|
||||||
|
},
|
||||||
|
"storageResourceIds": [
|
||||||
|
"res_id_VirtualStorage_1"
|
||||||
|
],
|
||||||
|
"vnfcCpInfo": [
|
||||||
|
{
|
||||||
|
"id": "VDU1_CP1-res_id_VDU1_1",
|
||||||
|
"cpdId": "VDU1_CP1",
|
||||||
|
"vnfExtCpId": "cp-res_id_VDU1_CP1_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU1_CP2-res_id_VDU1_1",
|
||||||
|
"cpdId": "VDU1_CP2",
|
||||||
|
"vnfExtCpId": "cp-res_id_VDU1_CP2_1_modified"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU1_CP3-res_id_VDU1_1",
|
||||||
|
"cpdId": "VDU1_CP3",
|
||||||
|
"vnfLinkPortId": "res_id_VDU1_CP3_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU1_CP4-res_id_VDU1_1",
|
||||||
|
"cpdId": "VDU1_CP4",
|
||||||
|
"vnfLinkPortId": "res_id_VDU1_CP4_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU1_CP5-res_id_VDU1_1",
|
||||||
|
"cpdId": "VDU1_CP5",
|
||||||
|
"vnfLinkPortId": "res_id_VDU1_CP5_1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"creation_time": "2021-12-10T00:41:43Z",
|
||||||
|
"parent_stack_id": _stack_id_VDU1_scale,
|
||||||
|
"parent_resource_name": "bemybz4ugeso"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "res_id_VDU2",
|
||||||
|
"vduId": "VDU2",
|
||||||
|
"computeResource": {
|
||||||
|
"vimConnectionId": "vim_id_1",
|
||||||
|
"resourceId": "res_id_VDU2",
|
||||||
|
"vimLevelResourceType": "OS::Nova::Server"
|
||||||
|
},
|
||||||
|
"vnfcCpInfo": [
|
||||||
|
{
|
||||||
|
"id": "VDU2_CP1-res_id_VDU2",
|
||||||
|
"cpdId": "VDU2_CP1",
|
||||||
|
"vnfExtCpId": "cp-res_id_VDU2_CP1_modified"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU2_CP2-res_id_VDU2",
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
# "vnfExtCpId" does not exist since it is specified by
|
||||||
|
# linkPortIds.
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU2_CP3-res_id_VDU2",
|
||||||
|
"cpdId": "VDU2_CP3",
|
||||||
|
"vnfLinkPortId": "res_id_VDU2_CP3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU2_CP4-res_id_VDU2",
|
||||||
|
"cpdId": "VDU2_CP4",
|
||||||
|
"vnfLinkPortId": "res_id_VDU2_CP4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VDU2_CP5-res_id_VDU2",
|
||||||
|
"cpdId": "VDU2_CP5",
|
||||||
|
"vnfLinkPortId": "res_id_VDU2_CP5"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"creation_time": "2021-12-10T00:40:46Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
# other members are not changed from _expected_inst_info
|
||||||
|
"extManagedVirtualLinkInfo":
|
||||||
|
_expected_inst_info["extManagedVirtualLinkInfo"],
|
||||||
|
"vnfVirtualLinkResourceInfo":
|
||||||
|
_expected_inst_info["vnfVirtualLinkResourceInfo"],
|
||||||
|
"virtualStorageResourceInfo":
|
||||||
|
_expected_inst_info["virtualStorageResourceInfo"],
|
||||||
|
"vnfcInfo": _expected_inst_info["vnfcInfo"]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestOpenstack(base.BaseTestCase):
|
class TestOpenstack(base.BaseTestCase):
|
||||||
|
|
||||||
@@ -1258,6 +1807,7 @@ class TestOpenstack(base.BaseTestCase):
|
|||||||
|
|
||||||
if "extVirtualLinkInfo" in expected:
|
if "extVirtualLinkInfo" in expected:
|
||||||
self.assertIn("extVirtualLinkInfo", result)
|
self.assertIn("extVirtualLinkInfo", result)
|
||||||
|
result["extVirtualLinkInfo"].sort(key=_get_key)
|
||||||
for ext_vl in result["extVirtualLinkInfo"]:
|
for ext_vl in result["extVirtualLinkInfo"]:
|
||||||
if "extLinkPorts" in ext_vl:
|
if "extLinkPorts" in ext_vl:
|
||||||
ext_vl["extLinkPorts"].sort(key=_get_key)
|
ext_vl["extLinkPorts"].sort(key=_get_key)
|
||||||
@@ -1350,3 +1900,30 @@ class TestOpenstack(base.BaseTestCase):
|
|||||||
# check
|
# check
|
||||||
result = inst.to_dict()["instantiatedVnfInfo"]
|
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||||
self._check_inst_info(_expected_inst_info_vnfc_updated, result)
|
self._check_inst_info(_expected_inst_info_vnfc_updated, result)
|
||||||
|
|
||||||
|
def test_make_instantiated_vnf_info_change_ext_conn(self):
|
||||||
|
# prepare
|
||||||
|
req = objects.ChangeExtVnfConnectivityRequest.from_dict(
|
||||||
|
_change_ext_conn_req_example)
|
||||||
|
inst_info = objects.VnfInstanceV2_InstantiatedVnfInfo.from_dict(
|
||||||
|
_expected_inst_info)
|
||||||
|
vim_info = {
|
||||||
|
"vim1": objects.VimConnectionInfo.from_dict(
|
||||||
|
_vim_connection_info_example)
|
||||||
|
}
|
||||||
|
inst = objects.VnfInstanceV2(
|
||||||
|
instantiatedVnfInfo=inst_info,
|
||||||
|
vimConnectionInfo=vim_info
|
||||||
|
)
|
||||||
|
grant_req = objects.GrantRequestV1(
|
||||||
|
operation=fields.LcmOperationType.CHANGE_EXT_CONN
|
||||||
|
)
|
||||||
|
grant = objects.GrantV1()
|
||||||
|
|
||||||
|
# execute make_instantiated_vnf_info
|
||||||
|
self.driver._make_instantiated_vnf_info(req, inst, grant_req, grant,
|
||||||
|
self.vnfd_1, _heat_reses_example_change_ext_conn)
|
||||||
|
|
||||||
|
# check
|
||||||
|
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||||
|
self._check_inst_info(_expected_inst_info_change_ext_conn, result)
|
||||||
|
@@ -210,6 +210,59 @@ class TestUserDataUtils(base.BaseTestCase):
|
|||||||
result = userdata_utils.get_param_fixed_ips('VDU2_CP2', {}, req)
|
result = userdata_utils.get_param_fixed_ips('VDU2_CP2', {}, req)
|
||||||
self.assertEqual(expected_result, result)
|
self.assertEqual(expected_result, result)
|
||||||
|
|
||||||
|
def _inst_example_get_network_fixed_ips_from_inst(self):
|
||||||
|
ext_cp = {
|
||||||
|
"cpdId": "VDU2_CP2",
|
||||||
|
"cpConfig": {
|
||||||
|
"VDU2_CP2_1": {
|
||||||
|
"cpProtocolData": [
|
||||||
|
{
|
||||||
|
"layerProtocol": "IP_OVER_ETHERNET",
|
||||||
|
"ipOverEthernet": {
|
||||||
|
"ipAddresses": [
|
||||||
|
{
|
||||||
|
"type": "IPV4",
|
||||||
|
"fixedAddresses": [
|
||||||
|
"ip_address"
|
||||||
|
],
|
||||||
|
"subnetId": "subnet_id"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inst = {
|
||||||
|
"instantiatedVnfInfo": {
|
||||||
|
"extVirtualLinkInfo": [
|
||||||
|
{
|
||||||
|
"id": "8b49f4b6-1ff9-4a03-99cf-ff445b788436",
|
||||||
|
"resourceHandle": {
|
||||||
|
"resourceId": "ext_vl_res_id"
|
||||||
|
},
|
||||||
|
"currentVnfExtCpData": [ext_cp]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inst
|
||||||
|
|
||||||
|
def test_get_parama_network_from_inst(self):
|
||||||
|
inst = self._inst_example_get_network_fixed_ips_from_inst()
|
||||||
|
|
||||||
|
result = userdata_utils.get_param_network_from_inst('VDU2_CP2', inst)
|
||||||
|
self.assertEqual("ext_vl_res_id", result)
|
||||||
|
|
||||||
|
def test_get_param_fixed_ips_from_inst(self):
|
||||||
|
inst = self._inst_example_get_network_fixed_ips_from_inst()
|
||||||
|
|
||||||
|
expected_result = [{'ip_address': 'ip_address', 'subnet': 'subnet_id'}]
|
||||||
|
|
||||||
|
result = userdata_utils.get_param_fixed_ips_from_inst('VDU2_CP2', inst)
|
||||||
|
self.assertEqual(expected_result, result)
|
||||||
|
|
||||||
def test_apply_ext_managed_vls(self):
|
def test_apply_ext_managed_vls(self):
|
||||||
hot_dict = self.vnfd_1.get_base_hot(SAMPLE_FLAVOUR_ID)
|
hot_dict = self.vnfd_1.get_base_hot(SAMPLE_FLAVOUR_ID)
|
||||||
top_hot = hot_dict['template']
|
top_hot = hot_dict['template']
|
||||||
|
Reference in New Issue
Block a user