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:
parent
5951218ee8
commit
83e4a8d526
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'}
|
||||
]
|
||||
),
|
||||
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.
|
||||
|
||||
|
@ -39,6 +39,7 @@ class VnflcmAPIRouterV2(sol_wsgi.SolAPIRouter):
|
||||
("/vnf_instances/{id}/heal", {"POST": "heal"}),
|
||||
("/vnf_instances/{id}/terminate", {"POST": "terminate"}),
|
||||
("/vnf_instances/{id}/scale", {"POST": "scale"}),
|
||||
("/vnf_instances/{id}/change_ext_conn", {"POST": "change_ext_conn"}),
|
||||
("/api_versions", {"GET": "api_versions"}),
|
||||
("/subscriptions", {"GET": "subscription_list",
|
||||
"POST": "subscription_create"}),
|
||||
|
@ -93,6 +93,26 @@ ScaleVnfRequest_V200 = {
|
||||
'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
|
||||
_SubscriptionAuthentication = {
|
||||
'type': 'object',
|
||||
|
@ -329,7 +329,8 @@ def _change_vnf_info(lcmocc, inst_saved, inst):
|
||||
def update_lcmocc(lcmocc, inst_saved, inst):
|
||||
# if operation is MODIFY_INFO, make changedInfo 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
|
||||
# and so on are not included in lcmocc since such info are not
|
||||
# included in instantiatedVnfInfo.
|
||||
@ -431,6 +432,53 @@ def update_lcmocc(lcmocc, inst_saved, inst):
|
||||
change_info.affectedExtLinkPorts = affected_ext_link_ports
|
||||
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):
|
||||
if lcmocc.operation == fields.LcmOperationType.MODIFY_INFO:
|
||||
|
@ -47,10 +47,9 @@ def make_inst_links(inst, endpoint):
|
||||
else: # 'INSTANTIATED'
|
||||
links.terminate = objects.Link(href=self_href + "/terminate")
|
||||
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
|
||||
# links.heal = objects.Link(href=self_href + "/heal")
|
||||
# links.changeExtConn = objects.Link(
|
||||
# href=self_href + "/change_ext_conn")
|
||||
# etc.
|
||||
|
||||
return links
|
||||
|
@ -215,11 +215,12 @@ class ConductorV2(object):
|
||||
|
||||
lcmocc.operationState = fields.LcmOperationStateType.ROLLED_BACK
|
||||
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)
|
||||
# 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.
|
||||
if grant_req is not None:
|
||||
grant_req.delete(context)
|
||||
|
@ -36,6 +36,11 @@ LOG = logging.getLogger(__name__)
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
# sub method for making id
|
||||
def _make_combination_id(a, b):
|
||||
return '{}-{}'.format(a, b)
|
||||
|
||||
|
||||
class VnfLcmDriverV2(object):
|
||||
|
||||
def __init__(self):
|
||||
@ -256,7 +261,7 @@ class VnfLcmDriverV2(object):
|
||||
for cp_name in cp_names:
|
||||
add_reses.append(
|
||||
objects.ResourceDefinitionV1(
|
||||
id="{}-{}".format(cp_name, vdu_res_id),
|
||||
id=_make_combination_id(cp_name, vdu_res_id),
|
||||
type='LINKPORT',
|
||||
resourceTemplateId=cp_name
|
||||
)
|
||||
@ -264,7 +269,7 @@ class VnfLcmDriverV2(object):
|
||||
for storage_name in storage_names:
|
||||
add_reses.append(
|
||||
objects.ResourceDefinitionV1(
|
||||
id="{}-{}".format(storage_name, vdu_res_id),
|
||||
id=_make_combination_id(storage_name, vdu_res_id),
|
||||
type='STORAGE',
|
||||
resourceTemplateId=storage_name
|
||||
)
|
||||
@ -427,7 +432,7 @@ class VnfLcmDriverV2(object):
|
||||
# deleted.
|
||||
continue
|
||||
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,
|
||||
type='LINKPORT')
|
||||
rm_reses.append(res_def)
|
||||
@ -443,7 +448,8 @@ class VnfLcmDriverV2(object):
|
||||
str_name = inst_str.virtualStorageDescId
|
||||
rm_reses.append(
|
||||
objects.ResourceDefinitionV1(
|
||||
id="{}-{}".format(str_name, vdu_res_id),
|
||||
id=_make_combination_id(str_name,
|
||||
vdu_res_id),
|
||||
type='STORAGE',
|
||||
resourceTemplateId=str_name,
|
||||
resource=inst_str.storageResource
|
||||
@ -650,6 +656,17 @@ class VnfLcmDriverV2(object):
|
||||
setattr(inst, attr, inst_utils.json_merge_patch(
|
||||
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,
|
||||
grant, vnfd):
|
||||
req = lcmocc.operationParams
|
||||
@ -685,14 +702,7 @@ class VnfLcmDriverV2(object):
|
||||
self._modify_from_req(inst, req, attr)
|
||||
|
||||
if req.obj_attr_is_set('vimConnectionInfo'):
|
||||
# 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()}
|
||||
self._merge_vim_connection_info(inst, req)
|
||||
|
||||
if req.obj_attr_is_set('vnfcInfoModifications'):
|
||||
for vnfc_mod in req.vnfcInfoModifications:
|
||||
@ -712,3 +722,106 @@ class VnfLcmDriverV2(object):
|
||||
grant, vnfd):
|
||||
# DB is not updated, rollback does nothing and makes it successful.
|
||||
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)
|
||||
|
||||
@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')
|
||||
def subscription_create(self, request, body):
|
||||
context = request.context
|
||||
|
@ -73,16 +73,15 @@ class Openstack(object):
|
||||
def instantiate(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)
|
||||
|
||||
stack_name = fields['stack_name']
|
||||
|
||||
# create or 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)
|
||||
status, _ = heat_client.get_status(stack_name)
|
||||
if status is None:
|
||||
fields['stack_name'] = stack_name
|
||||
heat_client.create_stack(fields)
|
||||
else:
|
||||
heat_client.update_stack(stack_name, fields)
|
||||
@ -127,15 +126,12 @@ class Openstack(object):
|
||||
return fields
|
||||
|
||||
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
|
||||
fields = self._make_hot(req, inst, grant_req, grant, vnfd)
|
||||
|
||||
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
|
||||
if req.type == 'SCALE_IN':
|
||||
@ -153,6 +149,7 @@ class Openstack(object):
|
||||
vnfc.metadata['parent_resource_name'])
|
||||
|
||||
# update stack
|
||||
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)
|
||||
|
||||
@ -194,6 +191,40 @@ class Openstack(object):
|
||||
# NOTE: instantiatedVnfInfo is not necessary to update since it
|
||||
# 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):
|
||||
if grant_req.operation == v2fields.LcmOperationType.INSTANTIATE:
|
||||
flavour_id = req.flavourId
|
||||
@ -248,8 +279,6 @@ class Openstack(object):
|
||||
|
||||
fields = pickle.loads(out.stdout)
|
||||
|
||||
stack_name = heat_utils.get_stack_name(inst)
|
||||
fields['stack_name'] = stack_name
|
||||
fields['timeout_mins'] = (
|
||||
CONF.v2_vnfm.openstack_vim_stack_create_timeout)
|
||||
|
||||
@ -308,66 +337,80 @@ class Openstack(object):
|
||||
|
||||
return proto_info
|
||||
|
||||
def _make_link_ports(self, req_ext_vl, ext_cp_infos):
|
||||
link_ports = []
|
||||
if not req_ext_vl.obj_attr_is_set('extLinkPorts'):
|
||||
return link_ports
|
||||
|
||||
for req_link_port in req_ext_vl.extLinkPorts:
|
||||
link_port = objects.ExtLinkPortInfoV2(
|
||||
id=_make_link_port_id(req_link_port.id),
|
||||
resourceHandle=req_link_port.resourceHandle,
|
||||
)
|
||||
ext_cp_info = objects.VnfExtCpInfoV2(
|
||||
id=_make_cp_info_id(link_port.id),
|
||||
extLinkPortId=link_port.id
|
||||
# associatedVnfcCpId may set later
|
||||
)
|
||||
link_port.cpInstanceId = ext_cp_info.id
|
||||
|
||||
for ext_cp in req_ext_vl.extCps:
|
||||
found = False
|
||||
for key, cp_conf in ext_cp.cpConfig.items():
|
||||
if (cp_conf.obj_attr_is_set('linkPortId') and
|
||||
cp_conf.linkPortId == req_link_port.id):
|
||||
ext_cp_info.cpdId = ext_cp.cpdId
|
||||
ext_cp_info.cpConfigId = key
|
||||
# NOTE: cpProtocolInfo can't be filled
|
||||
found = True
|
||||
break
|
||||
if found:
|
||||
break
|
||||
|
||||
link_ports.append(link_port)
|
||||
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_vl
|
||||
|
||||
def _make_ext_vl_info_from_req(self, req, grant, 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)
|
||||
return [self._make_ext_vl_from_req(req_ext_vl, ext_cp_infos)
|
||||
for req_ext_vl in req_ext_vls]
|
||||
|
||||
ext_vls.append(ext_vl)
|
||||
|
||||
if not req_ext_vl.obj_attr_is_set('extLinkPorts'):
|
||||
continue
|
||||
link_ports = []
|
||||
for req_link_port in req_ext_vl.extLinkPorts:
|
||||
link_port = objects.ExtLinkPortInfoV2(
|
||||
id=_make_link_port_id(req_link_port.id),
|
||||
resourceHandle=req_link_port.resourceHandle,
|
||||
)
|
||||
ext_cp_info = objects.VnfExtCpInfoV2(
|
||||
id=_make_cp_info_id(link_port.id),
|
||||
extLinkPortId=link_port.id
|
||||
# associatedVnfcCpId may set later
|
||||
)
|
||||
link_port.cpInstanceId = ext_cp_info.id
|
||||
|
||||
for ext_cp in req_ext_vl.extCps:
|
||||
found = False
|
||||
for key, cp_conf in ext_cp.cpConfig.items():
|
||||
if (cp_conf.obj_attr_is_set('linkPortId') and
|
||||
cp_conf.linkPortId == req_link_port.id):
|
||||
ext_cp_info.cpdId = ext_cp.cpdId
|
||||
ext_cp_info.cpConfigId = key
|
||||
# NOTE: cpProtocolInfo can't be filled
|
||||
found = True
|
||||
break
|
||||
if found:
|
||||
break
|
||||
|
||||
link_ports.append(link_port)
|
||||
ext_cp_infos.append(ext_cp_info)
|
||||
|
||||
ext_vl.extLinkPorts = link_ports
|
||||
|
||||
return 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):
|
||||
# make extVirtualLinkInfo from old inst.extVirtualLinkInfo
|
||||
@ -384,20 +427,83 @@ class Openstack(object):
|
||||
continue
|
||||
new_link_ports = []
|
||||
for link_port in ext_vl.extLinkPorts:
|
||||
if not _is_link_port(link_port.id):
|
||||
# port created by heat. re-create later
|
||||
continue
|
||||
|
||||
new_link_ports.append(link_port)
|
||||
for ext_cp in old_cp_infos:
|
||||
if ext_cp.id == link_port.cpInstanceId:
|
||||
ext_cp_infos.append(ext_cp)
|
||||
break
|
||||
|
||||
if _is_link_port(link_port.id):
|
||||
new_link_ports.append(link_port)
|
||||
ext_cp_infos.append(self._find_ext_cp_info(link_port,
|
||||
old_cp_infos))
|
||||
ext_vl.extLinkPorts = new_link_ports
|
||||
|
||||
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):
|
||||
# make extManagedVirtualLinkInfo
|
||||
ext_mgd_vls = []
|
||||
@ -557,9 +663,8 @@ class Openstack(object):
|
||||
|
||||
def _make_instantiated_vnf_info(self, req, inst, grant_req, grant, vnfd,
|
||||
heat_reses):
|
||||
init = False
|
||||
if grant_req.operation == v2fields.LcmOperationType.INSTANTIATE:
|
||||
init = True
|
||||
op = grant_req.operation
|
||||
if op == v2fields.LcmOperationType.INSTANTIATE:
|
||||
flavour_id = req.flavourId
|
||||
else:
|
||||
flavour_id = inst.instantiatedVnfInfo.flavourId
|
||||
@ -636,15 +741,19 @@ class Openstack(object):
|
||||
]
|
||||
|
||||
ext_cp_infos = []
|
||||
if init:
|
||||
if op == v2fields.LcmOperationType.INSTANTIATE:
|
||||
ext_vl_infos = self._make_ext_vl_info_from_req(
|
||||
req, grant, ext_cp_infos)
|
||||
ext_mgd_vl_infos = self._make_ext_mgd_vl_info_from_req(vnfd,
|
||||
flavour_id, req, grant)
|
||||
else:
|
||||
old_inst_vnf_info = inst.instantiatedVnfInfo
|
||||
ext_vl_infos = self._make_ext_vl_info_from_inst(
|
||||
old_inst_vnf_info, ext_cp_infos)
|
||||
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(
|
||||
old_inst_vnf_info, ext_cp_infos)
|
||||
ext_mgd_vl_infos = self._make_ext_mgd_vl_info_from_inst(
|
||||
old_inst_vnf_info)
|
||||
|
||||
@ -701,7 +810,7 @@ class Openstack(object):
|
||||
# because the association of compute resource and port resource
|
||||
# is not identified.
|
||||
|
||||
# make new instatiatedVnfInfo and replace
|
||||
# make new instantiatedVnfInfo and replace
|
||||
inst_vnf_info = objects.VnfInstanceV2_InstantiatedVnfInfo(
|
||||
flavourId=flavour_id,
|
||||
vnfState='STARTED',
|
||||
|
@ -144,3 +144,97 @@ class DefaultUserData(userdata_utils.AbstractUserData):
|
||||
fields = {'parameters': {'nfv': {'VDU': new_vdus}}}
|
||||
|
||||
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):
|
||||
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):
|
||||
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)
|
||||
|
||||
|
||||
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):
|
||||
# see grant first then instantiateVnfRequest
|
||||
mgd_vls = (grant.get('extManagedVirtualLinks', []) +
|
||||
|
@ -20,8 +20,8 @@ from tacker.sol_refactored.objects import fields
|
||||
# NFV-SOL 003
|
||||
# - v3.3.1 5.5.2.11 (API version: 2.0.0)
|
||||
@base.TackerObjectRegistry.register
|
||||
class ChangeExtVnfConnectivityRequestV2(base.TackerObject,
|
||||
base.TackerObjectDictCompat):
|
||||
class ChangeExtVnfConnectivityRequest(base.TackerObject,
|
||||
base.TackerObjectDictCompat):
|
||||
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
|
@ -100,6 +100,12 @@ class Client(object):
|
||||
path, "POST", body=req_body, version="2.0.0")
|
||||
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):
|
||||
path = self.path + '/' + id + '/retry'
|
||||
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 term {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 list [body(path of content)]")
|
||||
print(" subsc show {id}")
|
||||
@ -152,7 +159,7 @@ if __name__ == '__main__':
|
||||
|
||||
if resource == "inst":
|
||||
if action not in ["create", "list", "show", "delete", "update",
|
||||
"inst", "term", "scale"]:
|
||||
"inst", "term", "scale", "chg_ext_conn"]:
|
||||
usage()
|
||||
client = Client("/vnflcm/v2/vnf_instances")
|
||||
elif resource == "subsc":
|
||||
@ -202,6 +209,10 @@ if __name__ == '__main__':
|
||||
if len(sys.argv) != 5:
|
||||
usage()
|
||||
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":
|
||||
if len(sys.argv) != 4:
|
||||
usage()
|
||||
|
@ -81,6 +81,109 @@ _inst_info_example_1 = {
|
||||
}
|
||||
],
|
||||
# "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": [
|
||||
@ -616,6 +719,190 @@ _inst_info_example_2 = {
|
||||
# "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_resource_changes_instantiate = {
|
||||
"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):
|
||||
|
||||
@ -1366,3 +1685,28 @@ class TestLcmOpOccUtils(base.BaseTestCase):
|
||||
# check changedInfo
|
||||
lcmocc = lcmocc.to_dict()
|
||||
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
|
||||
# NOTE:
|
||||
# - some identifiers are modified to make check easy.
|
||||
@ -1227,3 +1267,107 @@ class TestVnfLcmDriverV2(base.BaseTestCase):
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
_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):
|
||||
|
||||
def setUp(self):
|
||||
@ -459,3 +487,19 @@ class TestVnflcmV2(db_base.SqlTestCase):
|
||||
self.assertRaises(sol_ex.SolValidationError,
|
||||
self.controller.update, request=self.request, id=inst.id,
|
||||
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:
|
||||
# - following attributes which are not related to tests are omitted.
|
||||
# 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")
|
||||
_href_VDU1_2 = "".join((_url, _stack_id_VDU1_2))
|
||||
|
||||
_heat_reses_example = [
|
||||
_heat_reses_example_base = [
|
||||
{
|
||||
"creation_time": "2021-12-10T00:40:46Z",
|
||||
"resource_name": "VDU2",
|
||||
@ -183,21 +260,6 @@ _heat_reses_example = [
|
||||
],
|
||||
"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",
|
||||
"resource_name": "VDU2_CP5",
|
||||
@ -437,22 +499,6 @@ _heat_reses_example = [
|
||||
],
|
||||
"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",
|
||||
"resource_name": "VDU1_CP1",
|
||||
@ -564,22 +610,6 @@ _heat_reses_example = [
|
||||
],
|
||||
"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",
|
||||
"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 = {
|
||||
"flavourId": "simple",
|
||||
"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):
|
||||
|
||||
@ -1258,6 +1807,7 @@ class TestOpenstack(base.BaseTestCase):
|
||||
|
||||
if "extVirtualLinkInfo" in expected:
|
||||
self.assertIn("extVirtualLinkInfo", result)
|
||||
result["extVirtualLinkInfo"].sort(key=_get_key)
|
||||
for ext_vl in result["extVirtualLinkInfo"]:
|
||||
if "extLinkPorts" in ext_vl:
|
||||
ext_vl["extLinkPorts"].sort(key=_get_key)
|
||||
@ -1350,3 +1900,30 @@ class TestOpenstack(base.BaseTestCase):
|
||||
# check
|
||||
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||
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)
|
||||
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):
|
||||
hot_dict = self.vnfd_1.get_base_hot(SAMPLE_FLAVOUR_ID)
|
||||
top_hot = hot_dict['template']
|
||||
|
Loading…
x
Reference in New Issue
Block a user