Merge "Support Placement Constraints for Grant"
This commit is contained in:
commit
6fc64560e2
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- Add placement constraints support so that the VNFM may interoperate with 3rd
|
||||
party NFVO, it enables to deploy each VM in the VNF after setting the zone
|
||||
information based on the grant response from NFVO.
|
@ -1084,12 +1084,15 @@ class Conductor(manager.Manager):
|
||||
placement_obj_list = []
|
||||
topo_temp = vnfd_dict.get('topology_template', {})
|
||||
for policy in topo_temp.get('policies', []):
|
||||
affinity_type = {
|
||||
'tosca.policies.nfv.AntiAffinityRule': 'ANTI_AFFINITY',
|
||||
'tosca.policies.nfv.AffinityRule': 'AFFINITY'}
|
||||
for policy_name, policy_dict in policy.items():
|
||||
key_type = 'tosca.policies.nfv.AntiAffinityRule'
|
||||
if policy_dict['type'] == key_type:
|
||||
if policy_dict['type'] in affinity_type.keys():
|
||||
placement_constraint = objects.PlacementConstraint()
|
||||
placement_constraint.affinity_or_anti_affinity = \
|
||||
'ANTI_AFFINITY'
|
||||
key = policy_dict['type']
|
||||
placement_constraint.affinity_or_anti_affinity = (
|
||||
affinity_type[key])
|
||||
placement_constraint.scope = 'ZONE'
|
||||
placement_constraint.resource = []
|
||||
placement_constraint.fallback_best_effort = True
|
||||
|
@ -23,6 +23,7 @@ resources:
|
||||
net3: { get_resource: extmanageNW_1 }
|
||||
net4: { get_resource: extmanageNW_2 }
|
||||
net5: { get_resource: internalNW_1 }
|
||||
subnet: { get_param: [nfv, CP, VDU1_CP2, fixed_ips, 0, subnet]}
|
||||
VDU1_scale_out:
|
||||
type: OS::Heat::ScalingPolicy
|
||||
properties:
|
||||
@ -41,20 +42,21 @@ resources:
|
||||
type: OS::Heat::AutoScalingGroup
|
||||
depends_on: VDU1
|
||||
properties:
|
||||
min_size: 2
|
||||
max_size: 2
|
||||
desired_capacity: 2
|
||||
min_size: 1
|
||||
max_size: 1
|
||||
desired_capacity: 1
|
||||
resource:
|
||||
type: VDU2.yaml
|
||||
properties:
|
||||
flavor: { get_param: [ nfv, VDU, VDU2, flavor ] }
|
||||
image: { get_param: [ nfv, VDU, VDU2, image ] }
|
||||
zone: { get_param: [ nfv, vdu, VDU2, zone ] }
|
||||
net1: { get_param: [ nfv, CP, VDU2_CP1, network ] }
|
||||
net2: { get_param: [ nfv, CP, VDU2_CP2, network ] }
|
||||
net3: { get_resource: extmanageNW_1 }
|
||||
net4: { get_resource: extmanageNW_2 }
|
||||
net5: { get_resource: internalNW_1 }
|
||||
ip1: { get_param: [nfv, CP, VDU2_CP2, fixed_ips, 0, ip_address]}
|
||||
subnet: { get_param: [nfv, CP, VDU2_CP2, fixed_ips, 0, subnet]}
|
||||
VDU2_scale_out:
|
||||
type: OS::Heat::ScalingPolicy
|
||||
properties:
|
||||
|
@ -18,6 +18,8 @@ parameters:
|
||||
type: string
|
||||
net5:
|
||||
type: string
|
||||
subnet:
|
||||
type: string
|
||||
|
||||
resources:
|
||||
VDU1:
|
||||
@ -47,6 +49,8 @@ resources:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net2 }
|
||||
fixed_ips:
|
||||
- subnet: { get_param: subnet}
|
||||
VDU1_CP3:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
|
@ -6,8 +6,6 @@ parameters:
|
||||
type: string
|
||||
image:
|
||||
type: string
|
||||
zone:
|
||||
type: string
|
||||
net1:
|
||||
type: string
|
||||
net2:
|
||||
@ -18,6 +16,10 @@ parameters:
|
||||
type: string
|
||||
net5:
|
||||
type: string
|
||||
ip1:
|
||||
type: string
|
||||
subnet:
|
||||
type: string
|
||||
|
||||
resources:
|
||||
VDU2:
|
||||
@ -37,7 +39,6 @@ resources:
|
||||
get_resource: VDU2_CP4
|
||||
- port:
|
||||
get_resource: VDU2_CP5
|
||||
availability_zone: { get_param: zone }
|
||||
|
||||
VDU2_CP1:
|
||||
type: OS::Neutron::Port
|
||||
@ -47,6 +48,9 @@ resources:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
network: { get_param: net2 }
|
||||
fixed_ips:
|
||||
- ip_address: { get_param: ip1}
|
||||
subnet: { get_param: subnet}
|
||||
VDU2_CP3:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
|
@ -96,8 +96,8 @@ topology_template:
|
||||
name: VDU2
|
||||
description: VDU2 compute node
|
||||
vdu_profile:
|
||||
min_number_of_instances: 2
|
||||
max_number_of_instances: 2
|
||||
min_number_of_instances: 1
|
||||
max_number_of_instances: 1
|
||||
sw_image_data:
|
||||
name: cirros-0.4.0-x86_64-disk
|
||||
version: '0.4.0'
|
||||
@ -291,7 +291,7 @@ topology_template:
|
||||
type: tosca.policies.nfv.VduInitialDelta
|
||||
properties:
|
||||
initial_delta:
|
||||
number_of_instances: 2
|
||||
number_of_instances: 1
|
||||
targets: [ VDU2 ]
|
||||
|
||||
- VDU1_scaling_aspect_deltas:
|
||||
@ -334,9 +334,9 @@ topology_template:
|
||||
properties:
|
||||
levels:
|
||||
instantiation_level_1:
|
||||
number_of_instances: 2
|
||||
number_of_instances: 1
|
||||
instantiation_level_2:
|
||||
number_of_instances: 2
|
||||
number_of_instances: 1
|
||||
targets: [ VDU2 ]
|
||||
|
||||
- internalVL1_instantiation_levels:
|
||||
|
@ -626,6 +626,14 @@ class BaseVnfLcmTest(base.BaseTackerTest):
|
||||
|
||||
return resource
|
||||
|
||||
def _get_heat_stack_template(self, stack_id, nested_depth=0):
|
||||
try:
|
||||
template = self.h_client.stacks.template(stack_id)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
return template
|
||||
|
||||
def _get_image_id_from_resource_attributes(self, stack_resource_details):
|
||||
if stack_resource_details is None:
|
||||
return None
|
||||
|
@ -108,8 +108,7 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
|
||||
- Delete subscription.
|
||||
- Show subscription.
|
||||
"""
|
||||
vnf_package_info = self._register_vnf_package_mock_response(
|
||||
package_dir="functional5")
|
||||
vnf_package_info = self._register_vnf_package_mock_response()
|
||||
glance_image = self._list_glance_image()[0]
|
||||
|
||||
# Create subscription and register it.
|
||||
@ -143,9 +142,10 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
|
||||
self.vim['tenant_id'], glance_image.id))
|
||||
|
||||
# Instantiate vnf instance
|
||||
request_body = fake_vnflcm.VnfInstances.make_inst_request_body(
|
||||
self.vim['tenant_id'], self.ext_networks, self.ext_mngd_networks,
|
||||
self.ext_link_ports, self.ext_subnets)
|
||||
request_body = fake_vnflcm.VnfInstances.\
|
||||
make_inst_request_body_include_num_dynamic(
|
||||
self.vim['tenant_id'], self.ext_networks,
|
||||
self.ext_mngd_networks, self.ext_link_ports, self.ext_subnets)
|
||||
resp, _ = self._instantiate_vnf_instance(vnf_instance_id, request_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
self._assert_instantiate_vnf(resp, vnf_instance_id)
|
||||
@ -284,12 +284,14 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
|
||||
self.vim['tenant_id'], glance_image.id))
|
||||
|
||||
# Instantiate vnf instance
|
||||
request_body = fake_vnflcm.VnfInstances.make_inst_request_body(
|
||||
self.vim['tenant_id'], self.ext_networks, self.ext_mngd_networks,
|
||||
self.ext_link_ports, self.ext_subnets)
|
||||
request_body = fake_vnflcm.VnfInstances.\
|
||||
make_inst_request_body_include_num_dynamic(
|
||||
self.vim['tenant_id'], self.ext_networks,
|
||||
self.ext_mngd_networks, self.ext_link_ports, self.ext_subnets)
|
||||
resp, _ = self._instantiate_vnf_instance(vnf_instance_id, request_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
self._assert_instantiate_vnf(resp, vnf_instance_id)
|
||||
self._assert_stack_template(vnf_instance_id)
|
||||
|
||||
# Show vnf instance
|
||||
resp, vnf_instance = self._show_vnf_instance(vnf_instance_id)
|
||||
@ -303,15 +305,19 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
|
||||
self.vim['tenant_id'], glance_image.id))
|
||||
|
||||
# Heal vnf (exists vnfc_instace_id)
|
||||
vnfc_instance_id_list = [
|
||||
vnfc.get('id') for vnfc in vnf_instance.get(
|
||||
'instantiatedVnfInfo', {}).get(
|
||||
'vnfcResourceInfo', [])]
|
||||
vnfc_instance_id_list = []
|
||||
|
||||
for vnfc in vnf_instance.get('instantiatedVnfInfo', {}).\
|
||||
get('vnfcResourceInfo', []):
|
||||
if vnfc.get('vduId') == 'VDU1':
|
||||
vnfc_instance_id_list.append(vnfc.get('id'))
|
||||
|
||||
request_body = fake_vnflcm.VnfInstances.make_heal_request_body(
|
||||
vnfc_instance_id_list)
|
||||
resp, _ = self._heal_vnf_instance(vnf_instance_id, request_body)
|
||||
self._wait_lcm_done('COMPLETED', vnf_instance_id=vnf_instance_id)
|
||||
self._assert_heal_vnf(resp, vnf_instance_id)
|
||||
self._assert_stack_template(vnf_instance_id)
|
||||
|
||||
# Set Fake server response for Grant-Req(Terminate)
|
||||
vnflcm_base.FAKE_SERVER_MANAGER.set_callback('POST',
|
||||
@ -522,3 +528,14 @@ class VnfLcmWithNfvoSeparator(vnflcm_base.BaseVnfLcmTest):
|
||||
ans_list.append(detail.attributes['fixed_ips'])
|
||||
|
||||
return ans_list
|
||||
|
||||
def _assert_stack_template(self, vnf_instance_id):
|
||||
stack = self._get_heat_stack(vnf_instance_id)
|
||||
resources_list\
|
||||
= self._get_heat_resource_list(stack.id, nested_depth=2)
|
||||
stack_name_wd = vnf_instance_id + "-VDU2"
|
||||
physical_resource_id = [r.physical_resource_id for r
|
||||
in resources_list if stack_name_wd in r.stack_name]
|
||||
template = self._get_heat_stack_template(physical_resource_id[0])
|
||||
template_count = str(template).count("zone")
|
||||
self.assertEqual(template_count, 3)
|
||||
|
@ -264,10 +264,18 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
vnf_resource = type('', (), {})
|
||||
vnf_resource.resource_identifier = constants.INVALID_UUID
|
||||
grant_info_test = {'vdu_name': {vnf_resource}}
|
||||
nested_hot_dict = {'parameters': {'vnf': 'test'}}
|
||||
nested_hot_dict = {
|
||||
'VDU1.yaml': {'parameters': {'vnf': 'test',
|
||||
'zone': {'type': 'string'}},
|
||||
'resources': {'VDU1': {'properties':
|
||||
{'availability_zone': {'get_param': 'zone'}}}}}}
|
||||
base_hot_dict = self._read_file()
|
||||
base_hot_dict['resources']['VDU1']['properties'].setdefault(
|
||||
'resource', {'properties': {'zone':
|
||||
{'get_param': ['nfv', 'vdu', 'VDU1', 'zone']}}})
|
||||
mock_get_base_hot_dict.return_value = \
|
||||
self._read_file(), nested_hot_dict
|
||||
vimAssets = {'compute_resource_flavours': [
|
||||
base_hot_dict, nested_hot_dict
|
||||
vim_assets = {'compute_resource_flavours': [
|
||||
{'vim_connection_id': uuidsentinel.vim_id,
|
||||
'vnfd_virtual_compute_desc_id': 'VDU1',
|
||||
'vim_flavour_id': 'm1.tiny'}],
|
||||
@ -275,27 +283,27 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
{'vim_connection_id': uuidsentinel.vim_id,
|
||||
'vnfd_software_image_id': 'VDU1',
|
||||
'vim_software_image_id': 'cirros'}]}
|
||||
resAddResource = []
|
||||
res_add_resource = []
|
||||
resource = {
|
||||
'resource_definition_id': '2c6e5cc7-240d-4458-a683-1fe648351280',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
resAddResource.append(resource)
|
||||
res_add_resource.append(resource)
|
||||
resource = {
|
||||
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa9',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
resAddResource.append(resource)
|
||||
res_add_resource.append(resource)
|
||||
resource = {
|
||||
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa0',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
resAddResource.append(resource)
|
||||
res_add_resource.append(resource)
|
||||
resource = {
|
||||
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa1',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
resAddResource.append(resource)
|
||||
res_add_resource.append(resource)
|
||||
zone = {
|
||||
'id': '5e4da3c3-4a55-412a-b624-843921f8b51d',
|
||||
'zone_id': 'nova',
|
||||
@ -313,8 +321,224 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
grant_dict['vnf_instance_id'] = uuidsentinel.vnf_instance_id
|
||||
grant_dict['vnf_lcm_op_occ_id'] = uuidsentinel.vnf_lcm_op_occ_id
|
||||
grant_dict['add_resources'] = []
|
||||
grant_dict['add_resources'].extend(resAddResource)
|
||||
grant_dict['vim_assets'] = vimAssets
|
||||
grant_dict['add_resources'].extend(res_add_resource)
|
||||
grant_dict['vim_assets'] = vim_assets
|
||||
grant_dict['zones'] = [zone]
|
||||
grant_dict['vim_connections'] = [vim_obj]
|
||||
grant_obj = objects.Grant.obj_from_primitive(
|
||||
grant_dict, context=self.context)
|
||||
vnf['grant'] = grant_obj
|
||||
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||
vnf_instance.instantiated_vnf_info.reinitialize()
|
||||
vnfc_obj = objects.VnfcResourceInfo()
|
||||
vnfc_obj.id = '2c6e5cc7-240d-4458-a683-1fe648351280'
|
||||
vnfc_obj.vdu_id = 'VDU1'
|
||||
vnfc_obj.storage_resource_ids = \
|
||||
['faf14707-da7c-4eec-be99-8099fa1e9fa0']
|
||||
compute_resource = objects.ResourceHandle(
|
||||
vim_connection_id=uuidsentinel.vim_id,
|
||||
resource_id='6e1c286d-c023-4b34-8369-831c6e84cce2')
|
||||
vnfc_obj.compute_resource = compute_resource
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info = [vnfc_obj]
|
||||
self.openstack.create(self.plugin, self.context, vnf,
|
||||
self.auth_attr, inst_req_info=inst_req_info_test,
|
||||
vnf_package_path=vnf_package_path_test,
|
||||
grant_info=grant_info_test,
|
||||
vnf_instance=vnf_instance)
|
||||
|
||||
@mock.patch('tacker.vnfm.vim_client.VimClient.get_vim')
|
||||
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
|
||||
'.OpenStack._format_base_hot')
|
||||
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||
def test_create_grant_zone_add(self, mock_OpenstackClients_heat,
|
||||
mock_get_base_hot_dict,
|
||||
mock_format_base_hot,
|
||||
mock_get_vim):
|
||||
mock_get_vim.return_value = {
|
||||
'vim_id': uuidsentinel.vnfd_id,
|
||||
'vim_type': 'test',
|
||||
'vim_auth': {'username': 'test', 'password': 'test'},
|
||||
'placement_attr': {'region': 'TestRegionOne'},
|
||||
'tenant': 'test'
|
||||
}
|
||||
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
|
||||
flavour='simple')
|
||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||
vnf_package_path_test = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__),
|
||||
"../../../../etc/samples/etsi/nfv",
|
||||
"user_data_sample_normal"))
|
||||
inst_req_info_test = type('', (), {})
|
||||
test_json = self._json_load(
|
||||
'instantiate_vnf_request_lcm_userdata.json')
|
||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||
inst_req_info_test.ext_virtual_links = None
|
||||
inst_req_info_test.flavour_id = 'simple'
|
||||
vnf_resource = type('', (), {})
|
||||
vnf_resource.resource_identifier = constants.INVALID_UUID
|
||||
grant_info_test = {'vdu_name': {vnf_resource}}
|
||||
nested_hot_dict = {
|
||||
'VDU1.yaml': {'parameters': {'vnf': 'test'},
|
||||
'resources': {'VDU1': {'properties': {}}}}}
|
||||
mock_get_base_hot_dict.return_value = \
|
||||
self._read_file(), nested_hot_dict
|
||||
vim_assets = {'compute_resource_flavours': [
|
||||
{'vim_connection_id': uuidsentinel.vim_id,
|
||||
'vnfd_virtual_compute_desc_id': 'VDU1',
|
||||
'vim_flavour_id': 'm1.tiny'}],
|
||||
'softwareImages': [
|
||||
{'vim_connection_id': uuidsentinel.vim_id,
|
||||
'vnfd_software_image_id': 'VDU1',
|
||||
'vim_software_image_id': 'cirros'}]}
|
||||
res_add_resource = []
|
||||
resource = {
|
||||
'resource_definition_id': '2c6e5cc7-240d-4458-a683-1fe648351280',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
res_add_resource.append(resource)
|
||||
resource = {
|
||||
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa9',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
res_add_resource.append(resource)
|
||||
resource = {
|
||||
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa0',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
res_add_resource.append(resource)
|
||||
resource = {
|
||||
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa1',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
res_add_resource.append(resource)
|
||||
zone = {
|
||||
'id': '5e4da3c3-4a55-412a-b624-843921f8b51d',
|
||||
'zone_id': 'nova',
|
||||
'vim_connection_id': uuidsentinel.vim_id}
|
||||
vim_obj = {'id': '0b9c66bb-9e1f-4bb2-92c3-913074e52e2b',
|
||||
'vim_id': uuidsentinel.vim_id,
|
||||
'vim_type': 'openstack',
|
||||
'access_info': {
|
||||
'password': 'test_pw',
|
||||
'username': 'test_user',
|
||||
'region': 'test_region',
|
||||
'tenant': uuidsentinel.tenant}}
|
||||
grant_dict = {}
|
||||
grant_dict['id'] = 'c213e465-8220-487e-9464-f79104e81e96'
|
||||
grant_dict['vnf_instance_id'] = uuidsentinel.vnf_instance_id
|
||||
grant_dict['vnf_lcm_op_occ_id'] = uuidsentinel.vnf_lcm_op_occ_id
|
||||
grant_dict['add_resources'] = []
|
||||
grant_dict['add_resources'].extend(res_add_resource)
|
||||
grant_dict['vim_assets'] = vim_assets
|
||||
grant_dict['zones'] = [zone]
|
||||
grant_dict['vim_connections'] = [vim_obj]
|
||||
grant_obj = objects.Grant.obj_from_primitive(
|
||||
grant_dict, context=self.context)
|
||||
vnf['grant'] = grant_obj
|
||||
vnf_instance = fd_utils.get_vnf_instance_object()
|
||||
vnf_instance.instantiated_vnf_info.reinitialize()
|
||||
vnfc_obj = objects.VnfcResourceInfo()
|
||||
vnfc_obj.id = '2c6e5cc7-240d-4458-a683-1fe648351280'
|
||||
vnfc_obj.vdu_id = 'VDU1'
|
||||
vnfc_obj.storage_resource_ids = \
|
||||
['faf14707-da7c-4eec-be99-8099fa1e9fa0']
|
||||
compute_resource = objects.ResourceHandle(
|
||||
vim_connection_id=uuidsentinel.vim_id,
|
||||
resource_id='6e1c286d-c023-4b34-8369-831c6e84cce2')
|
||||
vnfc_obj.compute_resource = compute_resource
|
||||
vnf_instance.instantiated_vnf_info.vnfc_resource_info = [vnfc_obj]
|
||||
self.openstack.create(self.plugin, self.context, vnf,
|
||||
self.auth_attr, inst_req_info=inst_req_info_test,
|
||||
vnf_package_path=vnf_package_path_test,
|
||||
grant_info=grant_info_test,
|
||||
vnf_instance=vnf_instance)
|
||||
|
||||
@mock.patch('tacker.vnfm.vim_client.VimClient.get_vim')
|
||||
@mock.patch('tacker.vnfm.infra_drivers.openstack.openstack'
|
||||
'.OpenStack._format_base_hot')
|
||||
@mock.patch('tacker.vnflcm.utils.get_base_nest_hot_dict')
|
||||
@mock.patch('tacker.common.clients.OpenstackClients')
|
||||
def test_create_grant_zone_id_none(self, mock_OpenstackClients_heat,
|
||||
mock_get_base_hot_dict,
|
||||
mock_format_base_hot,
|
||||
mock_get_vim):
|
||||
mock_get_vim.return_value = {
|
||||
'vim_id': uuidsentinel.vnfd_id,
|
||||
'vim_type': 'test',
|
||||
'vim_auth': {'username': 'test', 'password': 'test'},
|
||||
'placement_attr': {'region': 'TestRegionOne'},
|
||||
'tenant': 'test'
|
||||
}
|
||||
vnf = utils.get_dummy_vnf_etsi(instance_id=self.instance_uuid,
|
||||
flavour='simple')
|
||||
vnf['placement_attr'] = {'region_name': 'dummy_region'}
|
||||
vnf_package_path_test = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__),
|
||||
"../../../../etc/samples/etsi/nfv",
|
||||
"user_data_sample_normal"))
|
||||
inst_req_info_test = type('', (), {})
|
||||
test_json = self._json_load(
|
||||
'instantiate_vnf_request_lcm_userdata.json')
|
||||
inst_req_info_test.additional_params = test_json['additionalParams']
|
||||
inst_req_info_test.ext_virtual_links = None
|
||||
inst_req_info_test.flavour_id = 'simple'
|
||||
vnf_resource = type('', (), {})
|
||||
vnf_resource.resource_identifier = constants.INVALID_UUID
|
||||
grant_info_test = {'vdu_name': {vnf_resource}}
|
||||
nested_hot_dict = {
|
||||
'VDU1.yaml': {'parameters': {'vnf': 'test'},
|
||||
'resources': {'VDU1': {'properties': {}}}}}
|
||||
mock_get_base_hot_dict.return_value = \
|
||||
self._read_file(), nested_hot_dict
|
||||
vim_assets = {'compute_resource_flavours': [
|
||||
{'vim_connection_id': uuidsentinel.vim_id,
|
||||
'vnfd_virtual_compute_desc_id': 'VDU1',
|
||||
'vim_flavour_id': 'm1.tiny'}],
|
||||
'softwareImages': [
|
||||
{'vim_connection_id': uuidsentinel.vim_id,
|
||||
'vnfd_software_image_id': 'VDU1',
|
||||
'vim_software_image_id': 'cirros'}]}
|
||||
res_add_resource = []
|
||||
resource = {
|
||||
'resource_definition_id': '2c6e5cc7-240d-4458-a683-1fe648351280',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
res_add_resource.append(resource)
|
||||
resource = {
|
||||
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa9',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
res_add_resource.append(resource)
|
||||
resource = {
|
||||
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa0',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
res_add_resource.append(resource)
|
||||
resource = {
|
||||
'resource_definition_id': 'faf14707-da7c-4eec-be99-8099fa1e9fa1',
|
||||
'vim_connection_id': uuidsentinel.vim_id,
|
||||
'zone_id': '5e4da3c3-4a55-412a-b624-843921f8b51d'}
|
||||
res_add_resource.append(resource)
|
||||
zone = {
|
||||
'id': '5e4da3c3-4a55-412a-b624-843921f8b51d',
|
||||
'zone_id': '',
|
||||
'vim_connection_id': uuidsentinel.vim_id}
|
||||
vim_obj = {'id': '0b9c66bb-9e1f-4bb2-92c3-913074e52e2b',
|
||||
'vim_id': uuidsentinel.vim_id,
|
||||
'vim_type': 'openstack',
|
||||
'access_info': {
|
||||
'password': 'test_pw',
|
||||
'username': 'test_user',
|
||||
'region': 'test_region',
|
||||
'tenant': uuidsentinel.tenant}}
|
||||
grant_dict = {}
|
||||
grant_dict['id'] = 'c213e465-8220-487e-9464-f79104e81e96'
|
||||
grant_dict['vnf_instance_id'] = uuidsentinel.vnf_instance_id
|
||||
grant_dict['vnf_lcm_op_occ_id'] = uuidsentinel.vnf_lcm_op_occ_id
|
||||
grant_dict['add_resources'] = []
|
||||
grant_dict['add_resources'].extend(res_add_resource)
|
||||
grant_dict['vim_assets'] = vim_assets
|
||||
grant_dict['zones'] = [zone]
|
||||
grant_dict['vim_connections'] = [vim_obj]
|
||||
grant_obj = objects.Grant.obj_from_primitive(
|
||||
@ -2085,6 +2309,199 @@ class TestOpenStack(base.FixturedTestCase):
|
||||
region_name=None
|
||||
)
|
||||
|
||||
@mock.patch.object(hc.HeatClient, "update")
|
||||
def test_scale_out_initial_zone_none(self, mock_update):
|
||||
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
|
||||
aspect_id='SP1',
|
||||
number_of_steps=1)
|
||||
vnf_info = {}
|
||||
add_resources = []
|
||||
resource = objects.ResourceDefinition(
|
||||
id='2c6e5cc7-240d-4458-a683-1fe648351280',
|
||||
type='COMPUTE',
|
||||
vdu_id='VDU1',
|
||||
resource_template_id='VDU1')
|
||||
add_resources.append(resource)
|
||||
resource = objects.ResourceDefinition(
|
||||
id='faf14707-da7c-4eec-be99-8099fa1e9fa9',
|
||||
type='LINKPORT',
|
||||
vdu_id='VDU1',
|
||||
resource_template_id='PORT1')
|
||||
add_resources.append(resource)
|
||||
resource = objects.ResourceDefinition(
|
||||
id='faf14707-da7c-4eec-be99-8099fa1e9fa9',
|
||||
type='STORAGE',
|
||||
vdu_id='VDU1',
|
||||
resource_template_id='ST1')
|
||||
add_resources.append(resource)
|
||||
vnf_info['addResources'] = add_resources
|
||||
vnf_info['attributes'] = {}
|
||||
vnf_info['attributes']['scale_group'] = '{\"scaleGroupDict\": ' + \
|
||||
'{ \"SP1\": { \"vdu\": [\"VDU1\"], \"num\": ' + \
|
||||
'1, \"maxLevel\": 3, \"initialNum\": 0, ' + \
|
||||
'\"initialLevel\": 0, \"default\": 0 }}}'
|
||||
vnf_info['attributes']['heat_template'] = \
|
||||
utils.get_dummy_scale_initial_hot()
|
||||
vnf_info['attributes']['SP1_res.yaml'] = \
|
||||
utils.get_dummy_scale_nest_initial_hot()
|
||||
stack_param_dict = {}
|
||||
stack_param_dict['nfv'] = {}
|
||||
stack_param_dict['nfv']['VDU'] = {}
|
||||
stack_param_dict['nfv']['VDU']['VDU1'] = {}
|
||||
stack_param_dict['nfv']['VDU']['VDU1']['flavor'] = ''
|
||||
stack_param_dict['nfv']['VDU']['VDU1']['image'] = ''
|
||||
vnf_info['attributes'].update({'stack_param': str(stack_param_dict)})
|
||||
vnf_info['instance_id'] = uuidsentinel.stack_id
|
||||
testjson = '{"id": "c213e465-8220-487e-9464-f79104e81e96", ' + \
|
||||
'"vnf_instance_id": ' + \
|
||||
'"47101fb6-bd18-4e04-b2b5-22370a023448", ' + \
|
||||
'"vnf_lcm_op_occ_id": ' + \
|
||||
'"f26f181d-7891-4720-b022-b074ec1733ef", ' + \
|
||||
'"zones": [{' + \
|
||||
'"id": ' + \
|
||||
'"5e4da3c3-4a55-412a-b624-843921f8b51d", ' + \
|
||||
'"zone_id": ' + \
|
||||
'"nova", ' + \
|
||||
'"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187"}], ' + \
|
||||
'"add_resources": [{"resource_definition_id": ' + \
|
||||
'"2c6e5cc7-240d-4458-a683-1fe648351280", ' + \
|
||||
'"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
|
||||
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
|
||||
', {"resource_definition_id": ' + \
|
||||
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
|
||||
'"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
|
||||
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
|
||||
', {"resource_definition_id": ' + \
|
||||
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
|
||||
'"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
|
||||
'"zone_id": ' + \
|
||||
'"5e4da3c3-4a55-412a-b624-843921f8b51d"}], ' + \
|
||||
'"vim_assets": {"compute_resource_flavours": ' + \
|
||||
'[{"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
|
||||
'"vnfd_virtual_compute_desc_id": "VDU1", ' + \
|
||||
'"vim_flavour_id": "m1.tiny"}], "software_images": ' + \
|
||||
'[{"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
|
||||
'"vnfd_software_image_id": "VDU1", ' + \
|
||||
'"vim_software_image_id": "cirros"}]}}'
|
||||
res_body = jsonutils.loads(testjson)
|
||||
res_dict = cutils.convert_camelcase_to_snakecase(res_body)
|
||||
grant_obj = objects.Grant.obj_from_primitive(
|
||||
res_dict, context=context)
|
||||
vnf_info['grant'] = grant_obj
|
||||
self.openstack.scale_out_initial(context=self.context,
|
||||
plugin=self,
|
||||
auth_attr=None,
|
||||
vnf_info=vnf_info,
|
||||
scale_vnf_request=scale_vnf_request,
|
||||
region_name=None
|
||||
)
|
||||
|
||||
@mock.patch.object(hc.HeatClient, "update")
|
||||
def test_scale_out_initial_zone_id_none(self, mock_update):
|
||||
scale_vnf_request = objects.ScaleVnfRequest(type='SCALE_OUT',
|
||||
aspect_id='SP1',
|
||||
number_of_steps=1)
|
||||
vnf_info = {}
|
||||
add_resources = []
|
||||
resource = objects.ResourceDefinition(
|
||||
id='2c6e5cc7-240d-4458-a683-1fe648351280',
|
||||
type='COMPUTE',
|
||||
vdu_id='VDU1',
|
||||
resource_template_id='VDU1')
|
||||
add_resources.append(resource)
|
||||
resource = objects.ResourceDefinition(
|
||||
id='faf14707-da7c-4eec-be99-8099fa1e9fa9',
|
||||
type='LINKPORT',
|
||||
vdu_id='VDU1',
|
||||
resource_template_id='PORT1')
|
||||
add_resources.append(resource)
|
||||
resource = objects.ResourceDefinition(
|
||||
id='faf14707-da7c-4eec-be99-8099fa1e9fa9',
|
||||
type='STORAGE',
|
||||
vdu_id='VDU1',
|
||||
resource_template_id='ST1')
|
||||
add_resources.append(resource)
|
||||
vnf_info['addResources'] = add_resources
|
||||
vnf_info['attributes'] = {}
|
||||
vnf_info['attributes']['scale_group'] = '{\"scaleGroupDict\": ' + \
|
||||
'{ \"SP1\": { \"vdu\": [\"VDU1\"], \"num\": ' + \
|
||||
'1, \"maxLevel\": 3, \"initialNum\": 0, ' + \
|
||||
'\"initialLevel\": 0, \"default\": 0 }}}'
|
||||
vnf_info['attributes']['heat_template'] = \
|
||||
utils.get_dummy_scale_initial_hot()
|
||||
vnf_info['attributes']['SP1_res.yaml'] = \
|
||||
utils.get_dummy_scale_nest_initial_hot()
|
||||
stack_param_dict = {}
|
||||
stack_param_dict['nfv'] = {}
|
||||
stack_param_dict['nfv']['VDU'] = {}
|
||||
stack_param_dict['nfv']['VDU']['VDU1'] = {}
|
||||
stack_param_dict['nfv']['VDU']['VDU1']['zone'] = ''
|
||||
stack_param_dict['nfv']['VDU']['VDU1']['flavor'] = ''
|
||||
stack_param_dict['nfv']['VDU']['VDU1']['image'] = ''
|
||||
vnf_info['attributes'].update({'stack_param': str(stack_param_dict)})
|
||||
vnf_info['instance_id'] = uuidsentinel.stack_id
|
||||
testjson = '{"id": "c213e465-8220-487e-9464-f79104e81e96", ' + \
|
||||
'"vnf_instance_id": ' + \
|
||||
'"47101fb6-bd18-4e04-b2b5-22370a023448", ' + \
|
||||
'"vnf_lcm_op_occ_id": ' + \
|
||||
'"f26f181d-7891-4720-b022-b074ec1733ef", ' + \
|
||||
'"zones": [{' + \
|
||||
'"id": ' + \
|
||||
'"5e4da3c3-4a55-412a-b624-843921f8b51d", ' + \
|
||||
'"zone_id": ' + \
|
||||
'"", ' + \
|
||||
'"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187"}], ' + \
|
||||
'"add_resources": [{"resource_definition_id": ' + \
|
||||
'"2c6e5cc7-240d-4458-a683-1fe648351280", ' + \
|
||||
'"id": ' + \
|
||||
'"2c6e5cc7-240d-4458-a683-1fe648351280", ' + \
|
||||
'"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
|
||||
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
|
||||
', {"resource_definition_id": ' + \
|
||||
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
|
||||
'"id": ' + \
|
||||
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
|
||||
'"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
|
||||
'"zone_id": "5e4da3c3-4a55-412a-b624-843921f8b51d"}' + \
|
||||
', {"resource_definition_id": ' + \
|
||||
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
|
||||
'"id": ' + \
|
||||
'"faf14707-da7c-4eec-be99-8099fa1e9fa9", ' + \
|
||||
'"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
|
||||
'"zone_id": ' + \
|
||||
'"5e4da3c3-4a55-412a-b624-843921f8b51d"}], ' + \
|
||||
'"vim_assets": {"compute_resource_flavours": ' + \
|
||||
'[{"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
|
||||
'"vnfd_virtual_compute_desc_id": "VDU1", ' + \
|
||||
'"vim_flavour_id": "m1.tiny"}], "software_images": ' + \
|
||||
'[{"vim_connection_id": ' + \
|
||||
'"b6eacd1b-5a9e-41ea-a33b-9d7196cd9187", ' + \
|
||||
'"vnfd_software_image_id": "VDU1", ' + \
|
||||
'"vim_software_image_id": "cirros"}]}}'
|
||||
res_body = jsonutils.loads(testjson)
|
||||
res_dict = cutils.convert_camelcase_to_snakecase(res_body)
|
||||
grant_obj = objects.Grant.obj_from_primitive(
|
||||
res_dict, context=context)
|
||||
vnf_info['grant'] = grant_obj
|
||||
self.openstack.scale_out_initial(context=self.context,
|
||||
plugin=self,
|
||||
auth_attr=None,
|
||||
vnf_info=vnf_info,
|
||||
scale_vnf_request=scale_vnf_request,
|
||||
region_name=None
|
||||
)
|
||||
|
||||
@mock.patch.object(hc.HeatClient, "resource_get")
|
||||
@mock.patch.object(hc.HeatClient, "resource_get_list")
|
||||
def test_get_rollback_ids(self, mock_list, mock_resource):
|
||||
|
@ -264,29 +264,9 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||
scale_status_list.append(scale_status)
|
||||
vnf['scale_status'] = scale_status_list
|
||||
if vnf.get('grant'):
|
||||
grant = vnf['grant']
|
||||
ins_inf = vnf_instance.instantiated_vnf_info.vnfc_resource_info
|
||||
for addrsc in grant.add_resources:
|
||||
for zone in grant.zones:
|
||||
if zone.id == addrsc.zone_id:
|
||||
vdu_name = None
|
||||
for rsc in ins_inf:
|
||||
if addrsc.resource_definition_id == rsc.id:
|
||||
vdu_name = rsc.vdu_id
|
||||
break
|
||||
if not vdu_name:
|
||||
continue
|
||||
hot_param_dict['nfv']['VDU'][vdu_name]['zone'] = \
|
||||
zone.zone_id
|
||||
if 'vim_assets' in grant and grant.vim_assets:
|
||||
for flavour in grant.vim_assets.compute_resource_flavours:
|
||||
vdu_name = flavour.vnfd_virtual_compute_desc_id
|
||||
hot_param_dict['nfv']['VDU'][vdu_name]['flavor'] = \
|
||||
flavour.vim_flavour_id
|
||||
for image in grant.vim_assets.software_images:
|
||||
vdu_name = image.vnfd_software_image_id
|
||||
hot_param_dict['nfv']['VDU'][vdu_name]['image'] = \
|
||||
image.vim_software_image_id
|
||||
base_hot_dict, nested_hot_dict, hot_param_dict = \
|
||||
self._setup_hot_for_grant_resources(vnf, vnf_instance,
|
||||
base_hot_dict, nested_hot_dict, hot_param_dict)
|
||||
|
||||
# Add stack param to vnf_attributes
|
||||
vnf['attributes'].update({'stack_param': str(hot_param_dict)})
|
||||
@ -366,6 +346,79 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||
|
||||
return stack['stack']['id']
|
||||
|
||||
@log.log
|
||||
def _setup_hot_for_grant_resources(self, vnf, vnf_instance,
|
||||
base_hot_dict, nested_hot_dict, hot_param_dict):
|
||||
"""Setup HOT related params for grant resources
|
||||
|
||||
Update base_hot_dict, nested_hot_dict and hot_param_dict as HOT related
|
||||
params for grant resources.
|
||||
|
||||
:param vnf:
|
||||
:param vnf_instance:
|
||||
:param base_hot_dict:
|
||||
:param nested_hot_dict:
|
||||
:param hot_param_dict:
|
||||
:returns: updated base_hot_dict, nested_hot_dict and hot_param_dict
|
||||
"""
|
||||
|
||||
# Rename for readability
|
||||
grant = vnf['grant']
|
||||
bh = base_hot_dict
|
||||
nh = nested_hot_dict
|
||||
hparam = hot_param_dict
|
||||
|
||||
ins_inf = vnf_instance.instantiated_vnf_info.vnfc_resource_info
|
||||
for addrsc in grant.add_resources:
|
||||
for zone in grant.zones:
|
||||
if zone.id == addrsc.zone_id:
|
||||
vdu_name = None
|
||||
for rsc in ins_inf:
|
||||
if addrsc.resource_definition_id == rsc.id:
|
||||
vdu_name = rsc.vdu_id
|
||||
break
|
||||
if not vdu_name:
|
||||
continue
|
||||
|
||||
vdu_prop = bh['resources'][vdu_name]['properties']
|
||||
if not vdu_prop.get('resource'):
|
||||
vdu_prop['resource'] = {'properties': {}}
|
||||
|
||||
vdu_rsrc_prop = vdu_prop['resource']['properties']
|
||||
if not vdu_rsrc_prop.get('zone'):
|
||||
vdu_rsrc_prop['zone'] = {'get_param':
|
||||
['nfv', 'vdu', vdu_name, 'zone']}
|
||||
|
||||
if nh:
|
||||
for yaml_name in nh:
|
||||
if not (vdu_name in yaml_name):
|
||||
continue
|
||||
if not nh[yaml_name]['parameters'].get('zone'):
|
||||
nh[yaml_name]['parameters']['zone'] = {
|
||||
'type': 'string'}
|
||||
vdu_props = nh[yaml_name]['resources'][vdu_name][
|
||||
'properties']
|
||||
if not (vdu_props.get('availability_zone')):
|
||||
vdu_props['availability_zone'] = {
|
||||
'get_param': 'zone'}
|
||||
|
||||
h_vdu = hparam['nfv']['VDU'][vdu_name]
|
||||
if not h_vdu.get('zone') and zone.zone_id:
|
||||
hparam['nfv']['VDU'][vdu_name]['zone'] = zone.zone_id
|
||||
if h_vdu.get('zone') and not zone.zone_id:
|
||||
del hparam['nfv']['VDU'][vdu_name]['zone']
|
||||
|
||||
if 'vim_assets' in grant and grant.vim_assets:
|
||||
h_vdus = hparam['nfv']['VDU']
|
||||
for flv in grant.vim_assets.compute_resource_flavours:
|
||||
vdu_name = flv.vnfd_virtual_compute_desc_id
|
||||
h_vdus[vdu_name]['flavor'] = flv.vim_flavour_id
|
||||
for img in grant.vim_assets.software_images:
|
||||
vdu_name = img.vnfd_software_image_id
|
||||
h_vdus[vdu_name]['image'] = img.vim_software_image_id
|
||||
|
||||
return bh, nh, hparam
|
||||
|
||||
@log.log
|
||||
def _delete_user_data_module(self, user_data_module):
|
||||
# Delete module recursively.
|
||||
@ -1674,10 +1727,18 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
||||
for zone in grant.zones:
|
||||
if zone.id == addrsc.zone_id:
|
||||
for rsc in vnf_info['addResources']:
|
||||
if addrsc.id == rsc.id:
|
||||
if addrsc.resource_definition_id == rsc.id:
|
||||
vdu_name = rsc.vdu_id
|
||||
break
|
||||
stack_param['nfv']['VDU'][vdu_name]['zone'] = zone.zone_id
|
||||
if not (stack_param['nfv']['VDU']
|
||||
[vdu_name]).get('zone') and\
|
||||
zone.zone_id:
|
||||
stack_param['nfv']['VDU'][vdu_name]['zone'] = \
|
||||
zone.zone_id
|
||||
if (stack_param['nfv']['VDU']
|
||||
[vdu_name]).get('zone') and\
|
||||
not zone.zone_id:
|
||||
del stack_param['nfv']['VDU'][vdu_name]['zone']
|
||||
if 'vim_assets' in grant and grant.vim_assets:
|
||||
for flavour in grant.vim_assets.compute_resource_flavours:
|
||||
vdu_name = flavour.vnfd_virtual_compute_desc_id
|
||||
|
Loading…
Reference in New Issue
Block a user