Merge "change_vnfpkg enhance to enable network change"
This commit is contained in:
commit
b267c46855
@ -0,0 +1,9 @@
|
||||
features:
|
||||
- |
|
||||
Support Change Current VNF Package API to
|
||||
add and delete external Connection Point (CP).
|
||||
Support `extManagedVirtualLinks` attribute
|
||||
in ChangeCurrentVnfPkgRequest to change
|
||||
external management networks.
|
||||
These support only when using StandardUserData
|
||||
as the UserData class.
|
@ -53,7 +53,13 @@ class HeatClient(object):
|
||||
|
||||
def update_stack(self, stack_name, fields, wait=True):
|
||||
path = f"stacks/{stack_name}"
|
||||
resp, body = self.client.do_request(path, "PATCH",
|
||||
# It was assumed that PATCH is used and therefore 'fields'
|
||||
# contains only update parts and 'existing' is not used.
|
||||
# Now full replacing 'fields' is supported and it is indicated
|
||||
# by 'existing' is False. if 'existing' is specified and
|
||||
# it is False, PUT is used.
|
||||
method = "PATCH" if fields.pop('existing', True) else "PUT"
|
||||
resp, body = self.client.do_request(path, method,
|
||||
expected_status=[202], body=fields)
|
||||
|
||||
if wait:
|
||||
@ -107,7 +113,7 @@ class HeatClient(object):
|
||||
LOG.info("%s %s done.", operation, stack_name.split('/')[0])
|
||||
raise loopingcall.LoopingCallDone()
|
||||
elif status in failed_status:
|
||||
LOG.error("% %s failed.", operation, stack_name.split('/')[0])
|
||||
LOG.error("%s %s failed.", operation, stack_name.split('/')[0])
|
||||
sol_title = "%s failed" % operation
|
||||
raise sol_ex.StackOperationFailed(sol_title=sol_title,
|
||||
sol_detail=status_reason)
|
||||
|
@ -126,11 +126,22 @@ class Openstack(object):
|
||||
stack_name = heat_utils.get_stack_name(inst)
|
||||
heat_client.delete_stack(stack_name)
|
||||
|
||||
def _is_full_fields(self, fields):
|
||||
# NOTE: fields made by UserData class contains only update parts
|
||||
# and 'existing' is not specified (and is thought as True) by
|
||||
# default. if 'existing' is specified and it is False, fields is
|
||||
# a full content.
|
||||
return not fields.get('existing', True)
|
||||
|
||||
def _update_fields(self, heat_client, stack_name, fields):
|
||||
if self._is_full_fields(fields):
|
||||
# used by change_vnfpkg(, rollback) only at the moment.
|
||||
return fields
|
||||
|
||||
if 'nfv' in fields.get('parameters', {}):
|
||||
parameters = heat_client.get_parameters(stack_name)
|
||||
LOG.debug("ORIG parameters: %s", parameters)
|
||||
# NOTE: parameters['nfv'] is string
|
||||
# NOTE: Using json.loads because parameters['nfv'] is string
|
||||
orig_nfv_dict = json.loads(parameters.get('nfv', '{}'))
|
||||
fields['parameters']['nfv'] = inst_utils.json_merge_patch(
|
||||
orig_nfv_dict, fields['parameters']['nfv'])
|
||||
@ -334,6 +345,10 @@ class Openstack(object):
|
||||
vdu_name = _rsc_with_idx(vnfc.vduId, vnfc.metadata.get('vdu_idx'))
|
||||
return vdu_dict.get(vdu_name, {}).get('computeFlavourId')
|
||||
|
||||
def _get_zone_from_vdu_dict(self, vnfc, vdu_dict):
|
||||
vdu_name = _rsc_with_idx(vnfc.vduId, vnfc.metadata.get('vdu_idx'))
|
||||
return vdu_dict.get(vdu_name, {}).get('locationConstraints')
|
||||
|
||||
def _get_images_from_vdu_dict(self, vnfc, storage_infos, vdu_dict):
|
||||
vdu_idx = vnfc.metadata.get('vdu_idx')
|
||||
vdu_name = _rsc_with_idx(vnfc.vduId, vdu_idx)
|
||||
@ -364,6 +379,20 @@ class Openstack(object):
|
||||
for vnfc in inst.instantiatedVnfInfo.vnfcResourceInfo
|
||||
if vnfc.computeResource.resourceId in vnfc_res_ids]
|
||||
|
||||
if self._is_full_fields(fields):
|
||||
# NOTE: it is used by StandardUserData only at the moment,
|
||||
# use it to check the fields is constructed by
|
||||
# StandardUserData (and its inheritance) or not.
|
||||
method = self._change_vnfpkg_rolling_update_user_data_standard
|
||||
else:
|
||||
# method for DefaultUserData (and its inheritance)
|
||||
method = self._change_vnfpkg_rolling_update_user_data_default
|
||||
|
||||
method(req, inst, grant_req, grant, vnfd, fields, heat_client,
|
||||
vnfcs, is_rollback)
|
||||
|
||||
def _change_vnfpkg_rolling_update_user_data_default(self, req, inst,
|
||||
grant_req, grant, vnfd, fields, heat_client, vnfcs, is_rollback):
|
||||
templates = {}
|
||||
|
||||
def _get_template(parent_stack_id):
|
||||
@ -400,8 +429,7 @@ class Openstack(object):
|
||||
heat_client.update_stack(parent_stack_id, vdu_fields)
|
||||
else:
|
||||
# pickup 'vcImageId' and 'computeFlavourId' from vdu_dict
|
||||
vdu_idx = vnfc.metadata.get('vdu_idx')
|
||||
vdu_name = _rsc_with_idx(vnfc.vduId, vdu_idx)
|
||||
vdu_name = vnfc.vduId
|
||||
new_vdus = {}
|
||||
flavor = self._get_flavor_from_vdu_dict(vnfc, vdu_dict)
|
||||
if flavor:
|
||||
@ -418,17 +446,14 @@ class Openstack(object):
|
||||
# pickup 'CP' updates
|
||||
cp_names = vnfd.get_vdu_cps(
|
||||
inst.instantiatedVnfInfo.flavourId, vnfc.vduId)
|
||||
new_cps = {}
|
||||
for cp_name in cp_names:
|
||||
cp_name = _rsc_with_idx(cp_name, vdu_idx)
|
||||
if cp_name in cp_dict:
|
||||
new_cps[cp_name] = cp_dict[cp_name]
|
||||
new_cps = {cp_name: cp_dict[cp_name]
|
||||
for cp_name in cp_names if cp_name in cp_dict}
|
||||
|
||||
update_fields = {
|
||||
'parameters': {'nfv': {'VDU': new_vdus, 'CP': new_cps}}
|
||||
}
|
||||
update_fields = self._update_fields(heat_client, stack_name,
|
||||
update_fields)
|
||||
update_fields)
|
||||
LOG.debug("stack fields: %s", update_fields)
|
||||
heat_client.update_stack(stack_name, update_fields)
|
||||
|
||||
@ -436,6 +461,80 @@ class Openstack(object):
|
||||
self._execute_coordinate_vnf_script(req, vnfd, vnfc, heat_client,
|
||||
is_rollback)
|
||||
|
||||
def _change_vnfpkg_rolling_update_user_data_standard(self, req, inst,
|
||||
grant_req, grant, vnfd, fields, heat_client, vnfcs, is_rollback):
|
||||
stack_name = heat_utils.get_stack_name(inst)
|
||||
|
||||
# make base template
|
||||
base_template = heat_client.get_template(stack_name)
|
||||
new_template = yaml.safe_load(fields['template'])
|
||||
diff_reses = {
|
||||
res_name: res_value
|
||||
for res_name, res_value in new_template['resources'].items()
|
||||
if res_name not in base_template['resources'].keys()
|
||||
}
|
||||
base_template['resources'].update(diff_reses)
|
||||
|
||||
base_files = heat_client.get_files(stack_name)
|
||||
base_files.update(fields['files'])
|
||||
|
||||
base_parameters = heat_client.get_parameters(stack_name)
|
||||
# NOTE: Using json.loads because parameters['nfv'] is string
|
||||
base_nfv_dict = json.loads(base_parameters.get('nfv', '{}'))
|
||||
new_nfv_dict = fields['parameters']['nfv']
|
||||
|
||||
def _get_param_third_keys(res):
|
||||
"""Get third parameter keys
|
||||
|
||||
example:
|
||||
---
|
||||
VDU1-1:
|
||||
type: VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1-1, computeFlavourId ] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1-1, vcImageId ] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1-1, network ] }
|
||||
---
|
||||
returns {'VDU1-1', 'VDU1_CP1-1'}
|
||||
"""
|
||||
|
||||
keys = set()
|
||||
for prop_value in res.get('properties', {}).values():
|
||||
if not isinstance(prop_value, dict):
|
||||
continue
|
||||
for key, value in prop_value.items():
|
||||
if (key == 'get_param' and isinstance(value, list) and
|
||||
len(value) >= 4 and value[0] == 'nfv'):
|
||||
keys.add(value[2])
|
||||
return keys
|
||||
|
||||
for vnfc in vnfcs:
|
||||
vdu_idx = vnfc.metadata.get('vdu_idx')
|
||||
vdu_name = _rsc_with_idx(vnfc.vduId, vdu_idx)
|
||||
|
||||
# replace VDU_{idx} part
|
||||
target_res = new_template['resources'][vdu_name]
|
||||
base_template['resources'][vdu_name] = target_res
|
||||
|
||||
# update parameters
|
||||
third_keys = _get_param_third_keys(target_res)
|
||||
for item in ['VDU', 'CP']:
|
||||
for key, value in new_nfv_dict.get(item, {}).items():
|
||||
if key in third_keys:
|
||||
base_nfv_dict[item][key] = value
|
||||
|
||||
update_fields = {
|
||||
'template': base_template,
|
||||
'files': base_files,
|
||||
'parameters': {'nfv': base_nfv_dict}
|
||||
}
|
||||
LOG.debug("update %s: stack fields: %s", vdu_name, update_fields)
|
||||
heat_client.update_stack(stack_name, update_fields)
|
||||
|
||||
# execute coordinate_vnf_script
|
||||
self._execute_coordinate_vnf_script(req, vnfd, vnfc, heat_client,
|
||||
is_rollback)
|
||||
|
||||
def _get_ssh_ip(self, stack_id, cp_name, heat_client):
|
||||
# NOTE: It is assumed that if the user want to use floating_ip,
|
||||
# he must specify the resource name of 'OS::Neutron::FloatingIP'
|
||||
@ -997,6 +1096,10 @@ class Openstack(object):
|
||||
storage_infos, nfv_dict['VDU'])
|
||||
for vdu_name, image in images.items():
|
||||
metadata[f'image-{vdu_name}'] = image
|
||||
zone = self._get_zone_from_vdu_dict(vnfc_res_info,
|
||||
nfv_dict['VDU'])
|
||||
if zone is not None:
|
||||
metadata['zone'] = zone
|
||||
|
||||
def _make_instantiated_vnf_info(self, req, inst, grant_req, grant, vnfd,
|
||||
heat_client, is_rollback=False, stack_id=None):
|
||||
@ -1005,6 +1108,7 @@ class Openstack(object):
|
||||
'stack_id']
|
||||
stack_name = heat_utils.get_stack_name(inst, stack_id)
|
||||
heat_reses = heat_client.get_resources(stack_name)
|
||||
# NOTE: Using json.loads because parameters['nfv'] is string
|
||||
nfv_dict = json.loads(heat_client.get_parameters(stack_name)['nfv'])
|
||||
|
||||
op = grant_req.operation
|
||||
|
@ -137,24 +137,24 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
top_hot = hot_dict['template']
|
||||
|
||||
# first modify VDU resources
|
||||
poped_vdu = {}
|
||||
popped_vdu = {}
|
||||
vdu_idxes = {}
|
||||
for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
|
||||
poped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
vdu_idxes[vdu_name] = 0
|
||||
zones = {}
|
||||
for res in grant_req['addResources']:
|
||||
if res['type'] != 'COMPUTE':
|
||||
continue
|
||||
vdu_name = res['resourceTemplateId']
|
||||
if vdu_name not in poped_vdu:
|
||||
if vdu_name not in popped_vdu:
|
||||
continue
|
||||
vdu_idx = vdu_idxes[vdu_name]
|
||||
vdu_idxes[vdu_name] += 1
|
||||
zones[add_idx(vdu_name, vdu_idx)] = (
|
||||
common_script_utils.get_param_zone_by_vnfc(
|
||||
res['id'], grant))
|
||||
res = add_idx_to_vdu_template(poped_vdu[vdu_name], vdu_idx)
|
||||
res = add_idx_to_vdu_template(popped_vdu[vdu_name], vdu_idx)
|
||||
top_hot['resources'][add_idx(vdu_name, vdu_idx)] = res
|
||||
|
||||
nfv_dict = common_script_utils.init_nfv_dict(top_hot)
|
||||
@ -231,10 +231,10 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
top_hot = hot_dict['template']
|
||||
|
||||
# first modify VDU resources
|
||||
poped_vdu = {}
|
||||
popped_vdu = {}
|
||||
vdu_idxes = {}
|
||||
for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
|
||||
poped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
vdu_idxes[vdu_name] = common_script_utils.get_current_capacity(
|
||||
vdu_name, inst)
|
||||
|
||||
@ -243,14 +243,14 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
if res['type'] != 'COMPUTE':
|
||||
continue
|
||||
vdu_name = res['resourceTemplateId']
|
||||
if vdu_name not in poped_vdu:
|
||||
if vdu_name not in popped_vdu:
|
||||
continue
|
||||
vdu_idx = vdu_idxes[vdu_name]
|
||||
vdu_idxes[vdu_name] += 1
|
||||
zones[add_idx(vdu_name, vdu_idx)] = (
|
||||
common_script_utils.get_param_zone_by_vnfc(
|
||||
res['id'], grant))
|
||||
res = add_idx_to_vdu_template(poped_vdu[vdu_name], vdu_idx)
|
||||
res = add_idx_to_vdu_template(popped_vdu[vdu_name], vdu_idx)
|
||||
top_hot['resources'][add_idx(vdu_name, vdu_idx)] = res
|
||||
|
||||
nfv_dict = common_script_utils.init_nfv_dict(top_hot)
|
||||
@ -393,9 +393,9 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
top_hot = hot_dict['template']
|
||||
|
||||
# first modify VDU resources
|
||||
poped_vdu = {}
|
||||
popped_vdu = {}
|
||||
for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
|
||||
poped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
|
||||
for inst_vnfc in inst['instantiatedVnfInfo'].get(
|
||||
'vnfcResourceInfo', []):
|
||||
@ -403,7 +403,7 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
if vdu_idx is None:
|
||||
continue
|
||||
vdu_name = inst_vnfc['vduId']
|
||||
res = add_idx_to_vdu_template(poped_vdu[vdu_name], vdu_idx)
|
||||
res = add_idx_to_vdu_template(popped_vdu[vdu_name], vdu_idx)
|
||||
top_hot['resources'][add_idx(vdu_name, vdu_idx)] = res
|
||||
|
||||
nfv_dict = common_script_utils.init_nfv_dict(top_hot)
|
||||
@ -424,9 +424,9 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
top_hot = hot_dict['template']
|
||||
|
||||
# first modify VDU resources
|
||||
poped_vdu = {}
|
||||
popped_vdu = {}
|
||||
for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
|
||||
poped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
|
||||
for inst_vnfc in inst['instantiatedVnfInfo'].get(
|
||||
'vnfcResourceInfo', []):
|
||||
@ -434,7 +434,7 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
if vdu_idx is None:
|
||||
continue
|
||||
vdu_name = inst_vnfc['vduId']
|
||||
res = add_idx_to_vdu_template(poped_vdu[vdu_name], vdu_idx)
|
||||
res = add_idx_to_vdu_template(popped_vdu[vdu_name], vdu_idx)
|
||||
top_hot['resources'][add_idx(vdu_name, vdu_idx)] = res
|
||||
|
||||
nfv_dict = common_script_utils.init_nfv_dict(top_hot)
|
||||
@ -455,9 +455,9 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
top_hot = hot_dict['template']
|
||||
|
||||
# first modify VDU resources
|
||||
poped_vdu = {}
|
||||
popped_vdu = {}
|
||||
for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
|
||||
poped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
|
||||
for res in grant_req['removeResources']:
|
||||
if res['type'] != 'COMPUTE':
|
||||
@ -469,7 +469,7 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
vdu_idx = inst_vnfc['metadata']['vdu_idx']
|
||||
break
|
||||
vdu_name = res['resourceTemplateId']
|
||||
res = add_idx_to_vdu_template(poped_vdu[vdu_name], vdu_idx)
|
||||
res = add_idx_to_vdu_template(popped_vdu[vdu_name], vdu_idx)
|
||||
top_hot['resources'][add_idx(vdu_name, vdu_idx)] = res
|
||||
|
||||
nfv_dict = common_script_utils.init_nfv_dict(top_hot)
|
||||
@ -499,28 +499,65 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
top_hot = hot_dict['template']
|
||||
|
||||
# first modify VDU resources
|
||||
poped_vdu = {}
|
||||
popped_vdu = {}
|
||||
for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
|
||||
poped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
|
||||
for res in grant_req['removeResources']:
|
||||
if res['type'] != 'COMPUTE':
|
||||
target_vnfc_res_ids = [
|
||||
res['resource']['resourceId']
|
||||
for res in grant_req['removeResources']
|
||||
if res['type'] == 'COMPUTE'
|
||||
]
|
||||
|
||||
cur_hot_reses = {}
|
||||
new_hot_reses = {}
|
||||
images = {}
|
||||
flavors = {}
|
||||
zones = {}
|
||||
for inst_vnfc in inst['instantiatedVnfInfo']['vnfcResourceInfo']:
|
||||
vdu_idx = inst_vnfc['metadata'].get('vdu_idx')
|
||||
if vdu_idx is None:
|
||||
# should not be None. just check for consistency.
|
||||
continue
|
||||
for inst_vnfc in inst['instantiatedVnfInfo']['vnfcResourceInfo']:
|
||||
if (inst_vnfc['computeResource']['resourceId'] ==
|
||||
res['resource']['resourceId']):
|
||||
# must be found
|
||||
vdu_idx = inst_vnfc['metadata']['vdu_idx']
|
||||
break
|
||||
vdu_name = res['resourceTemplateId']
|
||||
res = add_idx_to_vdu_template(poped_vdu[vdu_name], vdu_idx)
|
||||
top_hot['resources'][add_idx(vdu_name, vdu_idx)] = res
|
||||
vdu_name = inst_vnfc['vduId']
|
||||
vdu_name_idx = add_idx(vdu_name, vdu_idx)
|
||||
|
||||
nfv_dict = common_script_utils.init_nfv_dict(top_hot)
|
||||
res = add_idx_to_vdu_template(popped_vdu[vdu_name], vdu_idx)
|
||||
top_hot['resources'][vdu_name_idx] = res
|
||||
|
||||
vdus = nfv_dict.get('VDU', {})
|
||||
for vdu_name, vdu_value in vdus.items():
|
||||
vdu_name = rm_idx(vdu_name)
|
||||
if (inst_vnfc['computeResource']['resourceId'] in
|
||||
target_vnfc_res_ids):
|
||||
new_hot_reses[vdu_name_idx] = res
|
||||
else:
|
||||
cur_hot_reses[vdu_name_idx] = res
|
||||
|
||||
# NOTE: only zone is necessary for new_hot_reses
|
||||
for key, value in inst_vnfc['metadata'].items():
|
||||
if key == 'flavor':
|
||||
flavors[vdu_name_idx] = value
|
||||
elif key == 'zone':
|
||||
zones[vdu_name_idx] = value
|
||||
elif key.startswith('image-'):
|
||||
image_vdu = key.replace('image-', '')
|
||||
images[image_vdu] = value
|
||||
|
||||
cur_nfv_dict = common_script_utils.init_nfv_dict(
|
||||
{'resources': cur_hot_reses})
|
||||
new_nfv_dict = common_script_utils.init_nfv_dict(
|
||||
{'resources': new_hot_reses})
|
||||
cur_vdus = cur_nfv_dict.get('VDU', {})
|
||||
new_vdus = new_nfv_dict.get('VDU', {})
|
||||
|
||||
for vdu_name_idx, vdu_value in cur_vdus.items():
|
||||
if 'computeFlavourId' in vdu_value:
|
||||
vdu_value['computeFlavourId'] = flavors.get(vdu_name_idx)
|
||||
if 'vcImageId' in vdu_value:
|
||||
vdu_value['vcImageId'] = images.get(vdu_name_idx)
|
||||
if 'locationConstraints' in vdu_value:
|
||||
vdu_value['locationConstraints'] = zones.get(vdu_name_idx)
|
||||
|
||||
for vdu_name_idx, vdu_value in new_vdus.items():
|
||||
vdu_name = rm_idx(vdu_name_idx)
|
||||
if 'computeFlavourId' in vdu_value:
|
||||
vdu_value['computeFlavourId'] = (
|
||||
common_script_utils.get_param_flavor(
|
||||
@ -529,14 +566,33 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
vdu_value['vcImageId'] = common_script_utils.get_param_image(
|
||||
vdu_name, flavour_id, vnfd, grant)
|
||||
if 'locationConstraints' in vdu_value:
|
||||
vdu_value.pop('locationConstraints')
|
||||
vdu_value['locationConstraints'] = zones.get(vdu_name_idx)
|
||||
|
||||
cps = nfv_dict.get('CP', {})
|
||||
new_cps = _get_new_cps_from_req(cps, req, grant)
|
||||
vdus = cur_vdus
|
||||
vdus.update(new_vdus)
|
||||
|
||||
cps = cur_nfv_dict.get('CP', {})
|
||||
cps.update(new_nfv_dict.get('CP', {}))
|
||||
# NOTE: req includes only different part. some CPs in new_nfv_dict
|
||||
# may be necessary to get from inst.
|
||||
cur_cps = _get_new_cps_from_inst(cps, inst)
|
||||
req_cps = _get_new_cps_from_req(cps, req, grant)
|
||||
for cp_name in cps.keys():
|
||||
if cp_name in req_cps:
|
||||
cps[cp_name] = req_cps[cp_name]
|
||||
else:
|
||||
cps[cp_name] = cur_cps[cp_name]
|
||||
|
||||
common_script_utils.apply_ext_managed_vls(top_hot, req, grant)
|
||||
|
||||
fields = {
|
||||
'parameters': {'nfv': {'VDU': vdus, 'CP': new_cps}}
|
||||
'template': yaml.safe_dump(top_hot),
|
||||
'parameters': {'nfv': {'VDU': vdus, 'CP': cps}},
|
||||
'files': {},
|
||||
'existing': False
|
||||
}
|
||||
for key, value in hot_dict.get('files', {}).items():
|
||||
fields['files'][key] = yaml.safe_dump(value)
|
||||
|
||||
return fields
|
||||
|
||||
@ -549,56 +605,57 @@ class StandardUserData(userdata_utils.AbstractUserData):
|
||||
top_hot = hot_dict['template']
|
||||
|
||||
# first modify VDU resources
|
||||
poped_vdu = {}
|
||||
popped_vdu = {}
|
||||
for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
|
||||
poped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
|
||||
for res in grant_req['removeResources']:
|
||||
if res['type'] != 'COMPUTE':
|
||||
continue
|
||||
for inst_vnfc in inst['instantiatedVnfInfo']['vnfcResourceInfo']:
|
||||
if (inst_vnfc['computeResource']['resourceId'] ==
|
||||
res['resource']['resourceId']):
|
||||
# must be found
|
||||
vdu_idx = inst_vnfc['metadata']['vdu_idx']
|
||||
break
|
||||
vdu_name = res['resourceTemplateId']
|
||||
res = add_idx_to_vdu_template(poped_vdu[vdu_name], vdu_idx)
|
||||
top_hot['resources'][add_idx(vdu_name, vdu_idx)] = res
|
||||
|
||||
nfv_dict = common_script_utils.init_nfv_dict(top_hot)
|
||||
popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
|
||||
|
||||
images = {}
|
||||
flavors = {}
|
||||
zones = {}
|
||||
for inst_vnfc in inst['instantiatedVnfInfo']['vnfcResourceInfo']:
|
||||
vdu_idx = inst_vnfc['metadata'].get('vdu_idx')
|
||||
if vdu_idx is None:
|
||||
# should not be None. just check for consistency.
|
||||
continue
|
||||
vdu_name = inst_vnfc['vduId']
|
||||
if vdu_name in flavors:
|
||||
continue
|
||||
vdu_name_idx = add_idx(vdu_name, vdu_idx)
|
||||
|
||||
res = add_idx_to_vdu_template(popped_vdu[vdu_name], vdu_idx)
|
||||
top_hot['resources'][vdu_name_idx] = res
|
||||
|
||||
for key, value in inst_vnfc['metadata'].items():
|
||||
if key == 'flavor':
|
||||
flavors[add_idx(vdu_name, vdu_idx)] = value
|
||||
flavors[vdu_name_idx] = value
|
||||
elif key == 'zone':
|
||||
zones[vdu_name_idx] = value
|
||||
elif key.startswith('image-'):
|
||||
image_vdu = key.replace('image-', '')
|
||||
images[image_vdu] = value
|
||||
|
||||
nfv_dict = common_script_utils.init_nfv_dict(top_hot)
|
||||
|
||||
vdus = nfv_dict.get('VDU', {})
|
||||
new_vdus = {}
|
||||
for vdu_name, vdu_value in vdus.items():
|
||||
for vdu_name_idx, vdu_value in vdus.items():
|
||||
vdu_name = rm_idx(vdu_name)
|
||||
if 'computeFlavourId' in vdu_value:
|
||||
new_vdus.setdefault(vdu_name, {})
|
||||
new_vdus[vdu_name]['computeFlavourId'] = flavors.get(vdu_name)
|
||||
vdu_value['computeFlavourId'] = flavors.get(vdu_name_idx)
|
||||
if 'vcImageId' in vdu_value:
|
||||
new_vdus.setdefault(vdu_name, {})
|
||||
new_vdus[vdu_name]['vcImageId'] = images.get(vdu_name)
|
||||
vdu_value['vcImageId'] = images.get(vdu_name_idx)
|
||||
if 'locationConstraints' in vdu_value:
|
||||
vdu_value['locationConstraints'] = zones.get(vdu_name_idx)
|
||||
|
||||
cps = nfv_dict.get('CP', {})
|
||||
new_cps = _get_new_cps_from_inst(cps, inst)
|
||||
|
||||
common_script_utils.apply_ext_managed_vls(top_hot, req, grant)
|
||||
|
||||
fields = {
|
||||
'parameters': {'nfv': {'VDU': new_vdus, 'CP': new_cps}}
|
||||
'template': yaml.safe_dump(top_hot),
|
||||
'parameters': {'nfv': {'VDU': vdus, 'CP': new_cps}},
|
||||
'files': {},
|
||||
'existing': False
|
||||
}
|
||||
for key, value in hot_dict.get('files', {}).items():
|
||||
fields['files'][key] = yaml.safe_dump(value)
|
||||
|
||||
return fields
|
||||
|
@ -30,8 +30,6 @@ class ChangeCurrentVnfPkgRequest(base.TackerObject,
|
||||
'vnfdId': fields.StringField(nullable=False),
|
||||
'extVirtualLinks': fields.ListOfObjectsField(
|
||||
'ExtVirtualLinkData', nullable=True),
|
||||
# NOTE: 'extManagedVirtualLinks' is not supported.
|
||||
# It can be specified but make no effect at all.
|
||||
'extManagedVirtualLinks': fields.ListOfObjectsField(
|
||||
'ExtManagedVirtualLinkData', nullable=True),
|
||||
'vimConnectionInfo': fields.DictOfObjectsField(
|
||||
|
@ -53,11 +53,18 @@ class IndividualVnfcMgmtTest(test_vnflcm_basic_common.CommonVnfLcmTest):
|
||||
cls.vnf_pkg_2, cls.vnfd_id_2 = cls.create_vnf_package(
|
||||
pkg_path_2, image_path=image_path, userdata_path=userdata_path)
|
||||
|
||||
# for change_vnfpkg network/flavor change test
|
||||
pkg_path_3 = os.path.join(cur_dir,
|
||||
"../sol_v2_common/samples/userdata_standard_change_vnfpkg_nw")
|
||||
cls.vnf_pkg_3, cls.vnfd_id_3 = cls.create_vnf_package(
|
||||
pkg_path_3, image_path=image_path, userdata_path=userdata_path)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
super(IndividualVnfcMgmtTest, cls).tearDownClass()
|
||||
cls.delete_vnf_package(cls.vnf_pkg_1)
|
||||
cls.delete_vnf_package(cls.vnf_pkg_2)
|
||||
cls.delete_vnf_package(cls.vnf_pkg_3)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@ -86,7 +93,12 @@ class IndividualVnfcMgmtTest(test_vnflcm_basic_common.CommonVnfLcmTest):
|
||||
vnfc = self._get_vnfc_by_vdu_index(inst, vdu, index)
|
||||
return vnfc['id']
|
||||
|
||||
def _get_vnfc_cps(self, inst, vdu, index):
|
||||
vnfc = self._get_vnfc_by_vdu_index(inst, vdu, index)
|
||||
return {cp_info['cpdId'] for cp_info in vnfc['vnfcCpInfo']}
|
||||
|
||||
def _get_vnfc_cp_net_id(self, inst, vdu, index, cp):
|
||||
# this is for external CPs
|
||||
vnfc = self._get_vnfc_by_vdu_index(inst, vdu, index)
|
||||
for cp_info in vnfc['vnfcCpInfo']:
|
||||
if cp_info['cpdId'] == cp:
|
||||
@ -99,6 +111,20 @@ class IndividualVnfcMgmtTest(test_vnflcm_basic_common.CommonVnfLcmTest):
|
||||
# must be found
|
||||
return ext_vl['resourceHandle']['resourceId']
|
||||
|
||||
def _get_vnfc_cp_net_name(self, inst, vdu, index, cp):
|
||||
# this is for internal CPs
|
||||
vnfc = self._get_vnfc_by_vdu_index(inst, vdu, index)
|
||||
for cp_info in vnfc['vnfcCpInfo']:
|
||||
if cp_info['cpdId'] == cp:
|
||||
# must be found
|
||||
link_port_id = cp_info['vnfLinkPortId']
|
||||
break
|
||||
for vl in inst['instantiatedVnfInfo']['vnfVirtualLinkResourceInfo']:
|
||||
for port in vl['vnfLinkPorts']:
|
||||
if port['id'] == link_port_id:
|
||||
# must be found
|
||||
return vl['vnfVirtualLinkDescId']
|
||||
|
||||
def _get_vnfc_image(self, inst, vdu, index):
|
||||
vnfc = self._get_vnfc_by_vdu_index(inst, vdu, index)
|
||||
for key, value in vnfc['metadata'].items():
|
||||
@ -106,6 +132,11 @@ class IndividualVnfcMgmtTest(test_vnflcm_basic_common.CommonVnfLcmTest):
|
||||
# must be found
|
||||
return value
|
||||
|
||||
def _get_vnfc_flavor(self, inst, vdu, index):
|
||||
vnfc = self._get_vnfc_by_vdu_index(inst, vdu, index)
|
||||
# must exist
|
||||
return vnfc['metadata']['flavor']
|
||||
|
||||
def _delete_instance(self, inst_id):
|
||||
for _ in range(3):
|
||||
resp, body = self.delete_vnf_instance(inst_id)
|
||||
@ -559,3 +590,224 @@ class IndividualVnfcMgmtTest(test_vnflcm_basic_common.CommonVnfLcmTest):
|
||||
|
||||
# Delete VNF instance
|
||||
self._delete_instance(inst_id)
|
||||
|
||||
def test_change_vnfpkg_nw(self):
|
||||
"""Test change_vnfpkg with additional functions
|
||||
|
||||
* Note:
|
||||
This test focuses change_vnfpkg with the following changes.
|
||||
- adding external CP
|
||||
- change internal network
|
||||
- change flavor
|
||||
|
||||
TODO: add anoter patterns (ex. change extMgdVLs)
|
||||
|
||||
* About LCM operations:
|
||||
This test includes the following operations.
|
||||
- Create VNF instance
|
||||
- 1. Instantiate VNF instance
|
||||
- Show VNF instance / check
|
||||
- 2. Change_vnfpkg operation
|
||||
- Show VNF instance / check
|
||||
- Terminate VNF instance
|
||||
- Delete VNF instance
|
||||
"""
|
||||
|
||||
net_ids = self.get_network_ids(['net0', 'net1', 'net_mgmt'])
|
||||
subnet_ids = self.get_subnet_ids(['subnet0', 'subnet1'])
|
||||
|
||||
# Create VNF instance
|
||||
create_req = paramgen.sample3_create(self.vnfd_id_1)
|
||||
resp, body = self.create_vnf_instance(create_req)
|
||||
self.assertEqual(201, resp.status_code)
|
||||
inst_id = body['id']
|
||||
|
||||
# 1. Instantiate VNF instance
|
||||
instantiate_req = paramgen.sample3_instantiate(
|
||||
net_ids, subnet_ids, self.auth_url)
|
||||
instantiate_req['instantiationLevelId'] = "instantiation_level_2"
|
||||
resp, body = self.instantiate_vnf_instance(inst_id, instantiate_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
# Show VNF instance
|
||||
resp, inst_1 = self.show_vnf_instance(inst_id)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# check number of VDUs and indexes
|
||||
self.assertEqual({0, 1}, self._get_vdu_indexes(inst_1, 'VDU1'))
|
||||
self.assertEqual({0}, self._get_vdu_indexes(inst_1, 'VDU2'))
|
||||
|
||||
# 2. Change_vnfpkg operation
|
||||
change_vnfpkg_req = paramgen.sample5_change_vnfpkg(self.vnfd_id_3,
|
||||
net_ids, subnet_ids)
|
||||
resp, body = self.change_vnfpkg(inst_id, change_vnfpkg_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
# Show VNF instance
|
||||
resp, inst_2 = self.show_vnf_instance(inst_id)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# check vnfdId is changed
|
||||
self.assertEqual(self.vnfd_id_3, inst_2['vnfdId'])
|
||||
# check images are changed
|
||||
self.assertNotEqual(self._get_vnfc_image(inst_1, 'VDU1', 0),
|
||||
self._get_vnfc_image(inst_2, 'VDU1', 0))
|
||||
self.assertNotEqual(self._get_vnfc_image(inst_1, 'VDU1', 1),
|
||||
self._get_vnfc_image(inst_2, 'VDU1', 1))
|
||||
self.assertNotEqual(self._get_vnfc_image(inst_1, 'VDU2', 0),
|
||||
self._get_vnfc_image(inst_2, 'VDU2', 0))
|
||||
# check flavor is changed (VDU2 only)
|
||||
self.assertNotEqual(self._get_vnfc_flavor(inst_1, 'VDU2', 0),
|
||||
self._get_vnfc_flavor(inst_2, 'VDU2', 0))
|
||||
# check external CPs; VDU1_CP4 and VDU2_CP4 are added
|
||||
self.assertFalse('VDU1_CP4' in self._get_vnfc_cps(inst_1, 'VDU1', 0))
|
||||
self.assertFalse('VDU1_CP4' in self._get_vnfc_cps(inst_1, 'VDU1', 1))
|
||||
self.assertFalse('VDU2_CP4' in self._get_vnfc_cps(inst_1, 'VDU2', 0))
|
||||
self.assertTrue('VDU1_CP4' in self._get_vnfc_cps(inst_2, 'VDU1', 0))
|
||||
self.assertTrue('VDU1_CP4' in self._get_vnfc_cps(inst_2, 'VDU1', 1))
|
||||
self.assertTrue('VDU2_CP4' in self._get_vnfc_cps(inst_2, 'VDU2', 0))
|
||||
self.assertEqual(net_ids['net0'],
|
||||
self._get_vnfc_cp_net_id(inst_2, 'VDU1', 0, 'VDU1_CP4'))
|
||||
self.assertEqual(net_ids['net0'],
|
||||
self._get_vnfc_cp_net_id(inst_2, 'VDU1', 1, 'VDU1_CP4'))
|
||||
self.assertEqual(net_ids['net0'],
|
||||
self._get_vnfc_cp_net_id(inst_2, 'VDU2', 0, 'VDU2_CP4'))
|
||||
# check internal CPs; VDU1_CP3 and VDU2_CP3 are changed
|
||||
self.assertEqual("internalVL2",
|
||||
self._get_vnfc_cp_net_name(inst_1, 'VDU1', 0, 'VDU1_CP3'))
|
||||
self.assertEqual("internalVL2",
|
||||
self._get_vnfc_cp_net_name(inst_1, 'VDU1', 1, 'VDU1_CP3'))
|
||||
self.assertEqual("internalVL2",
|
||||
self._get_vnfc_cp_net_name(inst_1, 'VDU2', 0, 'VDU2_CP3'))
|
||||
self.assertEqual("internalVL3",
|
||||
self._get_vnfc_cp_net_name(inst_2, 'VDU1', 0, 'VDU1_CP3'))
|
||||
self.assertEqual("internalVL3",
|
||||
self._get_vnfc_cp_net_name(inst_2, 'VDU1', 1, 'VDU1_CP3'))
|
||||
self.assertEqual("internalVL3",
|
||||
self._get_vnfc_cp_net_name(inst_2, 'VDU2', 0, 'VDU2_CP3'))
|
||||
|
||||
# Terminate VNF instance
|
||||
terminate_req = paramgen.sample5_terminate()
|
||||
resp, body = self.terminate_vnf_instance(inst_id, terminate_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
# Delete VNF instance
|
||||
self._delete_instance(inst_id)
|
||||
|
||||
def test_change_vnfpkg_nw_rollback(self):
|
||||
"""Test rollback of change_vnfpkg with additional functions
|
||||
|
||||
* Note:
|
||||
This test focuses rollback of change_vnfpkg with the following
|
||||
changes.
|
||||
- adding external CP
|
||||
- change internal network
|
||||
- change flavor
|
||||
|
||||
TODO: add anoter patterns (ex. change extMgdVLs)
|
||||
|
||||
* About LCM operations:
|
||||
This test includes the following operations.
|
||||
- Create VNF instance
|
||||
- 1. Instantiate VNF instance
|
||||
- Show VNF instance / check
|
||||
- 2. Change_vnfpkg operation => FAILED_TEMP
|
||||
- Rollback
|
||||
- Show VNF instance / check
|
||||
- Terminate VNF instance
|
||||
- Delete VNF instance
|
||||
"""
|
||||
|
||||
net_ids = self.get_network_ids(['net0', 'net1', 'net_mgmt'])
|
||||
subnet_ids = self.get_subnet_ids(['subnet0', 'subnet1'])
|
||||
|
||||
# Create VNF instance
|
||||
create_req = paramgen.sample3_create(self.vnfd_id_1)
|
||||
resp, body = self.create_vnf_instance(create_req)
|
||||
self.assertEqual(201, resp.status_code)
|
||||
inst_id = body['id']
|
||||
|
||||
# 1. Instantiate VNF instance
|
||||
instantiate_req = paramgen.sample3_instantiate(
|
||||
net_ids, subnet_ids, self.auth_url)
|
||||
instantiate_req['instantiationLevelId'] = "instantiation_level_2"
|
||||
resp, body = self.instantiate_vnf_instance(inst_id, instantiate_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
# Show VNF instance
|
||||
resp, inst_1 = self.show_vnf_instance(inst_id)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# check number of VDUs and indexes
|
||||
self.assertEqual({0, 1}, self._get_vdu_indexes(inst_1, 'VDU1'))
|
||||
self.assertEqual({0}, self._get_vdu_indexes(inst_1, 'VDU2'))
|
||||
|
||||
# 2. Change_vnfpkg operation
|
||||
self._put_fail_file('change_vnfpkg')
|
||||
change_vnfpkg_req = paramgen.sample5_change_vnfpkg(self.vnfd_id_3,
|
||||
net_ids, subnet_ids)
|
||||
resp, body = self.change_vnfpkg(inst_id, change_vnfpkg_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_failed_temp(lcmocc_id)
|
||||
self._rm_fail_file('change_vnfpkg')
|
||||
|
||||
# Rollback
|
||||
resp, body = self.rollback_lcmocc(lcmocc_id)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
self.wait_lcmocc_rolled_back(lcmocc_id)
|
||||
|
||||
# Show VNF instance
|
||||
resp, inst_2 = self.show_vnf_instance(inst_id)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# check vnfdId is not changed
|
||||
self.assertEqual(self.vnfd_id_1, inst_2['vnfdId'])
|
||||
# check images are not changed
|
||||
self.assertEqual(self._get_vnfc_image(inst_1, 'VDU1', 0),
|
||||
self._get_vnfc_image(inst_2, 'VDU1', 0))
|
||||
self.assertEqual(self._get_vnfc_image(inst_1, 'VDU1', 1),
|
||||
self._get_vnfc_image(inst_2, 'VDU1', 1))
|
||||
self.assertEqual(self._get_vnfc_image(inst_1, 'VDU2', 0),
|
||||
self._get_vnfc_image(inst_2, 'VDU2', 0))
|
||||
# check flavor is not changed (VDU2 only)
|
||||
self.assertEqual(self._get_vnfc_flavor(inst_1, 'VDU2', 0),
|
||||
self._get_vnfc_flavor(inst_2, 'VDU2', 0))
|
||||
# check external CPs; VDU1_CP4 and VDU2_CP4 are not added
|
||||
self.assertFalse('VDU1_CP4' in self._get_vnfc_cps(inst_2, 'VDU1', 0))
|
||||
self.assertFalse('VDU1_CP4' in self._get_vnfc_cps(inst_2, 'VDU1', 1))
|
||||
self.assertFalse('VDU2_CP4' in self._get_vnfc_cps(inst_2, 'VDU2', 0))
|
||||
# check internal CPs; VDU1_CP3 and VDU2_CP3 are not changed
|
||||
self.assertEqual(
|
||||
self._get_vnfc_cp_net_name(inst_1, 'VDU1', 0, 'VDU1_CP3'),
|
||||
self._get_vnfc_cp_net_name(inst_2, 'VDU1', 0, 'VDU1_CP3'))
|
||||
self.assertEqual(
|
||||
self._get_vnfc_cp_net_name(inst_1, 'VDU1', 1, 'VDU1_CP3'),
|
||||
self._get_vnfc_cp_net_name(inst_2, 'VDU1', 1, 'VDU1_CP3'))
|
||||
self.assertEqual(
|
||||
self._get_vnfc_cp_net_name(inst_1, 'VDU2', 0, 'VDU2_CP3'),
|
||||
self._get_vnfc_cp_net_name(inst_2, 'VDU2', 0, 'VDU2_CP3'))
|
||||
|
||||
# Terminate VNF instance
|
||||
terminate_req = paramgen.sample3_terminate()
|
||||
resp, body = self.terminate_vnf_instance(inst_id, terminate_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
|
||||
lcmocc_id = os.path.basename(resp.headers['Location'])
|
||||
self.wait_lcmocc_complete(lcmocc_id)
|
||||
|
||||
# Delete VNF instance
|
||||
self._delete_instance(inst_id)
|
||||
|
@ -1015,7 +1015,7 @@ def sample3_instantiate(net_ids, subnet_ids, auth_url):
|
||||
"extVirtualLinks": [ext_vl_1],
|
||||
"extManagedVirtualLinks": [
|
||||
{
|
||||
"id": uuidutils.generate_uuid(),
|
||||
"id": "ext_managed_vl_1",
|
||||
"vnfVirtualLinkDescId": "internalVL1",
|
||||
"resourceId": net_ids['net_mgmt']
|
||||
},
|
||||
@ -1141,6 +1141,13 @@ def sample4_change_vnfpkg(vnfd_id, net_ids, subnet_ids):
|
||||
]
|
||||
}
|
||||
],
|
||||
"extManagedVirtualLinks": [
|
||||
{
|
||||
"id": "ext_managed_vl_1",
|
||||
"vnfVirtualLinkDescId": "internalVL1",
|
||||
"resourceId": net_ids['net_mgmt']
|
||||
},
|
||||
],
|
||||
"additionalParams": {
|
||||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-new-vnf": "./Scripts/coordinate_vnf.py",
|
||||
@ -1197,3 +1204,139 @@ def server_notification(alarm_id):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# sample5 is for change_vnfpkg network change test of StandardUserData
|
||||
#
|
||||
def sample5_change_vnfpkg(vnfd_id, net_ids, subnet_ids):
|
||||
ext_vl_4 = {
|
||||
"id": "ext_vl_id_net4",
|
||||
"resourceId": net_ids['net0'],
|
||||
"extCps": [
|
||||
{
|
||||
"cpdId": "VDU1_CP4",
|
||||
"cpConfig": {
|
||||
"VDU1_CP4_1": {
|
||||
"cpProtocolData": [{
|
||||
"layerProtocol": "IP_OVER_ETHERNET",
|
||||
"ipOverEthernet": {
|
||||
"ipAddresses": [{
|
||||
"type": "IPV4",
|
||||
"numDynamicAddresses": 1}]}}]}
|
||||
}
|
||||
},
|
||||
{
|
||||
"cpdId": "VDU2_CP4",
|
||||
"cpConfig": {
|
||||
"VDU2_CP4_1": {
|
||||
"cpProtocolData": [{
|
||||
"layerProtocol": "IP_OVER_ETHERNET",
|
||||
"ipOverEthernet": {
|
||||
"ipAddresses": [{
|
||||
"type": "IPV4",
|
||||
"numDynamicAddresses": 1}]}}]}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
return {
|
||||
"vnfdId": vnfd_id,
|
||||
"extVirtualLinks": [ext_vl_4],
|
||||
"extManagedVirtualLinks": [
|
||||
{
|
||||
"id": "ext_managed_vl_1",
|
||||
"vnfVirtualLinkDescId": "internalVL1",
|
||||
"resourceId": net_ids['net_mgmt']
|
||||
},
|
||||
],
|
||||
"additionalParams": {
|
||||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-new-vnf": "./Scripts/coordinate_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf": "./Scripts/coordinate_vnf.py",
|
||||
"vdu_params": [
|
||||
{
|
||||
"vdu_id": "VDU1",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "VDU1_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "VDU1_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
}
|
||||
},
|
||||
{
|
||||
"vdu_id": "VDU2",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "VDU2_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "VDU2_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
}
|
||||
}
|
||||
],
|
||||
"lcm-operation-user-data": "./UserData/userdata_standard.py",
|
||||
"lcm-operation-user-data-class": "StandardUserData"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def sample5_change_vnfpkg_back(vnfd_id, net_ids, subnet_ids):
|
||||
return {
|
||||
"vnfdId": vnfd_id,
|
||||
"extManagedVirtualLinks": [
|
||||
{
|
||||
"id": "ext_managed_vl_1",
|
||||
"vnfVirtualLinkDescId": "internalVL1",
|
||||
"resourceId": net_ids['net_mgmt']
|
||||
},
|
||||
],
|
||||
"additionalParams": {
|
||||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-new-vnf": "./Scripts/coordinate_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf": "./Scripts/coordinate_vnf.py",
|
||||
"vdu_params": [
|
||||
{
|
||||
"vdu_id": "VDU1",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "VDU1_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "VDU1_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
}
|
||||
},
|
||||
{
|
||||
"vdu_id": "VDU2",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "VDU2_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "VDU2_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
}
|
||||
}
|
||||
],
|
||||
"lcm-operation-user-data": "./UserData/userdata_standard.py",
|
||||
"lcm-operation-user-data-class": "StandardUserData"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def sample5_terminate():
|
||||
return {
|
||||
"terminationType": "FORCEFUL"
|
||||
}
|
||||
|
@ -45,7 +45,8 @@ resources:
|
||||
multi:
|
||||
type: OS::Cinder::VolumeType
|
||||
properties:
|
||||
name: VDU2-multi
|
||||
# making unique name to avoid conflicting with other packages
|
||||
name: { list_join: ['-', [get_param: OS::stack_name, 'VDU2-multi']] }
|
||||
metadata: { multiattach: "<is> True" }
|
||||
|
||||
# extVL with numDynamicAddresses and subnet
|
||||
|
@ -1,5 +1,5 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'Simple Base HOT for Sample VNF'
|
||||
description: 'For Test of Individual Vnfc Management: sample3'
|
||||
|
||||
parameters:
|
||||
nfv:
|
||||
|
@ -6,14 +6,14 @@ parameters:
|
||||
type: string
|
||||
image-VDU1:
|
||||
type: string
|
||||
zone:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
net2:
|
||||
type: string
|
||||
net3:
|
||||
type: string
|
||||
affinity:
|
||||
type: string
|
||||
|
||||
resources:
|
||||
VDU1:
|
||||
@ -25,14 +25,13 @@ resources:
|
||||
networks:
|
||||
- port:
|
||||
get_resource: VDU1_CP1
|
||||
# replace the following line to Port ID when extmanagedVLs' Ports are
|
||||
# specified in instantiatevnfrequest
|
||||
# replace the following line to Port ID when extManagedVLs' Ports are
|
||||
# specified in InstantiateVnfRequest
|
||||
- port:
|
||||
get_resource: VDU1_CP2
|
||||
- port:
|
||||
get_resource: VDU1_CP3
|
||||
scheduler_hints:
|
||||
group: { get_param: affinity }
|
||||
availability_zone: { get_param: zone }
|
||||
|
||||
# extVL without FixedIP or with numDynamicAddresses
|
||||
VDU1_CP1:
|
||||
@ -40,8 +39,8 @@ resources:
|
||||
properties:
|
||||
network: { get_param: net1 }
|
||||
|
||||
# CPs of internal VLs are deleted when extmanagedVLs and port are
|
||||
# specified in instantiatevnfrequest
|
||||
# CPs of internal VLs are deleted when extManagedVLs and port are
|
||||
# specified in InstantiateVnfRequest
|
||||
VDU1_CP2:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
|
@ -27,8 +27,8 @@ resources:
|
||||
networks:
|
||||
- port:
|
||||
get_resource: VDU2_CP1
|
||||
# replace the following line to Port ID when extmanagedVLs' Ports are
|
||||
# specified in instantiatevnfrequest
|
||||
# replace the following line to Port ID when extManagedVLs' Ports are
|
||||
# specified in InstantiateVnfRequest
|
||||
- port:
|
||||
get_resource: VDU2_CP2
|
||||
- port:
|
||||
@ -45,7 +45,8 @@ resources:
|
||||
multi:
|
||||
type: OS::Cinder::VolumeType
|
||||
properties:
|
||||
name: VDU2-multi
|
||||
# making unique name to avoid conflicting with other packages
|
||||
name: { list_join: ['-', [get_param: OS::stack_name, 'VDU2-multi']] }
|
||||
metadata: { multiattach: "<is> True" }
|
||||
|
||||
# extVL with numDynamicAddresses and subnet
|
||||
@ -56,8 +57,8 @@ resources:
|
||||
fixed_ips:
|
||||
- subnet: { get_param: subnet1 }
|
||||
|
||||
# CPs of internal VLs are deleted when extmanagedVLs and port are
|
||||
# specified in instantiatevnfrequest
|
||||
# CPs of internal VLs are deleted when extManagedVLs and port are
|
||||
# specified in InstantiateVnfRequest
|
||||
VDU2_CP2:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
|
@ -1,5 +1,5 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'Simple Base HOT for Sample VNF'
|
||||
description: 'For Test of Individual Vnfc Management: sample4'
|
||||
|
||||
parameters:
|
||||
nfv:
|
||||
@ -11,10 +11,10 @@ resources:
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
zone: { get_param: [ nfv, VDU, VDU1, locationConstraints] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network ] }
|
||||
net2: { get_resource: internalVL1 }
|
||||
net3: { get_resource: internalVL2 }
|
||||
affinity: { get_resource: nfvi_node_affinity }
|
||||
|
||||
VDU2:
|
||||
type: VDU2.yaml
|
||||
@ -27,7 +27,7 @@ resources:
|
||||
net3: { get_resource: internalVL2 }
|
||||
affinity: { get_resource: nfvi_node_affinity }
|
||||
|
||||
# delete the following lines when extmanagedVLs are specified in instantiatevnfrequest
|
||||
# delete the following lines when extManagedVLs are specified in InstantiateVnfRequest
|
||||
internalVL1:
|
||||
type: OS::Neutron::Net
|
||||
internalVL2:
|
||||
|
@ -0,0 +1,61 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'VDU1 HOT for Sample VNF'
|
||||
|
||||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image-VDU1:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
net2:
|
||||
type: string
|
||||
net3:
|
||||
type: string
|
||||
net4:
|
||||
type: string
|
||||
zone:
|
||||
type: string
|
||||
|
||||
resources:
|
||||
VDU1:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
name: VDU1
|
||||
image: { get_param: image-VDU1 }
|
||||
networks:
|
||||
- port:
|
||||
get_resource: VDU1_CP1
|
||||
# replace the following line to Port ID when extManagedVLs' Ports are
|
||||
# specified in InstantiateVnfRequest
|
||||
- port:
|
||||
get_resource: VDU1_CP2
|
||||
- port:
|
||||
get_resource: VDU1_CP3
|
||||
- port:
|
||||
get_resource: VDU1_CP4
|
||||
availability_zone: { get_param: zone }
|
||||
|
||||
# extVL without FixedIP or with numDynamicAddresses
|
||||
VDU1_CP1:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net1 }
|
||||
|
||||
VDU1_CP4:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net4 }
|
||||
|
||||
# CPs of internal VLs are deleted when extManagedVLs and port are
|
||||
# specified in InstantiateVnfRequest
|
||||
VDU1_CP2:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net2 }
|
||||
|
||||
VDU1_CP3:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net3 }
|
@ -0,0 +1,79 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'VDU2 HOT for Sample VNF'
|
||||
|
||||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image-VDU2-VirtualStorage:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
net2:
|
||||
type: string
|
||||
net3:
|
||||
type: string
|
||||
net4:
|
||||
type: string
|
||||
subnet1:
|
||||
type: string
|
||||
affinity:
|
||||
type: string
|
||||
|
||||
resources:
|
||||
VDU2:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
name: VDU2
|
||||
block_device_mapping_v2: [{"volume_id": { get_resource: VDU2-VirtualStorage }}]
|
||||
networks:
|
||||
- port:
|
||||
get_resource: VDU2_CP1
|
||||
# replace the following line to Port ID when extManagedVLs' Ports are
|
||||
# specified in InstantiateVnfRequest
|
||||
- port:
|
||||
get_resource: VDU2_CP2
|
||||
- port:
|
||||
get_resource: VDU2_CP3
|
||||
- port:
|
||||
get_resource: VDU2_CP4
|
||||
scheduler_hints:
|
||||
group: {get_param: affinity }
|
||||
|
||||
VDU2-VirtualStorage:
|
||||
type: OS::Cinder::Volume
|
||||
properties:
|
||||
image: { get_param: image-VDU2-VirtualStorage }
|
||||
size: 1
|
||||
volume_type: { get_resource: multi }
|
||||
multi:
|
||||
type: OS::Cinder::VolumeType
|
||||
properties:
|
||||
# making unique name to avoid conflicting with other packages
|
||||
name: { list_join: ['-', [get_param: OS::stack_name, 'VDU2-multi']] }
|
||||
metadata: { multiattach: "<is> True" }
|
||||
|
||||
# extVL with numDynamicAddresses and subnet
|
||||
VDU2_CP1:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net1 }
|
||||
fixed_ips:
|
||||
- subnet: { get_param: subnet1 }
|
||||
|
||||
VDU2_CP4:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net4 }
|
||||
|
||||
# CPs of internal VLs are deleted when extManagedVLs and port are
|
||||
# specified in InstantiateVnfRequest
|
||||
VDU2_CP2:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net2 }
|
||||
|
||||
VDU2_CP3:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net3 }
|
@ -0,0 +1,59 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'For Test of Individual Vnfc Management: sample5'
|
||||
|
||||
parameters:
|
||||
nfv:
|
||||
type: json
|
||||
|
||||
resources:
|
||||
VDU1:
|
||||
type: VDU1-ver2.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network ] }
|
||||
net2: { get_resource: internalVL1 }
|
||||
net3: { get_resource: internalVL3 }
|
||||
net4: { get_param: [ nfv, CP, VDU1_CP4, network ] }
|
||||
zone: { get_param: [ nfv, VDU, VDU1, locationConstraints ] }
|
||||
|
||||
VDU2:
|
||||
type: VDU2-ver2.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU2, computeFlavourId ] }
|
||||
image-VDU2-VirtualStorage: { get_param: [ nfv, VDU, VDU2-VirtualStorage, vcImageId ] }
|
||||
net1: { get_param: [ nfv, CP, VDU2_CP1, network ] }
|
||||
subnet1: { get_param: [nfv, CP, VDU2_CP1, fixed_ips, 0, subnet ]}
|
||||
net2: { get_resource: internalVL1 }
|
||||
net3: { get_resource: internalVL3 }
|
||||
net4: { get_param: [ nfv, CP, VDU2_CP4, network ] }
|
||||
affinity: { get_resource: nfvi_node_affinity }
|
||||
|
||||
# delete the following lines when extManagedVLs are specified in InstantiateVnfRequest
|
||||
internalVL1:
|
||||
type: OS::Neutron::Net
|
||||
internalVL3:
|
||||
type: OS::Neutron::Net
|
||||
|
||||
internalVL1_subnet:
|
||||
type: OS::Neutron::Subnet
|
||||
properties:
|
||||
ip_version: 4
|
||||
network:
|
||||
get_resource: internalVL1
|
||||
cidr: 192.168.3.0/24
|
||||
internalVL3_subnet:
|
||||
type: OS::Neutron::Subnet
|
||||
properties:
|
||||
ip_version: 4
|
||||
network:
|
||||
get_resource: internalVL3
|
||||
cidr: 192.168.5.0/24
|
||||
|
||||
nfvi_node_affinity:
|
||||
type: OS::Nova::ServerGroup
|
||||
properties:
|
||||
name: nfvi_node_affinity
|
||||
policies: [ 'affinity' ]
|
||||
|
||||
outputs: {}
|
@ -0,0 +1,375 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: Simple deployment flavour for Sample VNF
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
- v2_sample5_types.yaml
|
||||
|
||||
topology_template:
|
||||
inputs:
|
||||
descriptor_id:
|
||||
type: string
|
||||
descriptor_version:
|
||||
type: string
|
||||
provider:
|
||||
type: string
|
||||
product_name:
|
||||
type: string
|
||||
software_version:
|
||||
type: string
|
||||
vnfm_info:
|
||||
type: list
|
||||
entry_schema:
|
||||
type: string
|
||||
flavour_id:
|
||||
type: string
|
||||
flavour_description:
|
||||
type: string
|
||||
|
||||
substitution_mappings:
|
||||
node_type: company.provider.VNF
|
||||
properties:
|
||||
flavour_id: simple
|
||||
requirements:
|
||||
virtual_link_external1_1: [ VDU1_CP1, virtual_link ]
|
||||
virtual_link_external1_2: [ VDU2_CP1, virtual_link ]
|
||||
virtual_link_external1_3: [ VDU1_CP4, virtual_link ]
|
||||
virtual_link_external1_4: [ VDU2_CP4, virtual_link ]
|
||||
|
||||
node_templates:
|
||||
VNF:
|
||||
type: company.provider.VNF
|
||||
properties:
|
||||
flavour_description: A simple flavour
|
||||
interfaces:
|
||||
Vnflcm:
|
||||
instantiate_start:
|
||||
implementation: sample-script
|
||||
instantiate_end:
|
||||
implementation: sample-script
|
||||
terminate_start:
|
||||
implementation: sample-script
|
||||
terminate_end:
|
||||
implementation: sample-script
|
||||
scale_start:
|
||||
implementation: sample-script
|
||||
scale_end:
|
||||
implementation: sample-script
|
||||
heal_start:
|
||||
implementation: sample-script
|
||||
heal_end:
|
||||
implementation: sample-script
|
||||
change_external_connectivity_start:
|
||||
implementation: sample-script
|
||||
change_external_connectivity_end:
|
||||
implementation: sample-script
|
||||
modify_information_start:
|
||||
implementation: sample-script
|
||||
modify_information_end:
|
||||
implementation: sample-script
|
||||
artifacts:
|
||||
sample-script:
|
||||
description: Sample script
|
||||
type: tosca.artifacts.Implementation.Python
|
||||
file: ../Scripts/sample_script.py
|
||||
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.Vdu.Compute
|
||||
properties:
|
||||
name: VDU1
|
||||
description: VDU1 compute node
|
||||
vdu_profile:
|
||||
min_number_of_instances: 1
|
||||
max_number_of_instances: 3
|
||||
sw_image_data:
|
||||
name: VDU1-image
|
||||
version: '0.5.2'
|
||||
checksum:
|
||||
algorithm: sha-256
|
||||
hash: 932fcae93574e242dc3d772d5235061747dfe537668443a1f0567d893614b464
|
||||
container_format: bare
|
||||
disk_format: qcow2
|
||||
min_disk: 0 GB
|
||||
min_ram: 256 MB
|
||||
size: 12 GB
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
requested_additional_capabilities:
|
||||
properties:
|
||||
requested_additional_capability_name: m1.tiny
|
||||
support_mandatory: true
|
||||
target_performance_parameters:
|
||||
entry_schema: test
|
||||
virtual_memory:
|
||||
virtual_mem_size: 512 MB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 3 GB
|
||||
artifacts:
|
||||
sw_image:
|
||||
type: tosca.artifacts.nfv.SwImage
|
||||
file: ../Files/images/cirros-0.5.2-x86_64-disk.img
|
||||
|
||||
VDU2:
|
||||
type: tosca.nodes.nfv.Vdu.Compute
|
||||
properties:
|
||||
name: VDU2
|
||||
description: VDU2 compute node
|
||||
vdu_profile:
|
||||
min_number_of_instances: 1
|
||||
max_number_of_instances: 1
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
requested_additional_capabilities:
|
||||
properties:
|
||||
requested_additional_capability_name: m1.small
|
||||
support_mandatory: true
|
||||
target_performance_parameters:
|
||||
entry_schema: test
|
||||
virtual_memory:
|
||||
virtual_mem_size: 2048 MB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 3 GB
|
||||
requirements:
|
||||
- virtual_storage: VDU2-VirtualStorage
|
||||
|
||||
VDU2-VirtualStorage:
|
||||
type: tosca.nodes.nfv.Vdu.VirtualBlockStorage
|
||||
properties:
|
||||
virtual_block_storage_data:
|
||||
size_of_storage: 1 GB
|
||||
rdma_enabled: true
|
||||
sw_image_data:
|
||||
name: cirros-0.5.2-x86_64-disk
|
||||
version: '0.5.2'
|
||||
checksum:
|
||||
algorithm: sha-256
|
||||
hash: 932fcae93574e242dc3d772d5235061747dfe537668443a1f0567d893614b464
|
||||
container_format: bare
|
||||
disk_format: qcow2
|
||||
min_disk: 0 GB
|
||||
min_ram: 256 MB
|
||||
size: 12 GB
|
||||
|
||||
VDU1_CP1:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 0
|
||||
requirements:
|
||||
- virtual_binding: VDU1
|
||||
|
||||
VDU1_CP2:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 1
|
||||
requirements:
|
||||
- virtual_binding: VDU1
|
||||
- virtual_link: internalVL1
|
||||
|
||||
VDU1_CP3:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 2
|
||||
requirements:
|
||||
- virtual_binding: VDU1
|
||||
- virtual_link: internalVL3
|
||||
|
||||
VDU1_CP4:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 0
|
||||
requirements:
|
||||
- virtual_binding: VDU1
|
||||
|
||||
VDU2_CP1:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 0
|
||||
requirements:
|
||||
- virtual_binding: VDU2
|
||||
|
||||
VDU2_CP2:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 1
|
||||
requirements:
|
||||
- virtual_binding: VDU2
|
||||
- virtual_link: internalVL1
|
||||
|
||||
VDU2_CP3:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 2
|
||||
requirements:
|
||||
- virtual_binding: VDU2
|
||||
- virtual_link: internalVL3
|
||||
|
||||
VDU2_CP4:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 0
|
||||
requirements:
|
||||
- virtual_binding: VDU2
|
||||
|
||||
internalVL1:
|
||||
type: tosca.nodes.nfv.VnfVirtualLink
|
||||
properties:
|
||||
connectivity_type:
|
||||
layer_protocols: [ ipv4 ]
|
||||
description: External Managed Virtual link in the VNF
|
||||
vl_profile:
|
||||
max_bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
min_bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
virtual_link_protocol_data:
|
||||
- associated_layer_protocol: ipv4
|
||||
l3_protocol_data:
|
||||
ip_version: ipv4
|
||||
cidr: 192.168.3.0/24
|
||||
|
||||
internalVL3:
|
||||
type: tosca.nodes.nfv.VnfVirtualLink
|
||||
properties:
|
||||
connectivity_type:
|
||||
layer_protocols: [ ipv4 ]
|
||||
description: External Managed Virtual link in the VNF
|
||||
vl_profile:
|
||||
max_bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
min_bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
virtual_link_protocol_data:
|
||||
- associated_layer_protocol: ipv4
|
||||
l3_protocol_data:
|
||||
ip_version: ipv4
|
||||
cidr: 192.168.5.0/24
|
||||
|
||||
groups:
|
||||
affinityOrAntiAffinityGroup1:
|
||||
type: tosca.groups.nfv.PlacementGroup
|
||||
members: [ VDU1, VDU2 ]
|
||||
|
||||
policies:
|
||||
- scaling_aspects:
|
||||
type: tosca.policies.nfv.ScalingAspects
|
||||
properties:
|
||||
aspects:
|
||||
VDU1_scale:
|
||||
name: VDU1_scale
|
||||
description: VDU1 scaling aspect
|
||||
max_scale_level: 2
|
||||
step_deltas:
|
||||
- delta_1
|
||||
|
||||
- VDU1_initial_delta:
|
||||
type: tosca.policies.nfv.VduInitialDelta
|
||||
properties:
|
||||
initial_delta:
|
||||
number_of_instances: 1
|
||||
targets: [ VDU1 ]
|
||||
|
||||
- VDU2_initial_delta:
|
||||
type: tosca.policies.nfv.VduInitialDelta
|
||||
properties:
|
||||
initial_delta:
|
||||
number_of_instances: 1
|
||||
targets: [ VDU2 ]
|
||||
|
||||
- VDU1_scaling_aspect_deltas:
|
||||
type: tosca.policies.nfv.VduScalingAspectDeltas
|
||||
properties:
|
||||
aspect: VDU1_scale
|
||||
deltas:
|
||||
delta_1:
|
||||
number_of_instances: 1
|
||||
targets: [ VDU1 ]
|
||||
|
||||
- instantiation_levels:
|
||||
type: tosca.policies.nfv.InstantiationLevels
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
description: Smallest size
|
||||
scale_info:
|
||||
VDU1_scale:
|
||||
scale_level: 0
|
||||
instantiation_level_2:
|
||||
description: Largest size
|
||||
scale_info:
|
||||
VDU1_scale:
|
||||
scale_level: 1
|
||||
default_level: instantiation_level_1
|
||||
|
||||
- VDU1_instantiation_levels:
|
||||
type: tosca.policies.nfv.VduInstantiationLevels
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
number_of_instances: 1
|
||||
instantiation_level_2:
|
||||
number_of_instances: 2
|
||||
targets: [ VDU1 ]
|
||||
|
||||
- VDU2_instantiation_levels:
|
||||
type: tosca.policies.nfv.VduInstantiationLevels
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
number_of_instances: 1
|
||||
instantiation_level_2:
|
||||
number_of_instances: 1
|
||||
targets: [ VDU2 ]
|
||||
|
||||
- internalVL1_instantiation_levels:
|
||||
type: tosca.policies.nfv.VirtualLinkInstantiationLevels
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
instantiation_level_2:
|
||||
bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
targets: [ internalVL1 ]
|
||||
|
||||
- internalVL3_instantiation_levels:
|
||||
type: tosca.policies.nfv.VirtualLinkInstantiationLevels
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
instantiation_level_2:
|
||||
bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
targets: [ internalVL3 ]
|
||||
|
||||
- policy_antiaffinity_group:
|
||||
type: tosca.policies.nfv.AntiAffinityRule
|
||||
targets: [ affinityOrAntiAffinityGroup1 ]
|
||||
properties:
|
||||
scope: nfvi_node
|
@ -0,0 +1,31 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: Sample VNF
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
- v2_sample5_types.yaml
|
||||
- v2_sample5_df_simple.yaml
|
||||
|
||||
topology_template:
|
||||
inputs:
|
||||
selected_flavour:
|
||||
type: string
|
||||
description: VNF deployment flavour selected by the consumer. It is provided in the API
|
||||
|
||||
node_templates:
|
||||
VNF:
|
||||
type: company.provider.VNF
|
||||
properties:
|
||||
flavour_id: { get_input: selected_flavour }
|
||||
descriptor_id: b1bb0ce7-ebca-4fa7-95ed-4840d7000000
|
||||
provider: Company
|
||||
product_name: Sample VNF
|
||||
software_version: '1.0'
|
||||
descriptor_version: '1.0'
|
||||
vnfm_info:
|
||||
- Tacker
|
||||
requirements:
|
||||
#- virtual_link_external # mapped in lower-level templates
|
||||
#- virtual_link_internal # mapped in lower-level templates
|
@ -0,0 +1,55 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: VNF type definition
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
|
||||
node_types:
|
||||
company.provider.VNF:
|
||||
derived_from: tosca.nodes.nfv.VNF
|
||||
properties:
|
||||
descriptor_id:
|
||||
type: string
|
||||
constraints: [ valid_values: [ b1bb0ce7-ebca-4fa7-95ed-4840d7000000 ] ]
|
||||
default: b1bb0ce7-ebca-4fa7-95ed-4840d7000000
|
||||
descriptor_version:
|
||||
type: string
|
||||
constraints: [ valid_values: [ '1.0' ] ]
|
||||
default: '1.0'
|
||||
provider:
|
||||
type: string
|
||||
constraints: [ valid_values: [ 'Company' ] ]
|
||||
default: 'Company'
|
||||
product_name:
|
||||
type: string
|
||||
constraints: [ valid_values: [ 'Sample VNF' ] ]
|
||||
default: 'Sample VNF'
|
||||
software_version:
|
||||
type: string
|
||||
constraints: [ valid_values: [ '1.0' ] ]
|
||||
default: '1.0'
|
||||
vnfm_info:
|
||||
type: list
|
||||
entry_schema:
|
||||
type: string
|
||||
constraints: [ valid_values: [ Tacker ] ]
|
||||
default: [ Tacker ]
|
||||
flavour_id:
|
||||
type: string
|
||||
constraints: [ valid_values: [ simple ] ]
|
||||
default: simple
|
||||
flavour_description:
|
||||
type: string
|
||||
default: "flavour"
|
||||
requirements:
|
||||
- virtual_link_external1:
|
||||
capability: tosca.capabilities.nfv.VirtualLinkable
|
||||
- virtual_link_external2:
|
||||
capability: tosca.capabilities.nfv.VirtualLinkable
|
||||
- virtual_link_internal:
|
||||
capability: tosca.capabilities.nfv.VirtualLinkable
|
||||
interfaces:
|
||||
Vnflcm:
|
||||
type: tosca.interfaces.nfv.Vnflcm
|
@ -0,0 +1,46 @@
|
||||
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
import pickle
|
||||
import sys
|
||||
|
||||
|
||||
class FailScript(object):
|
||||
def __init__(self, vnfc_param):
|
||||
self.vnfc_param = vnfc_param
|
||||
|
||||
def run(self):
|
||||
operation = 'change_vnfpkg'
|
||||
if self.vnfc_param['is_rollback']:
|
||||
operation += '_rollback'
|
||||
if os.path.exists(f'/tmp/{operation}'):
|
||||
raise Exception(f'test {operation} error')
|
||||
|
||||
|
||||
def main():
|
||||
vnfc_param = pickle.load(sys.stdin.buffer)
|
||||
script = FailScript(vnfc_param)
|
||||
script.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
os._exit(0)
|
||||
except Exception as ex:
|
||||
sys.stderr.write(str(ex))
|
||||
sys.stderr.flush()
|
||||
os._exit(1)
|
@ -0,0 +1,68 @@
|
||||
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import functools
|
||||
import os
|
||||
import pickle
|
||||
import sys
|
||||
|
||||
|
||||
class FailScript(object):
|
||||
"""Define error method for each operation
|
||||
|
||||
For example:
|
||||
|
||||
def instantiate_start(self):
|
||||
if os.path.exists('/tmp/instantiate_start')
|
||||
raise Exception('test instantiate_start error')
|
||||
"""
|
||||
|
||||
def __init__(self, req, inst, grant_req, grant, csar_dir):
|
||||
self.req = req
|
||||
self.inst = inst
|
||||
self.grant_req = grant_req
|
||||
self.grant = grant
|
||||
self.csar_dir = csar_dir
|
||||
|
||||
def _fail(self, method):
|
||||
if os.path.exists(f'/tmp/{method}'):
|
||||
raise Exception(f'test {method} error')
|
||||
|
||||
def __getattr__(self, name):
|
||||
return functools.partial(self._fail, name)
|
||||
|
||||
|
||||
def main():
|
||||
script_dict = pickle.load(sys.stdin.buffer)
|
||||
|
||||
operation = script_dict['operation']
|
||||
req = script_dict['request']
|
||||
inst = script_dict['vnf_instance']
|
||||
grant_req = script_dict['grant_request']
|
||||
grant = script_dict['grant_response']
|
||||
csar_dir = script_dict['tmp_csar_dir']
|
||||
|
||||
script = FailScript(req, inst, grant_req, grant, csar_dir)
|
||||
getattr(script, operation)()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
os._exit(0)
|
||||
except Exception as ex:
|
||||
sys.stderr.write(str(ex))
|
||||
sys.stderr.flush()
|
||||
os._exit(1)
|
@ -0,0 +1,4 @@
|
||||
TOSCA-Meta-File-Version: 1.0
|
||||
CSAR-Version: 1.1
|
||||
Created-by: Onboarding portal
|
||||
Entry-Definitions: Definitions/v2_sample5_top.vnfd.yaml
|
@ -0,0 +1,60 @@
|
||||
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from tacker.tests.functional.sol_v2_common import paramgen
|
||||
from tacker.tests.functional.sol_v2_common import utils
|
||||
|
||||
|
||||
zip_file_name = os.path.basename(os.path.abspath(".")) + '.zip'
|
||||
tmp_dir = tempfile.mkdtemp()
|
||||
vnfd_id = uuidutils.generate_uuid()
|
||||
|
||||
# tacker/tests/etc...
|
||||
# /functional/sol_v2_common/samples/sampleX
|
||||
image_dir = "../../../../etc/samples/etsi/nfv/common/Files/images/"
|
||||
image_file = "cirros-0.5.2-x86_64-disk.img"
|
||||
image_path = os.path.abspath(image_dir + image_file)
|
||||
|
||||
# tacker/sol_refactored/infra_drivers/openstack/userdata_standard.py
|
||||
# /tests/functional/sol_v2_common/samples/sampleX
|
||||
userdata_dir = "../../../../../sol_refactored/infra_drivers/openstack/"
|
||||
userdata_file = "userdata_standard.py"
|
||||
userdata_path = os.path.abspath(userdata_dir + userdata_file)
|
||||
|
||||
utils.make_zip(".", tmp_dir, vnfd_id, image_path=image_path,
|
||||
userdata_path=userdata_path)
|
||||
|
||||
shutil.copy(os.path.join(tmp_dir, zip_file_name), ".")
|
||||
shutil.rmtree(tmp_dir)
|
||||
|
||||
net_ids = utils.get_network_ids(['net0', 'net1', 'net_mgmt'])
|
||||
subnet_ids = utils.get_subnet_ids(['subnet0', 'subnet1'])
|
||||
|
||||
change_vnfpkg_req = paramgen.sample5_change_vnfpkg(
|
||||
vnfd_id, net_ids, subnet_ids)
|
||||
change_vnfpkg_back_req = paramgen.sample5_change_vnfpkg_back(
|
||||
"input-original-vnfd-id", net_ids, subnet_ids)
|
||||
|
||||
with open("change_vnfpkg_req", "w") as f:
|
||||
f.write(json.dumps(change_vnfpkg_req, indent=2))
|
||||
with open("change_vnfpkg_back_req", "w") as f:
|
||||
f.write(json.dumps(change_vnfpkg_back_req, indent=2))
|
@ -735,9 +735,7 @@ _change_vnfpkg_example = {
|
||||
"additionalParams": {
|
||||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf": "./Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf": "./Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
|
||||
"vdu_params": [
|
||||
{
|
||||
"vdu_id": "VDU1",
|
||||
@ -769,9 +767,7 @@ _change_cnf_vnfpkg_example = {
|
||||
"additionalParams": {
|
||||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf": "Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf": "Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
|
||||
"lcm-kubernetes-def-files": [
|
||||
"Files/new_kubernetes/new_deployment.yaml"
|
||||
],
|
||||
|
@ -156,6 +156,70 @@ _instantiate_req_example = {
|
||||
}
|
||||
}
|
||||
|
||||
# example for test of StandardUserData
|
||||
_instantiate_req_example_S = {
|
||||
"flavourId": SAMPLE_FLAVOUR_ID,
|
||||
"extVirtualLinks": [
|
||||
{
|
||||
"id": "id_ext_vl_1",
|
||||
"resourceId": "res_id_ext_vl_1",
|
||||
"extCps": [
|
||||
{
|
||||
"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",
|
||||
"numDynamicAddresses": 1,
|
||||
"subnetId": "res_id_subnet"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"extManagedVirtualLinks": [
|
||||
{
|
||||
"id": "id_ext_mgd_1",
|
||||
"vnfVirtualLinkDescId": "internalVL1",
|
||||
"resourceId": "res_id_internalVL1"
|
||||
}
|
||||
],
|
||||
"vimConnectionInfo": {
|
||||
"vim1": _vim_connection_info_example
|
||||
}
|
||||
}
|
||||
|
||||
# ChangeExtVnfConnectivityRequest example
|
||||
_change_ext_conn_req_example = {
|
||||
"extVirtualLinks": [
|
||||
@ -233,54 +297,6 @@ _change_ext_conn_req_example = {
|
||||
]
|
||||
}
|
||||
|
||||
_change_vnfpkg_example = {
|
||||
"vnfdId": uuidutils.generate_uuid(),
|
||||
"additionalParams": {
|
||||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf": "Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf": "Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
|
||||
"vdu_params": [{
|
||||
"vdu_id": "VDU1",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
_change_vnfpkg_example_2 = {
|
||||
"vnfdId": uuidutils.generate_uuid(),
|
||||
"additionalParams": {
|
||||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf": "Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf": "Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
|
||||
"vdu_params": [{
|
||||
"vdu_id": "VDU2",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
# heat resources examples
|
||||
# NOTE:
|
||||
# - following attributes which are not related to tests are omitted.
|
||||
@ -848,6 +864,328 @@ _heat_reses_example = (
|
||||
_heat_reses_example_change_ext_conn = (
|
||||
_heat_reses_example_base + _heat_reses_example_cps_after)
|
||||
|
||||
# heat resources example for test of StandardUserData
|
||||
_stack_id_VDU1_0_S = (
|
||||
"vnf-881718c6-830b-4232-9e83-4b0cd7678713-VDU1-0-ntteaet43n2s/"
|
||||
"46c6328e-db32-4da0-8dee-c69079644982")
|
||||
_href_VDU1_0_S = "".join((_url, _stack_id_VDU1_0_S))
|
||||
|
||||
_stack_id_VDU1_1_S = (
|
||||
"vnf-881718c6-830b-4232-9e83-4b0cd7678713-VDU1-1-vswbicn4ezjc/"
|
||||
"64e143e1-49dc-4114-ad7c-5bb74cbd1efe")
|
||||
_href_VDU1_1_S = "".join((_url, _stack_id_VDU1_1_S))
|
||||
|
||||
_stack_id_VDU2_0_S = (
|
||||
"vnf-881718c6-830b-4232-9e83-4b0cd7678713-VDU2-0-hht2ozgyxu7q/"
|
||||
"f1398e13-26ca-4d87-93ef-883bac1f82f6")
|
||||
_href_VDU2_0_S = "".join((_url, _stack_id_VDU2_0_S))
|
||||
|
||||
_heat_reses_example_S = [
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:01Z",
|
||||
"resource_name": "VDU1-0",
|
||||
"physical_resource_id": "46c6328e-db32-4da0-8dee-c69079644982",
|
||||
"resource_type": "VDU1.yaml",
|
||||
"links": [
|
||||
{
|
||||
"href": _href,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": []
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:01Z",
|
||||
"resource_name": "VDU1-1",
|
||||
"physical_resource_id": "64e143e1-49dc-4114-ad7c-5bb74cbd1efe",
|
||||
"resource_type": "VDU1.yaml",
|
||||
"links": [
|
||||
{
|
||||
"href": _href,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": []
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:02Z",
|
||||
"resource_name": "internalVL2_subnet",
|
||||
"physical_resource_id": "acbd442b-00cc-4dfa-9243-8943673ff8cb",
|
||||
"resource_type": "OS::Neutron::Subnet",
|
||||
"links": [
|
||||
{
|
||||
"href": _href,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": []
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:02Z",
|
||||
"resource_name": "VDU2-0",
|
||||
"physical_resource_id": "f1398e13-26ca-4d87-93ef-883bac1f82f6",
|
||||
"resource_type": "VDU2.yaml",
|
||||
"links": [
|
||||
{
|
||||
"href": _href,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": []
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:02Z",
|
||||
"resource_name": "internalVL2",
|
||||
"physical_resource_id": "res_id_internalVL2",
|
||||
"resource_type": "OS::Neutron::Net",
|
||||
"links": [
|
||||
{
|
||||
"href": _href,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU1-0",
|
||||
"internalVL2_subnet",
|
||||
"VDU2-0",
|
||||
"VDU1-1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:02Z",
|
||||
"resource_name": "nfvi_node_affinity",
|
||||
"physical_resource_id": "a91fc295-72fd-456e-a607-67bbfceabece",
|
||||
"resource_type": "OS::Nova::ServerGroup",
|
||||
"links": [
|
||||
{
|
||||
"href": _href,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU2-0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:17Z",
|
||||
"resource_name": "VDU1",
|
||||
"physical_resource_id": "res_id_VDU1_0",
|
||||
"resource_type": "OS::Nova::Server",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU1_0_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [],
|
||||
"parent_resource": "VDU1-0"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:17Z",
|
||||
"resource_name": "VDU1_CP3",
|
||||
"physical_resource_id": "res_id_VDU1_CP3_0",
|
||||
"resource_type": "OS::Neutron::Port",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU1_0_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU1"
|
||||
],
|
||||
"parent_resource": "VDU1-0"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:18Z",
|
||||
"resource_name": "VDU1_CP1",
|
||||
"physical_resource_id": "res_id_VDU1_CP1_0",
|
||||
"resource_type": "OS::Neutron::Port",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU1_0_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU1"
|
||||
],
|
||||
"parent_resource": "VDU1-0"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:18Z",
|
||||
"resource_name": "VDU1_CP2",
|
||||
"physical_resource_id": "res_id_VDU1_CP2_0",
|
||||
"resource_type": "OS::Neutron::Port",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU1_0_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU1"
|
||||
],
|
||||
"parent_resource": "VDU1-0"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:18Z",
|
||||
"resource_name": "VDU1",
|
||||
"physical_resource_id": "res_id_VDU1_1",
|
||||
"resource_type": "OS::Nova::Server",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU1_1_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [],
|
||||
"parent_resource": "VDU1-1"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:18Z",
|
||||
"resource_name": "VDU1_CP3",
|
||||
"physical_resource_id": "res_id_VDU1_CP3_1",
|
||||
"resource_type": "OS::Neutron::Port",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU1_1_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU1"
|
||||
],
|
||||
"parent_resource": "VDU1-1"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:19Z",
|
||||
"resource_name": "VDU1_CP1",
|
||||
"physical_resource_id": "res_id_VDU1_CP1_1",
|
||||
"resource_type": "OS::Neutron::Port",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU1_1_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU1"
|
||||
],
|
||||
"parent_resource": "VDU1-1"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:20Z",
|
||||
"resource_name": "VDU1_CP2",
|
||||
"physical_resource_id": "res_id_VDU1_CP2_1",
|
||||
"resource_type": "OS::Neutron::Port",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU1_1_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU1"
|
||||
],
|
||||
"parent_resource": "VDU1-1"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:17Z",
|
||||
"resource_name": "VDU2",
|
||||
"physical_resource_id": "res_id_VDU2_0",
|
||||
"resource_type": "OS::Nova::Server",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU2_0_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [],
|
||||
"parent_resource": "VDU2-0"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:18Z",
|
||||
"resource_name": "VDU2_CP3",
|
||||
"physical_resource_id": "res_id_VDU2_CP3_0",
|
||||
"resource_type": "OS::Neutron::Port",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU2_0_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU2"
|
||||
],
|
||||
"parent_resource": "VDU2-0"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:18Z",
|
||||
"resource_name": "VDU2-VirtualStorage",
|
||||
"physical_resource_id": "res_id_VDU2-VirtualStorage_0",
|
||||
"resource_type": "OS::Cinder::Volume",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU2_0_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU2"
|
||||
],
|
||||
"parent_resource": "VDU2-0"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:18Z",
|
||||
"resource_name": "multi",
|
||||
"physical_resource_id": "3374895e-2f83-4061-bad7-1085215efa68",
|
||||
"resource_type": "OS::Cinder::VolumeType",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU2_0_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU2-VirtualStorage"
|
||||
],
|
||||
"parent_resource": "VDU2-0"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:19Z",
|
||||
"resource_name": "VDU2_CP2",
|
||||
"physical_resource_id": "res_id_VDU2_CP2_0",
|
||||
"resource_type": "OS::Neutron::Port",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU2_0_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU2"
|
||||
],
|
||||
"parent_resource": "VDU2-0"
|
||||
},
|
||||
{
|
||||
"creation_time": "2022-11-24T23:31:20Z",
|
||||
"resource_name": "VDU2_CP1",
|
||||
"physical_resource_id": "res_id_VDU2_CP1_0",
|
||||
"resource_type": "OS::Neutron::Port",
|
||||
"links": [
|
||||
{
|
||||
"href": _href_VDU2_0_S,
|
||||
"rel": "stack"
|
||||
}
|
||||
],
|
||||
"required_by": [
|
||||
"VDU2"
|
||||
],
|
||||
"parent_resource": "VDU2-0"
|
||||
}
|
||||
]
|
||||
|
||||
# heat get_parameters example
|
||||
_nfv_dict = {
|
||||
"VDU": {
|
||||
@ -860,6 +1198,21 @@ _heat_get_parameters_example = {
|
||||
'nfv': json.dumps(_nfv_dict)
|
||||
}
|
||||
|
||||
# heat get_parameters example for test of StandardUserData
|
||||
_nfv_dict_S = {
|
||||
"VDU": {
|
||||
"VDU1-0": {"vcImageId": "image-VDU1", "computeFlavourId": "m1.tiny",
|
||||
"locationConstraints": "zone1"},
|
||||
"VDU1-1": {"vcImageId": "image-VDU1", "computeFlavourId": "m1.tiny",
|
||||
"locationConstraints": "zone1"},
|
||||
"VDU2-0": {"computeFlavourId": "m1.small"},
|
||||
"VDU2-VirtualStorage-0": {"vcImageId": "image-VDU2"}
|
||||
}
|
||||
}
|
||||
_heat_get_parameters_example_S = {
|
||||
'nfv': json.dumps(_nfv_dict_S)
|
||||
}
|
||||
|
||||
# heat get_template example
|
||||
_heat_get_template_example = {
|
||||
"resources": {
|
||||
@ -2266,6 +2619,382 @@ _expected_inst_info_change_ext_conn = {
|
||||
}
|
||||
}
|
||||
|
||||
# expected results for test of StandardUserData
|
||||
_expected_inst_info_S = {
|
||||
"flavourId": "simple",
|
||||
"vnfState": "STARTED",
|
||||
"extCpInfo": [
|
||||
{
|
||||
"id": "cp-res_id_VDU1_CP1_0",
|
||||
"cpdId": "VDU1_CP1",
|
||||
"cpConfigId": "VDU1_CP1_1",
|
||||
"cpProtocolInfo": [
|
||||
{
|
||||
"layerProtocol": "IP_OVER_ETHERNET",
|
||||
"ipOverEthernet": {
|
||||
"ipAddresses": [
|
||||
{
|
||||
"type": "IPV4",
|
||||
"isDynamic": True
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"extLinkPortId": "res_id_VDU1_CP1_0",
|
||||
"associatedVnfcCpId": "VDU1_CP1-res_id_VDU1_0"
|
||||
},
|
||||
{
|
||||
"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_VDU2_CP1_0",
|
||||
"cpdId": "VDU2_CP1",
|
||||
"cpConfigId": "VDU2_CP1_1",
|
||||
"cpProtocolInfo": [
|
||||
{
|
||||
"layerProtocol": "IP_OVER_ETHERNET",
|
||||
"ipOverEthernet": {
|
||||
"ipAddresses": [
|
||||
{
|
||||
"type": "IPV4",
|
||||
"isDynamic": True,
|
||||
"subnetId": "res_id_subnet"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"extLinkPortId": "res_id_VDU2_CP1_0",
|
||||
"associatedVnfcCpId": "VDU2_CP1-res_id_VDU2_0"
|
||||
}
|
||||
],
|
||||
"extVirtualLinkInfo": [
|
||||
{
|
||||
"id": "id_ext_vl_1",
|
||||
"resourceHandle": {
|
||||
"resourceId": "res_id_ext_vl_1"
|
||||
},
|
||||
"extLinkPorts": [
|
||||
{
|
||||
"id": "res_id_VDU1_CP1_0",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU1_CP1_0",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "cp-res_id_VDU1_CP1_0"
|
||||
},
|
||||
{
|
||||
"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_VDU2_CP1_0",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU2_CP1_0",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "cp-res_id_VDU2_CP1_0"
|
||||
}
|
||||
],
|
||||
"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",
|
||||
"numDynamicAddresses": 1,
|
||||
"subnetId": "res_id_subnet"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"extManagedVirtualLinkInfo": [
|
||||
{
|
||||
"id": "id_ext_mgd_1",
|
||||
"vnfVirtualLinkDescId": "internalVL1",
|
||||
"networkResource": {
|
||||
"resourceId": "res_id_internalVL1"
|
||||
},
|
||||
"vnfLinkPorts": [
|
||||
{
|
||||
"id": "res_id_VDU1_CP2_0",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU1_CP2_0",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU1_CP2-res_id_VDU1_0",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_CP2_1",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU1_CP2_1",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU1_CP2-res_id_VDU1_1",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU2_CP2_0",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU2_CP2_0",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU2_CP2-res_id_VDU2_0",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vnfcResourceInfo": [
|
||||
{
|
||||
"id": "res_id_VDU1_1",
|
||||
"vduId": "VDU1",
|
||||
"computeResource": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU1_1",
|
||||
"vimLevelResourceType": "OS::Nova::Server"
|
||||
},
|
||||
"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",
|
||||
"vnfLinkPortId": "res_id_VDU1_CP2_1"
|
||||
},
|
||||
{
|
||||
"id": "VDU1_CP3-res_id_VDU1_1",
|
||||
"cpdId": "VDU1_CP3",
|
||||
"vnfLinkPortId": "res_id_VDU1_CP3_1"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"creation_time": "2022-11-24T23:31:18Z",
|
||||
"stack_id": _stack_id_VDU1_1_S,
|
||||
"vdu_idx": 1,
|
||||
"flavor": "m1.tiny",
|
||||
"image-VDU1-1": "image-VDU1",
|
||||
"zone": "zone1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_0",
|
||||
"vduId": "VDU1",
|
||||
"computeResource": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU1_0",
|
||||
"vimLevelResourceType": "OS::Nova::Server"
|
||||
},
|
||||
"vnfcCpInfo": [
|
||||
{
|
||||
"id": "VDU1_CP1-res_id_VDU1_0",
|
||||
"cpdId": "VDU1_CP1",
|
||||
"vnfExtCpId": "cp-res_id_VDU1_CP1_0"
|
||||
},
|
||||
{
|
||||
"id": "VDU1_CP2-res_id_VDU1_0",
|
||||
"cpdId": "VDU1_CP2",
|
||||
"vnfLinkPortId": "res_id_VDU1_CP2_0"
|
||||
},
|
||||
{
|
||||
"id": "VDU1_CP3-res_id_VDU1_0",
|
||||
"cpdId": "VDU1_CP3",
|
||||
"vnfLinkPortId": "res_id_VDU1_CP3_0"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"creation_time": "2022-11-24T23:31:17Z",
|
||||
"stack_id": _stack_id_VDU1_0_S,
|
||||
"vdu_idx": 0,
|
||||
"flavor": "m1.tiny",
|
||||
"image-VDU1-0": "image-VDU1",
|
||||
"zone": "zone1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU2_0",
|
||||
"vduId": "VDU2",
|
||||
"computeResource": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU2_0",
|
||||
"vimLevelResourceType": "OS::Nova::Server"
|
||||
},
|
||||
"storageResourceIds": [
|
||||
"res_id_VDU2-VirtualStorage_0"
|
||||
],
|
||||
"vnfcCpInfo": [
|
||||
{
|
||||
"id": "VDU2_CP1-res_id_VDU2_0",
|
||||
"cpdId": "VDU2_CP1",
|
||||
"vnfExtCpId": "cp-res_id_VDU2_CP1_0"
|
||||
},
|
||||
{
|
||||
"id": "VDU2_CP2-res_id_VDU2_0",
|
||||
"cpdId": "VDU2_CP2",
|
||||
"vnfLinkPortId": "res_id_VDU2_CP2_0"
|
||||
},
|
||||
{
|
||||
"id": "VDU2_CP3-res_id_VDU2_0",
|
||||
"cpdId": "VDU2_CP3",
|
||||
"vnfLinkPortId": "res_id_VDU2_CP3_0"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"creation_time": "2022-11-24T23:31:17Z",
|
||||
"stack_id": _stack_id_VDU2_0_S,
|
||||
"vdu_idx": 0,
|
||||
"flavor": "m1.small",
|
||||
"image-VDU2-VirtualStorage-0": "image-VDU2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"vnfVirtualLinkResourceInfo": [
|
||||
{
|
||||
"id": "res_id_internalVL2",
|
||||
"vnfVirtualLinkDescId": "internalVL2",
|
||||
"networkResource": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_internalVL2",
|
||||
"vimLevelResourceType": "OS::Neutron::Net"
|
||||
},
|
||||
"vnfLinkPorts": [
|
||||
{
|
||||
"id": "res_id_VDU1_CP3_0",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU1_CP3_0",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU1_CP3-res_id_VDU1_0",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU1_CP3_1",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU1_CP3_1",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU1_CP3-res_id_VDU1_1",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
},
|
||||
{
|
||||
"id": "res_id_VDU2_CP3_0",
|
||||
"resourceHandle": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU2_CP3_0",
|
||||
"vimLevelResourceType": "OS::Neutron::Port"
|
||||
},
|
||||
"cpInstanceId": "VDU2_CP3-res_id_VDU2_0",
|
||||
"cpInstanceType": "VNFC_CP"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"virtualStorageResourceInfo": [
|
||||
{
|
||||
"id": "res_id_VDU2-VirtualStorage_0",
|
||||
"virtualStorageDescId": "VDU2-VirtualStorage",
|
||||
"storageResource": {
|
||||
"vimConnectionId": "vim_id_1",
|
||||
"resourceId": "res_id_VDU2-VirtualStorage_0",
|
||||
"vimLevelResourceType": "OS::Cinder::Volume"
|
||||
},
|
||||
"metadata": {
|
||||
"stack_id": _stack_id_VDU2_0_S
|
||||
}
|
||||
}
|
||||
],
|
||||
"vnfcInfo": [
|
||||
{
|
||||
"id": "VDU1-res_id_VDU1_1",
|
||||
"vduId": "VDU1",
|
||||
"vnfcResourceInfoId": "res_id_VDU1_1",
|
||||
"vnfcState": "STARTED"
|
||||
},
|
||||
{
|
||||
"id": "VDU1-res_id_VDU1_0",
|
||||
"vduId": "VDU1",
|
||||
"vnfcResourceInfoId": "res_id_VDU1_0",
|
||||
"vnfcState": "STARTED"
|
||||
},
|
||||
{
|
||||
"id": "VDU2-res_id_VDU2_0",
|
||||
"vduId": "VDU2",
|
||||
"vnfcResourceInfoId": "res_id_VDU2_0",
|
||||
"vnfcState": "STARTED"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"stack_id": STACK_ID
|
||||
}
|
||||
}
|
||||
|
||||
mock_resource = {
|
||||
'resources': [{
|
||||
'updated_time': '2021-12-27T02:53:29Z',
|
||||
@ -2760,6 +3489,9 @@ class TestOpenstack(base.BaseTestCase):
|
||||
|
||||
self.vnfd_1 = vnfd_utils.Vnfd(SAMPLE_VNFD_ID)
|
||||
self.vnfd_1.init_from_csar_dir(os.path.join(sample_dir, "sample1"))
|
||||
self.vnfd_S = vnfd_utils.Vnfd(SAMPLE_VNFD_ID)
|
||||
self.vnfd_S.init_from_csar_dir(os.path.join(sample_dir,
|
||||
"standard_sample"))
|
||||
|
||||
def _check_inst_info(self, expected, result):
|
||||
# sort lists before compare with an expected result since
|
||||
@ -2921,6 +3653,36 @@ class TestOpenstack(base.BaseTestCase):
|
||||
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||
self._check_inst_info(_expected_inst_info_change_ext_conn, result)
|
||||
|
||||
def test_make_instantiated_vnf_info_standard(self):
|
||||
# test of _make_instantiated_vnf_info when StandardUserData is used.
|
||||
# NOTE: main difference between DefaultUserData is making metadata
|
||||
# of VnfcResourceInfo.
|
||||
# prepare
|
||||
req = objects.InstantiateVnfRequest.from_dict(
|
||||
_instantiate_req_example_S)
|
||||
inst = objects.VnfInstanceV2(
|
||||
id=uuidutils.generate_uuid(),
|
||||
vimConnectionInfo=req.vimConnectionInfo
|
||||
)
|
||||
grant_req = objects.GrantRequestV1(
|
||||
operation=fields.LcmOperationType.INSTANTIATE
|
||||
)
|
||||
grant = objects.GrantV1()
|
||||
|
||||
# prepare heat responses
|
||||
heat_client = mock.Mock()
|
||||
heat_client.get_resources.return_value = _heat_reses_example_S
|
||||
heat_client.get_parameters.return_value = (
|
||||
_heat_get_parameters_example_S)
|
||||
|
||||
# execute make_instantiated_vnf_info
|
||||
self.driver._make_instantiated_vnf_info(req, inst, grant_req, grant,
|
||||
self.vnfd_S, heat_client, stack_id=STACK_ID)
|
||||
|
||||
# check
|
||||
result = inst.to_dict()["instantiatedVnfInfo"]
|
||||
self._check_inst_info(_expected_inst_info_S, result)
|
||||
|
||||
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_stack_id')
|
||||
@mock.patch.object(openstack.heat_utils.HeatClient, 'get_status')
|
||||
@mock.patch.object(openstack.heat_utils.HeatClient, 'create_stack')
|
||||
|
@ -0,0 +1,52 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'VDU1 HOT for Sample VNF'
|
||||
|
||||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image-VDU1:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
net2:
|
||||
type: string
|
||||
net3:
|
||||
type: string
|
||||
zone:
|
||||
type: string
|
||||
|
||||
resources:
|
||||
VDU1:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
name: VDU1
|
||||
image: { get_param: image-VDU1 }
|
||||
networks:
|
||||
- port:
|
||||
get_resource: VDU1_CP1
|
||||
# replace the following line to Port ID when extManagedVLs' Ports are
|
||||
# specified in InstantiateVnfRequest
|
||||
- port:
|
||||
get_resource: VDU1_CP2
|
||||
- port:
|
||||
get_resource: VDU1_CP3
|
||||
availability_zone: { get_param: zone }
|
||||
|
||||
# extVL without FixedIP or with numDynamicAddresses
|
||||
VDU1_CP1:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net1 }
|
||||
|
||||
# CPs of internal VLs are deleted when extManagedVLs and port are
|
||||
# specified in InstantiateVnfRequest
|
||||
VDU1_CP2:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net2 }
|
||||
|
||||
VDU1_CP3:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net3 }
|
@ -0,0 +1,69 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'VDU2 HOT for Sample VNF'
|
||||
|
||||
parameters:
|
||||
flavor:
|
||||
type: string
|
||||
image-VDU2-VirtualStorage:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
net2:
|
||||
type: string
|
||||
net3:
|
||||
type: string
|
||||
subnet1:
|
||||
type: string
|
||||
affinity:
|
||||
type: string
|
||||
|
||||
resources:
|
||||
VDU2:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: { get_param: flavor }
|
||||
name: VDU2
|
||||
block_device_mapping_v2: [{"volume_id": { get_resource: VDU2-VirtualStorage }}]
|
||||
networks:
|
||||
- port:
|
||||
get_resource: VDU2_CP1
|
||||
# replace the following line to Port ID when extManagedVLs' Ports are
|
||||
# specified in InstantiateVnfRequest
|
||||
- port:
|
||||
get_resource: VDU2_CP2
|
||||
- port:
|
||||
get_resource: VDU2_CP3
|
||||
scheduler_hints:
|
||||
group: {get_param: affinity }
|
||||
|
||||
VDU2-VirtualStorage:
|
||||
type: OS::Cinder::Volume
|
||||
properties:
|
||||
image: { get_param: image-VDU2-VirtualStorage }
|
||||
size: 1
|
||||
volume_type: { get_resource: multi }
|
||||
multi:
|
||||
type: OS::Cinder::VolumeType
|
||||
properties:
|
||||
name: VDU2-multi
|
||||
metadata: { multiattach: "<is> True" }
|
||||
|
||||
# extVL with numDynamicAddresses and subnet
|
||||
VDU2_CP1:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net1 }
|
||||
fixed_ips:
|
||||
- subnet: { get_param: subnet1 }
|
||||
|
||||
# CPs of internal VLs are deleted when extManagedVLs and port are
|
||||
# specified in InstantiateVnfRequest
|
||||
VDU2_CP2:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net2 }
|
||||
|
||||
VDU2_CP3:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net3 }
|
@ -0,0 +1,57 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'Simple Base HOT for Sample VNF'
|
||||
|
||||
parameters:
|
||||
nfv:
|
||||
type: json
|
||||
|
||||
resources:
|
||||
VDU1:
|
||||
type: VDU1.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
|
||||
image-VDU1: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
|
||||
net1: { get_param: [ nfv, CP, VDU1_CP1, network ] }
|
||||
net2: { get_resource: internalVL1 }
|
||||
net3: { get_resource: internalVL2 }
|
||||
zone: { get_param: [ nfv, VDU, VDU1, locationConstraints ] }
|
||||
|
||||
VDU2:
|
||||
type: VDU2.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU2, computeFlavourId ] }
|
||||
image-VDU2-VirtualStorage: { get_param: [ nfv, VDU, VDU2-VirtualStorage, vcImageId ] }
|
||||
net1: { get_param: [ nfv, CP, VDU2_CP1, network ] }
|
||||
subnet1: { get_param: [nfv, CP, VDU2_CP1, fixed_ips, 0, subnet ]}
|
||||
net2: { get_resource: internalVL1 }
|
||||
net3: { get_resource: internalVL2 }
|
||||
affinity: { get_resource: nfvi_node_affinity }
|
||||
|
||||
# delete the following lines when extManagedVLs are specified in InstantiateVnfRequest
|
||||
internalVL1:
|
||||
type: OS::Neutron::Net
|
||||
internalVL2:
|
||||
type: OS::Neutron::Net
|
||||
|
||||
internalVL1_subnet:
|
||||
type: OS::Neutron::Subnet
|
||||
properties:
|
||||
ip_version: 4
|
||||
network:
|
||||
get_resource: internalVL1
|
||||
cidr: 192.168.3.0/24
|
||||
internalVL2_subnet:
|
||||
type: OS::Neutron::Subnet
|
||||
properties:
|
||||
ip_version: 4
|
||||
network:
|
||||
get_resource: internalVL2
|
||||
cidr: 192.168.4.0/24
|
||||
|
||||
nfvi_node_affinity:
|
||||
type: OS::Nova::ServerGroup
|
||||
properties:
|
||||
name: nfvi_node_affinity
|
||||
policies: [ 'affinity' ]
|
||||
|
||||
outputs: {}
|
@ -0,0 +1,357 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: Simple deployment flavour for Sample VNF
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
- v2_sample3_types.yaml
|
||||
|
||||
topology_template:
|
||||
inputs:
|
||||
descriptor_id:
|
||||
type: string
|
||||
descriptor_version:
|
||||
type: string
|
||||
provider:
|
||||
type: string
|
||||
product_name:
|
||||
type: string
|
||||
software_version:
|
||||
type: string
|
||||
vnfm_info:
|
||||
type: list
|
||||
entry_schema:
|
||||
type: string
|
||||
flavour_id:
|
||||
type: string
|
||||
flavour_description:
|
||||
type: string
|
||||
|
||||
substitution_mappings:
|
||||
node_type: company.provider.VNF
|
||||
properties:
|
||||
flavour_id: simple
|
||||
requirements:
|
||||
virtual_link_external1_1: [ VDU1_CP1, virtual_link ]
|
||||
virtual_link_external1_2: [ VDU2_CP1, virtual_link ]
|
||||
|
||||
node_templates:
|
||||
VNF:
|
||||
type: company.provider.VNF
|
||||
properties:
|
||||
flavour_description: A simple flavour
|
||||
interfaces:
|
||||
Vnflcm:
|
||||
instantiate_start:
|
||||
implementation: sample-script
|
||||
instantiate_end:
|
||||
implementation: sample-script
|
||||
terminate_start:
|
||||
implementation: sample-script
|
||||
terminate_end:
|
||||
implementation: sample-script
|
||||
scale_start:
|
||||
implementation: sample-script
|
||||
scale_end:
|
||||
implementation: sample-script
|
||||
heal_start:
|
||||
implementation: sample-script
|
||||
heal_end:
|
||||
implementation: sample-script
|
||||
change_external_connectivity_start:
|
||||
implementation: sample-script
|
||||
change_external_connectivity_end:
|
||||
implementation: sample-script
|
||||
modify_information_start:
|
||||
implementation: sample-script
|
||||
modify_information_end:
|
||||
implementation: sample-script
|
||||
artifacts:
|
||||
sample-script:
|
||||
description: Sample script
|
||||
type: tosca.artifacts.Implementation.Python
|
||||
file: ../Scripts/sample_script.py
|
||||
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.Vdu.Compute
|
||||
properties:
|
||||
name: VDU1
|
||||
description: VDU1 compute node
|
||||
vdu_profile:
|
||||
min_number_of_instances: 1
|
||||
max_number_of_instances: 3
|
||||
sw_image_data:
|
||||
name: cirros-0.5.2-x86_64-disk
|
||||
version: '0.5.2'
|
||||
checksum:
|
||||
algorithm: sha-256
|
||||
hash: 932fcae93574e242dc3d772d5235061747dfe537668443a1f0567d893614b464
|
||||
container_format: bare
|
||||
disk_format: qcow2
|
||||
min_disk: 0 GB
|
||||
min_ram: 256 MB
|
||||
size: 12 GB
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
requested_additional_capabilities:
|
||||
properties:
|
||||
requested_additional_capability_name: m1.tiny
|
||||
support_mandatory: true
|
||||
target_performance_parameters:
|
||||
entry_schema: test
|
||||
virtual_memory:
|
||||
virtual_mem_size: 512 MB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 3 GB
|
||||
|
||||
VDU2:
|
||||
type: tosca.nodes.nfv.Vdu.Compute
|
||||
properties:
|
||||
name: VDU2
|
||||
description: VDU2 compute node
|
||||
vdu_profile:
|
||||
min_number_of_instances: 1
|
||||
max_number_of_instances: 1
|
||||
capabilities:
|
||||
virtual_compute:
|
||||
properties:
|
||||
requested_additional_capabilities:
|
||||
properties:
|
||||
requested_additional_capability_name: m1.tiny
|
||||
support_mandatory: true
|
||||
target_performance_parameters:
|
||||
entry_schema: test
|
||||
virtual_memory:
|
||||
virtual_mem_size: 512 MB
|
||||
virtual_cpu:
|
||||
num_virtual_cpu: 1
|
||||
virtual_local_storage:
|
||||
- size_of_storage: 3 GB
|
||||
requirements:
|
||||
- virtual_storage: VDU2-VirtualStorage
|
||||
|
||||
VDU2-VirtualStorage:
|
||||
type: tosca.nodes.nfv.Vdu.VirtualBlockStorage
|
||||
properties:
|
||||
virtual_block_storage_data:
|
||||
size_of_storage: 1 GB
|
||||
rdma_enabled: true
|
||||
sw_image_data:
|
||||
name: VDU2-VirtualStorage-image
|
||||
version: '0.5.2'
|
||||
checksum:
|
||||
algorithm: sha-256
|
||||
hash: 932fcae93574e242dc3d772d5235061747dfe537668443a1f0567d893614b464
|
||||
container_format: bare
|
||||
disk_format: qcow2
|
||||
min_disk: 0 GB
|
||||
min_ram: 256 MB
|
||||
size: 12 GB
|
||||
artifacts:
|
||||
sw_image:
|
||||
type: tosca.artifacts.nfv.SwImage
|
||||
file: ../Files/images/cirros-0.5.2-x86_64-disk.img
|
||||
|
||||
VDU1_CP1:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 0
|
||||
requirements:
|
||||
- virtual_binding: VDU1
|
||||
|
||||
VDU1_CP2:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 1
|
||||
requirements:
|
||||
- virtual_binding: VDU1
|
||||
- virtual_link: internalVL1
|
||||
|
||||
VDU1_CP3:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 2
|
||||
requirements:
|
||||
- virtual_binding: VDU1
|
||||
- virtual_link: internalVL2
|
||||
|
||||
VDU2_CP1:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 0
|
||||
requirements:
|
||||
- virtual_binding: VDU2
|
||||
|
||||
VDU2_CP2:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 1
|
||||
requirements:
|
||||
- virtual_binding: VDU2
|
||||
- virtual_link: internalVL1
|
||||
|
||||
VDU2_CP3:
|
||||
type: tosca.nodes.nfv.VduCp
|
||||
properties:
|
||||
layer_protocols: [ ipv4 ]
|
||||
order: 2
|
||||
requirements:
|
||||
- virtual_binding: VDU2
|
||||
- virtual_link: internalVL2
|
||||
|
||||
internalVL1:
|
||||
type: tosca.nodes.nfv.VnfVirtualLink
|
||||
properties:
|
||||
connectivity_type:
|
||||
layer_protocols: [ ipv4 ]
|
||||
description: External Managed Virtual link in the VNF
|
||||
vl_profile:
|
||||
max_bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
min_bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
virtual_link_protocol_data:
|
||||
- associated_layer_protocol: ipv4
|
||||
l3_protocol_data:
|
||||
ip_version: ipv4
|
||||
cidr: 192.168.3.0/24
|
||||
|
||||
internalVL2:
|
||||
type: tosca.nodes.nfv.VnfVirtualLink
|
||||
properties:
|
||||
connectivity_type:
|
||||
layer_protocols: [ ipv4 ]
|
||||
description: External Managed Virtual link in the VNF
|
||||
vl_profile:
|
||||
max_bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
min_bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
virtual_link_protocol_data:
|
||||
- associated_layer_protocol: ipv4
|
||||
l3_protocol_data:
|
||||
ip_version: ipv4
|
||||
cidr: 192.168.4.0/24
|
||||
|
||||
groups:
|
||||
affinityOrAntiAffinityGroup1:
|
||||
type: tosca.groups.nfv.PlacementGroup
|
||||
members: [ VDU1, VDU2 ]
|
||||
|
||||
policies:
|
||||
- scaling_aspects:
|
||||
type: tosca.policies.nfv.ScalingAspects
|
||||
properties:
|
||||
aspects:
|
||||
VDU1_scale:
|
||||
name: VDU1_scale
|
||||
description: VDU1 scaling aspect
|
||||
max_scale_level: 2
|
||||
step_deltas:
|
||||
- delta_1
|
||||
|
||||
- VDU1_initial_delta:
|
||||
type: tosca.policies.nfv.VduInitialDelta
|
||||
properties:
|
||||
initial_delta:
|
||||
number_of_instances: 1
|
||||
targets: [ VDU1 ]
|
||||
|
||||
- VDU2_initial_delta:
|
||||
type: tosca.policies.nfv.VduInitialDelta
|
||||
properties:
|
||||
initial_delta:
|
||||
number_of_instances: 1
|
||||
targets: [ VDU2 ]
|
||||
|
||||
- VDU1_scaling_aspect_deltas:
|
||||
type: tosca.policies.nfv.VduScalingAspectDeltas
|
||||
properties:
|
||||
aspect: VDU1_scale
|
||||
deltas:
|
||||
delta_1:
|
||||
number_of_instances: 1
|
||||
targets: [ VDU1 ]
|
||||
|
||||
- instantiation_levels:
|
||||
type: tosca.policies.nfv.InstantiationLevels
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
description: Smallest size
|
||||
scale_info:
|
||||
VDU1_scale:
|
||||
scale_level: 0
|
||||
instantiation_level_2:
|
||||
description: Largest size
|
||||
scale_info:
|
||||
VDU1_scale:
|
||||
scale_level: 1
|
||||
default_level: instantiation_level_1
|
||||
|
||||
- VDU1_instantiation_levels:
|
||||
type: tosca.policies.nfv.VduInstantiationLevels
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
number_of_instances: 1
|
||||
instantiation_level_2:
|
||||
number_of_instances: 2
|
||||
targets: [ VDU1 ]
|
||||
|
||||
- VDU2_instantiation_levels:
|
||||
type: tosca.policies.nfv.VduInstantiationLevels
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
number_of_instances: 1
|
||||
instantiation_level_2:
|
||||
number_of_instances: 1
|
||||
targets: [ VDU2 ]
|
||||
|
||||
- internalVL1_instantiation_levels:
|
||||
type: tosca.policies.nfv.VirtualLinkInstantiationLevels
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
instantiation_level_2:
|
||||
bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
targets: [ internalVL1 ]
|
||||
|
||||
- internalVL2_instantiation_levels:
|
||||
type: tosca.policies.nfv.VirtualLinkInstantiationLevels
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
instantiation_level_2:
|
||||
bitrate_requirements:
|
||||
root: 1048576
|
||||
leaf: 1048576
|
||||
targets: [ internalVL2 ]
|
||||
|
||||
- policy_antiaffinity_group:
|
||||
type: tosca.policies.nfv.AntiAffinityRule
|
||||
targets: [ affinityOrAntiAffinityGroup1 ]
|
||||
properties:
|
||||
scope: nfvi_node
|
@ -0,0 +1,31 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: Sample VNF
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
- v2_sample3_types.yaml
|
||||
- v2_sample3_df_simple.yaml
|
||||
|
||||
topology_template:
|
||||
inputs:
|
||||
selected_flavour:
|
||||
type: string
|
||||
description: VNF deployment flavour selected by the consumer. It is provided in the API
|
||||
|
||||
node_templates:
|
||||
VNF:
|
||||
type: company.provider.VNF
|
||||
properties:
|
||||
flavour_id: { get_input: selected_flavour }
|
||||
descriptor_id: b1bb0ce7-ebca-4fa7-95ed-4840d7000000
|
||||
provider: Company
|
||||
product_name: Sample VNF
|
||||
software_version: '1.0'
|
||||
descriptor_version: '1.0'
|
||||
vnfm_info:
|
||||
- Tacker
|
||||
requirements:
|
||||
#- virtual_link_external # mapped in lower-level templates
|
||||
#- virtual_link_internal # mapped in lower-level templates
|
@ -0,0 +1,55 @@
|
||||
tosca_definitions_version: tosca_simple_yaml_1_2
|
||||
|
||||
description: VNF type definition
|
||||
|
||||
imports:
|
||||
- etsi_nfv_sol001_common_types.yaml
|
||||
- etsi_nfv_sol001_vnfd_types.yaml
|
||||
|
||||
node_types:
|
||||
company.provider.VNF:
|
||||
derived_from: tosca.nodes.nfv.VNF
|
||||
properties:
|
||||
descriptor_id:
|
||||
type: string
|
||||
constraints: [ valid_values: [ b1bb0ce7-ebca-4fa7-95ed-4840d7000000 ] ]
|
||||
default: b1bb0ce7-ebca-4fa7-95ed-4840d7000000
|
||||
descriptor_version:
|
||||
type: string
|
||||
constraints: [ valid_values: [ '1.0' ] ]
|
||||
default: '1.0'
|
||||
provider:
|
||||
type: string
|
||||
constraints: [ valid_values: [ 'Company' ] ]
|
||||
default: 'Company'
|
||||
product_name:
|
||||
type: string
|
||||
constraints: [ valid_values: [ 'Sample VNF' ] ]
|
||||
default: 'Sample VNF'
|
||||
software_version:
|
||||
type: string
|
||||
constraints: [ valid_values: [ '1.0' ] ]
|
||||
default: '1.0'
|
||||
vnfm_info:
|
||||
type: list
|
||||
entry_schema:
|
||||
type: string
|
||||
constraints: [ valid_values: [ Tacker ] ]
|
||||
default: [ Tacker ]
|
||||
flavour_id:
|
||||
type: string
|
||||
constraints: [ valid_values: [ simple ] ]
|
||||
default: simple
|
||||
flavour_description:
|
||||
type: string
|
||||
default: "flavour"
|
||||
requirements:
|
||||
- virtual_link_external1:
|
||||
capability: tosca.capabilities.nfv.VirtualLinkable
|
||||
- virtual_link_external2:
|
||||
capability: tosca.capabilities.nfv.VirtualLinkable
|
||||
- virtual_link_internal:
|
||||
capability: tosca.capabilities.nfv.VirtualLinkable
|
||||
interfaces:
|
||||
Vnflcm:
|
||||
type: tosca.interfaces.nfv.Vnflcm
|
@ -0,0 +1,46 @@
|
||||
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
import pickle
|
||||
import sys
|
||||
|
||||
|
||||
class FailScript(object):
|
||||
def __init__(self, vnfc_param):
|
||||
self.vnfc_param = vnfc_param
|
||||
|
||||
def run(self):
|
||||
operation = 'change_vnfpkg'
|
||||
if self.vnfc_param['is_rollback']:
|
||||
operation += '_rollback'
|
||||
if os.path.exists(f'/tmp/{operation}'):
|
||||
raise Exception(f'test {operation} error')
|
||||
|
||||
|
||||
def main():
|
||||
vnfc_param = pickle.load(sys.stdin.buffer)
|
||||
script = FailScript(vnfc_param)
|
||||
script.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
os._exit(0)
|
||||
except Exception as ex:
|
||||
sys.stderr.write(str(ex))
|
||||
sys.stderr.flush()
|
||||
os._exit(1)
|
@ -0,0 +1,68 @@
|
||||
# Copyright (C) 2022 Nippon Telegraph and Telephone Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import functools
|
||||
import os
|
||||
import pickle
|
||||
import sys
|
||||
|
||||
|
||||
class FailScript(object):
|
||||
"""Define error method for each operation
|
||||
|
||||
For example:
|
||||
|
||||
def instantiate_start(self):
|
||||
if os.path.exists('/tmp/instantiate_start')
|
||||
raise Exception('test instantiate_start error')
|
||||
"""
|
||||
|
||||
def __init__(self, req, inst, grant_req, grant, csar_dir):
|
||||
self.req = req
|
||||
self.inst = inst
|
||||
self.grant_req = grant_req
|
||||
self.grant = grant
|
||||
self.csar_dir = csar_dir
|
||||
|
||||
def _fail(self, method):
|
||||
if os.path.exists(f'/tmp/{method}'):
|
||||
raise Exception(f'test {method} error')
|
||||
|
||||
def __getattr__(self, name):
|
||||
return functools.partial(self._fail, name)
|
||||
|
||||
|
||||
def main():
|
||||
script_dict = pickle.load(sys.stdin.buffer)
|
||||
|
||||
operation = script_dict['operation']
|
||||
req = script_dict['request']
|
||||
inst = script_dict['vnf_instance']
|
||||
grant_req = script_dict['grant_request']
|
||||
grant = script_dict['grant_response']
|
||||
csar_dir = script_dict['tmp_csar_dir']
|
||||
|
||||
script = FailScript(req, inst, grant_req, grant, csar_dir)
|
||||
getattr(script, operation)()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
os._exit(0)
|
||||
except Exception as ex:
|
||||
sys.stderr.write(str(ex))
|
||||
sys.stderr.flush()
|
||||
os._exit(1)
|
@ -0,0 +1,4 @@
|
||||
TOSCA-Meta-File-Version: 1.0
|
||||
CSAR-Version: 1.1
|
||||
Created-by: Onboarding portal
|
||||
Entry-Definitions: Definitions/v2_sample3_top.vnfd.yaml
|
Loading…
x
Reference in New Issue
Block a user