Add a VNF package sample for practical use cases

Added a sample VNF package for practical use cases.

In this sample, the use cases listed below is supported.
  - using multiple deployment flavours
  - deploying VNF connected to an external network
  - deploying VNF as HA cluster
  - deploying scalable VNF

Implements: blueprint add-vnf-package-sample-for-practical-use-cases
Spec: https://review.opendev.org/c/openstack/tacker-specs/+/814511
Change-Id: I1c55e028b96ba3c1ad26270d359e0b1165670078
This commit is contained in:
Masaki Oyama 2022-03-07 13:25:38 +00:00
parent 61cb57a8b9
commit 2ee465438c
16 changed files with 4514 additions and 0 deletions

View File

@ -106,3 +106,14 @@ Kubernetes Cluster VNF
mgmt_driver_deploy_k8s_cir_usage_guide
mgmt_driver_deploy_k8s_pv_usage_guide
mgmt_driver_deploy_k8s_kubespary_usage_guide
Sample Usage
^^^^^^^^^^^^
VM
~~
.. toctree::
:maxdepth: 1
practical_sample_package_usage_guide

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,139 @@
heat_template_version: newton
description: "Sample VNF HOT"
parameters:
nfv:
type: json
security_group:
type: string
resources:
int_net:
type: OS::Neutron::Net
properties:
name: vdu_int_net
admin_state_up: true
value_specs:
mtu: 1450
int_subnet:
type: OS::Neutron::Subnet
depends_on: [ int_net ]
properties:
name: vdu_int_subnet
network: { get_resource: int_net }
cidr: 192.168.0.0/24
enable_dhcp: true
gateway_ip: 192.168.0.254
router:
type: OS::Neutron::Router
properties:
name: vdu_router
admin_state_up: true
external_gateway_info:
network: { get_param: [ nfv, CP, VDU0_extCP0, network_id ] }
external_fixed_ips:
- ip_address:
get_param:
[ nfv, CP, RT_extCP, subnets, 0, fixed_ip_addresses, 0 ]
router_interface:
type: OS::Neutron::RouterInterface
depends_on:
- router
- int_subnet
properties:
router: { get_resource: router }
subnet: { get_resource: int_subnet }
VDU_vCP:
type: OS::Neutron::Port
depends_on:
- int_subnet
properties:
network: { get_resource: int_net }
fixed_ips:
- ip_address: 192.168.0.10
security_groups: [ { get_param: security_group } ]
VDU_extvCP:
type: OS::Neutron::FloatingIP
depends_on:
- VDU_vCP
- router_interface
properties:
fixed_ip_address: 192.168.0.10
floating_ip_address:
get_param: [ nfv, CP, VDU_extvCP, subnets, 0, fixed_ip_addresses, 0 ]
floating_network:
get_param: [ nfv, CP, VDU_extvCP, network_id ]
port_id: { get_resource: VDU_vCP }
VDU_0:
type: OS::Nova::Server
depends_on: [ VDU0_CP0 ]
properties:
name: VDU_0
flavor: { get_param: [ nfv, VDU, VDU_0, flavor ] }
image: { get_param: [ nfv, VDU, VDU_0, image ] }
networks:
- port: { get_resource: VDU0_CP0 }
VDU0_CP0:
type: OS::Neutron::Port
depends_on: [ router_interface ]
properties:
network: { get_resource: int_net }
fixed_ips: [ { ip_address: 192.168.0.11 } ]
allowed_address_pairs: [ { ip_address: 192.168.0.10 } ]
security_groups: [ { get_param: security_group } ]
VDU0_floating_ip:
type: OS::Neutron::FloatingIP
depends_on: [ VDU0_CP0 ]
properties:
fixed_ip_address: 192.168.0.11
floating_ip_address:
get_param: [ nfv, CP, VDU0_extCP0, subnets, 0, fixed_ip_addresses, 0 ]
floating_network: { get_param: [ nfv, CP, VDU0_extCP0, network_id ] }
port_id: { get_resource: VDU0_CP0 }
VDU_1:
type: OS::Nova::Server
depends_on: [ VDU1_CP0 ]
properties:
name: VDU_1
flavor: { get_param: [ nfv, VDU, VDU_1, flavor ] }
image: { get_param: [ nfv, VDU, VDU_1, image ] }
networks:
- port: { get_resource: VDU1_CP0 }
VDU1_CP0:
type: OS::Neutron::Port
depends_on: [ router_interface ]
properties:
network: { get_resource: int_net }
fixed_ips: [ { ip_address: 192.168.0.12 } ]
allowed_address_pairs: [ { ip_address: 192.168.0.10 } ]
security_groups: [ { get_param: security_group } ]
VDU1_floating_ip:
type: OS::Neutron::FloatingIP
depends_on: [ VDU1_CP0 ]
properties:
fixed_ip_address: 192.168.0.12
floating_ip_address:
get_param: [nfv, CP, VDU1_extCP0, subnets, 0, fixed_ip_addresses, 0 ]
floating_network: { get_param: [ nfv, CP, VDU1_extCP0, network_id ] }
port_id: { get_resource: VDU1_CP0 }
outputs:
int_net_id:
value: { get_resource: int_net }
mgmt_ip-VDU_0:
value: { get_attr: [ VDU0_floating_ip, floating_ip_address ] }
mgmt_ip-VDU_1:
value: { get_attr: [ VDU1_floating_ip, floating_ip_address ] }

View File

@ -0,0 +1,77 @@
heat_template_version: rocky
description: 'Sample VDU_0 HOT'
parameters:
Image:
type: string
constraints:
- custom_constraint: 'glance.image'
Flavor:
type: string
default: "m1.tiny"
ExtNetwork:
type: string
constraints:
- custom_constraint: 'neutron.network'
IntNetwork:
type: string
constraints:
- custom_constraint: 'neutron.network'
ExtFixedIP:
type: string
IntFixedIP:
type: string
AvailabilityZone:
type: string
default: "nova"
Server_Group:
type: string
resources:
VDU_0:
type: OS::Nova::Server
depends_on: [ VDU0_CP0, VDU0_CP1 ]
properties:
name: VDU_000
flavor: { get_param: Flavor }
image: { get_param: Image }
networks:
- port:
get_resource: VDU0_CP0
- port:
get_resource: VDU0_CP1
availability_zone: { get_param: AvailabilityZone }
scheduler_hints:
group:
get_param: Server_Group
VDU0_CP0:
type: OS::Neutron::Port
properties:
network:
get_param: IntNetwork
fixed_ips:
- ip_address: { get_param: IntFixedIP }
VDU0_CP1:
type: OS::Neutron::Port
properties:
network:
get_param: ExtNetwork
fixed_ips:
- ip_address: { get_param: ExtFixedIP }
outputs:
mgmt_ip-VDU_0:
value:
get_attr: [ VDU0_CP0, fixed_ips, 0, ip_address ]

View File

@ -0,0 +1,77 @@
heat_template_version: rocky
description: 'Sample VDU_1 HOT'
parameters:
Image:
type: string
constraints:
- custom_constraint: 'glance.image'
Flavor:
type: string
default: "m1.tiny"
ExtNetwork:
type: string
constraints:
- custom_constraint: 'neutron.network'
IntNetwork:
type: string
constraints:
- custom_constraint: 'neutron.network'
ExtFixedIP:
type: string
IntFixedIP:
type: string
AvailabilityZone:
type: string
default: "nova"
Server_Group:
type: string
resources:
VDU_1:
type: OS::Nova::Server
depends_on: [ VDU1_CP0, VDU1_CP1 ]
properties:
name: VDU_100
flavor: { get_param: Flavor }
image: { get_param: Image }
networks:
- port:
get_resource: VDU1_CP0
- port:
get_resource: VDU1_CP1
availability_zone: { get_param: AvailabilityZone }
scheduler_hints:
group:
get_param: Server_Group
VDU1_CP0:
type: OS::Neutron::Port
properties:
network:
get_param: IntNetwork
fixed_ips:
- ip_address: { get_param: IntFixedIP }
VDU1_CP1:
type: OS::Neutron::Port
properties:
network:
get_param: ExtNetwork
fixed_ips:
- ip_address: { get_param: ExtFixedIP }
outputs:
mgmt_ip-VDU_1:
value:
get_attr: [ VDU1_CP0, fixed_ips, 0, ip_address ]

View File

@ -0,0 +1,77 @@
heat_template_version: rocky
description: 'Sample VDU_2 HOT'
parameters:
Image:
type: string
constraints:
- custom_constraint: 'glance.image'
Flavor:
type: string
default: "m1.tiny"
ExtNetwork:
type: string
constraints:
- custom_constraint: 'neutron.network'
IntNetwork:
type: string
constraints:
- custom_constraint: 'neutron.network'
ExtFixedIP:
type: string
IntFixedIP:
type: string
AvailabilityZone:
type: string
default: "nova"
Server_Group:
type: string
resources:
VDU_2:
type: OS::Nova::Server
depends_on: [ VDU2_CP0, VDU2_CP1 ]
properties:
name: VDU_200
flavor: { get_param: Flavor }
image: { get_param: Image }
networks:
- port:
get_resource: VDU2_CP0
- port:
get_resource: VDU2_CP1
availability_zone: { get_param: AvailabilityZone }
scheduler_hints:
group:
get_param: Server_Group
VDU2_CP0:
type: OS::Neutron::Port
properties:
network:
get_param: IntNetwork
fixed_ips:
- ip_address: { get_param: IntFixedIP }
VDU2_CP1:
type: OS::Neutron::Port
properties:
network:
get_param: ExtNetwork
fixed_ips:
- ip_address: { get_param: ExtFixedIP }
outputs:
mgmt_ip-VDU_2:
value:
get_attr: [ VDU2_CP0, fixed_ips, 0, ip_address ]

View File

@ -0,0 +1,129 @@
heat_template_version: newton
description: "Sample VNF HOT"
parameters:
nfv:
type: json
security_group:
type: string
vdu0_availabilityzone:
type: string
default: "nova"
vdu1_availabilityzone:
type: string
default: "nova"
vdu2_availabilityzone:
type: string
default: "nova"
resources:
int_net:
type: OS::Neutron::Net
properties:
name: int_net
admin_state_up: true
value_specs:
mtu: 1450
int_subnet:
type: OS::Neutron::Subnet
depends_on: [ int_net ]
properties:
name: int_subnet
network: { get_resource: int_net }
cidr: 192.168.1.0/24
enable_dhcp: true
gateway_ip: 192.168.1.254
VDU_0:
type: OS::Heat::AutoScalingGroup
properties:
cooldown: 120
desired_capacity: 1
max_size: 1
min_size: 1
resource:
type: VDU_0.yaml
properties:
Image: { get_param: [ nfv, VDU, VDU_0, image ] }
Flavor: { get_param: [ nfv, VDU, VDU_0, flavor ] }
IntNetwork: { get_resource: int_net }
IntFixedIP: 192.168.1.10
ExtNetwork: { get_param: [ nfv, CP, VDU0_CP1, network_id ] }
ExtFixedIP:
get_param: [ nfv, CP, VDU0_CP1, subnets, 0, fixed_ip_addresses, 0 ]
AvailabilityZone: { get_param: vdu0_availabilityzone }
Server_Group: { get_resource: vdu_placement_policy }
VDU_1:
type: OS::Heat::AutoScalingGroup
properties:
cooldown: 120
desired_capacity: 1
max_size: 1
min_size: 1
resource:
type: VDU_1.yaml
properties:
Image: { get_param: [ nfv, VDU, VDU_1, image ] }
Flavor: { get_param: [ nfv, VDU, VDU_1, flavor ] }
IntNetwork: { get_resource: int_net }
IntFixedIP: 192.168.1.11
ExtNetwork: { get_param: [ nfv, CP, VDU1_CP1, network_id ] }
ExtFixedIP:
get_param: [ nfv, CP, VDU1_CP1, subnets, 0, fixed_ip_addresses, 0 ]
AvailabilityZone: { get_param: vdu1_availabilityzone }
Server_Group: { get_resource: vdu_placement_policy }
VDU_2:
type: OS::Heat::AutoScalingGroup
properties:
cooldown: 120
desired_capacity: { get_param: [nfv, VDU, VDU_2, number_of_instance ] }
max_size: 1
min_size: 0
resource:
type: VDU_2.yaml
properties:
Image: { get_param: [ nfv, VDU, VDU_2, image ] }
Flavor: { get_param: [ nfv, VDU, VDU_2, flavor ] }
IntNetwork: { get_resource: int_net }
IntFixedIP: 192.168.1.13
ExtNetwork: { get_param: [ nfv, CP, VDU2_CP1, network_id ] }
ExtFixedIP:
get_param: [ nfv, CP, VDU2_CP1, subnets, 0, fixed_ip_addresses, 0 ]
AvailabilityZone: { get_param: vdu2_availabilityzone }
Server_Group: { get_resource: vdu_placement_policy }
VDU_2_scale_in:
type: OS::Heat::ScalingPolicy
properties:
adjustment_type: change_in_capacity
auto_scaling_group_id:
get_resource: VDU_2
cooldown: 120
scaling_adjustment: -1
VDU_2_scale_out:
type: OS::Heat::ScalingPolicy
properties:
adjustment_type: change_in_capacity
auto_scaling_group_id:
get_resource: VDU_2
cooldown: 120
scaling_adjustment: 1
vdu_placement_policy:
type: OS::Nova::ServerGroup
properties:
name: vdu_placement_policy
policies:
- soft-anti-affinity
outputs:

View File

@ -0,0 +1,72 @@
tosca_definitions_version: tosca_simple_yaml_1_2
description: VNF template definition
imports:
- etsi_nfv_sol001_common_types.yaml
- etsi_nfv_sol001_vnfd_types.yaml
node_types:
Sample.VNF.Node:
derived_from: tosca.nodes.nfv.VNF
properties:
descriptor_id:
type: string
default: '3b3c61e4-26b6-4686-80fc-e9ff83010c08'
descriptor_version:
type: string
constraints: [ valid_values: [ '1.0' ] ]
default: '1.0'
provider:
type: string
constraints: [ valid_values: [ Sample ] ]
default: Sample
product_name:
type: string
constraints: [ valid_values: [ Node ] ]
default: Node
software_version:
type: string
constraints: [ valid_values: [ '10.1' ] ]
default: '10.1'
vnfm_info:
type: list
entry_schema:
type: string
constraints: [ valid_values: [ Tacker ] ]
default: [ Tacker ]
flavour_id:
type: string
constraints: [ valid_values: [ ha, scalable ] ]
default: ha
flavour_description:
type: string
default: 'vnf'
requirements:
- VNF0_extnet0:
capability: tosca.capabilities.nfv.VirtualLinkable
relationship: tosca.relationships.nfv.VirtualLinksTo
occurrences: [ 0, 1 ]
- VNF1_extnet0:
capability: tosca.capabilities.nfv.VirtualLinkable
relationship: tosca.relationships.nfv.VirtualLinksTo
occurrences: [ 0, 1 ]
interfaces:
Vnflcm:
type: tosca.interfaces.nfv.Vnflcm
instantiate: []
instantiate_start: []
instantiate_end: []
scale: []
scale_start: []
scale_end: []
heal: []
heal_start: []
heal_end: []
terminate: []
terminate_start: []
terminate_end: []
modify_information: []
modify_information_start: []
modify_information_end: []

View File

@ -0,0 +1,31 @@
tosca_definitions_version: tosca_simple_yaml_1_2
description: VNF definitions
imports:
- etsi_nfv_sol001_common_types.yaml
- etsi_nfv_sol001_vnfd_types.yaml
- Common.yaml
- df_ha.yaml
- df_scalable.yaml
topology_template:
inputs:
selected_flavour:
type: string
description: VNF deployment flavour selected by the consumer. Itis provided in the API.
node_templates:
VNF:
type: Sample.VNF.Node
properties:
flavour_id: { get_input: selected_flavour }
flavour_description: 'vnf'
descriptor_id: 75aaa9fa-9c79-dcf5-bda2-5b98a08c9f54
provider: Sample
product_name: Node
software_version: '10.1'
descriptor_version: '1.0'
vnfm_info:
- Tacker
requirements:

View File

@ -0,0 +1,232 @@
tosca_definitions_version: tosca_simple_yaml_1_2
description: Sample VNF ha DF
imports:
- etsi_nfv_sol001_common_types.yaml
- etsi_nfv_sol001_vnfd_types.yaml
- Common.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
configurable_properties:
type: map
substitution_mappings:
node_type: Sample.VNF.Node
properties:
flavour_id: ha
requirements:
VDU0_extnet: [ VDU0_extCP0, external_virtual_link ]
VDU1_extnet: [ VDU1_extCP0, external_virtual_link ]
VDU_extnet: [ VDU_extvCP, external_virtual_link ]
RT_extnet: [ RT_extCP, external_virtual_link ]
node_templates:
VNF:
type: Sample.VNF.Node
properties:
flavour_description: 'ha'
configurable_properties:
is_autoscale_enabled: false
is_autoheal_enabled: false
vnfm_info:
- Tacker
interfaces:
Vnflcm:
instantiate: []
instantiate_start: []
instantiate_end: []
scale: []
scale_start: []
scale_end: []
heal: []
heal_start: []
heal_end: []
terminate: []
terminate_start: []
terminate_end: []
modify_information: []
modify_information_start: []
modify_information_end: []
VDU_0:
type: tosca.nodes.nfv.Vdu.Compute
properties:
name: VDU_0
description: VDU_0
vdu_profile:
min_number_of_instances: 1
max_number_of_instances: 1
sw_image_data:
name: sample_image
version: '1.0'
checksum:
algorithm: sha-512
hash: 6513f21e44aa3da349f248188a44bc304a3653a04122d8fb4535423c8e1d14cd6a153f735bb0982e2161b5b5186106570c17a9e58b64dd39390617cd5a350f78
container_format: bare
disk_format: qcow2
min_disk: 0 GB
size: 1869 MB
capabilities:
virtual_compute:
properties:
requested_additional_capabilities:
properties:
requested_additional_capability_name: sample_flavor
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: 1 GB
VDU_1:
type: tosca.nodes.nfv.Vdu.Compute
properties:
name: VDU_1
description: VDU_1
vdu_profile:
min_number_of_instances: 1
max_number_of_instances: 1
sw_image_data:
name: sample_image
version: '1.0'
checksum:
algorithm: sha-512
hash: 6513f21e44aa3da349f248188a44bc304a3653a04122d8fb4535423c8e1d14cd6a153f735bb0982e2161b5b5186106570c17a9e58b64dd39390617cd5a350f78
container_format: bare
disk_format: qcow2
min_disk: 0 GB
size: 1869 MB
capabilities:
virtual_compute:
properties:
requested_additional_capabilities:
properties:
requested_additional_capability_name: sample_flavor
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: 1 GB
VDU0_CP0:
type: tosca.nodes.nfv.VduCp
properties:
order: 0
bitrate_requirement: 1
vnic_type: normal
layer_protocols: [ ipv4 ]
protocol:
- associated_layer_protocol: ipv4
address_data:
- address_type: ip_address
l3_address_data:
ip_address_assignment: true
floating_ip_activated: false
requirements:
- virtual_binding: VDU_0
- virtual_link: VDU_intnet0
VDU1_CP0:
type: tosca.nodes.nfv.VduCp
properties:
order: 0
bitrate_requirement: 1
vnic_type: normal
layer_protocols: [ ipv4 ]
protocol:
- associated_layer_protocol: ipv4
address_data:
- address_type: ip_address
l3_address_data:
ip_address_assignment: true
floating_ip_activated: false
requirements:
- virtual_binding: VDU_1
- virtual_link: VDU_intnet0
VDU0_extCP0:
type: tosca.nodes.nfv.VnfExtCp
properties:
layer_protocols: [ ipv4 ]
requirements:
- internal_virtual_link: VDU_intnet0
VDU1_extCP0:
type: tosca.nodes.nfv.VnfExtCp
properties:
layer_protocols: [ ipv4 ]
requirements:
- internal_virtual_link: VDU_intnet0
VDU_intnet0:
type: tosca.nodes.nfv.VnfVirtualLink
properties:
connectivity_type:
layer_protocols: [ ipv4 ]
vl_profile:
max_bitrate_requirements:
root: 1000000
min_bitrate_requirements:
root: 100000
virtual_link_protocol_data:
- associated_layer_protocol: ipv4
l2_protocol_data:
network_type: vxlan
l3_protocol_data:
ip_version: ipv4
cidr: '192.168.0.0/24'
dhcp_enabled: true
RT_extCP:
type: tosca.nodes.nfv.VnfExtCp
properties:
layer_protocols: [ ipv4 ]
requirements:
- internal_virtual_link: VDU_intnet0
VDU_extvCP:
type: tosca.nodes.nfv.VnfExtCp
properties:
layer_protocols: [ ipv4 ]
requirements:
- internal_virtual_link: VDU_intnet0
groups:
VDU_AntiAffinityGroup:
type: tosca.groups.nfv.PlacementGroup
members: [ VDU_0, VDU_1 ]
policies:
- VDU_placement_policy:
type: tosca.policies.nfv.AntiAffinityRule
targets: [ VDU_AntiAffinityGroup ]
properties:
scope: nfvi_node

View File

@ -0,0 +1,391 @@
tosca_definitions_version: tosca_simple_yaml_1_2
description: Sample VNF default DF
imports:
- etsi_nfv_sol001_common_types.yaml
- etsi_nfv_sol001_vnfd_types.yaml
- Common.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
configurable_properties:
type: map
substitution_mappings:
node_type: Sample.VNF.Node
properties:
flavour_id: scalable
requirements:
VDU0_extnet: [ VDU0_CP1, external_virtual_link ]
VDU1_extnet: [ VDU1_CP1, external_virtual_link ]
VDU2_extnet: [ VDU2_CP1, external_virtual_link ]
node_templates:
VNF:
type: Sample.VNF.Node
properties:
flavour_description: 'scalable'
configurable_properties:
is_autoscale_enabled: false
is_autoheal_enabled: false
vnfm_info:
- Tacker
interfaces:
Vnflcm:
instantiate: []
instantiate_start: []
instantiate_end: []
scale: []
scale_start: []
scale_end: []
heal: []
heal_start: []
heal_end: []
terminate: []
terminate_start: []
terminate_end: []
modify_information: []
modify_information_start: []
modify_information_end: []
VDU_0:
type: tosca.nodes.nfv.Vdu.Compute
properties:
name: VDU_0
description: VDU_0
vdu_profile:
min_number_of_instances: 1
max_number_of_instances: 1
sw_image_data:
name: sample_image
version: '1.0'
checksum:
algorithm: sha-512
hash: 6513f21e44aa3da349f248188a44bc304a3653a04122d8fb4535423c8e1d14cd6a153f735bb0982e2161b5b5186106570c17a9e58b64dd39390617cd5a350f78
container_format: bare
disk_format: qcow2
min_disk: 0 GB
size: 1869 MB
capabilities:
virtual_compute:
properties:
requested_additional_capabilities:
properties:
requested_additional_capability_name: sample_flavor
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: 1 GB
VDU_1:
type: tosca.nodes.nfv.Vdu.Compute
properties:
name: VDU_1
description: VDU_1
vdu_profile:
min_number_of_instances: 1
max_number_of_instances: 1
sw_image_data:
name: sample_image
version: '1.0'
checksum:
algorithm: sha-512
hash: 6513f21e44aa3da349f248188a44bc304a3653a04122d8fb4535423c8e1d14cd6a153f735bb0982e2161b5b5186106570c17a9e58b64dd39390617cd5a350f78
container_format: bare
disk_format: qcow2
min_disk: 0 GB
size: 1869 MB
capabilities:
virtual_compute:
properties:
requested_additional_capabilities:
properties:
requested_additional_capability_name: sample_flavor
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: 1 GB
VDU_2:
type: tosca.nodes.nfv.Vdu.Compute
properties:
name: VDU_2
description: VDU_2
vdu_profile:
min_number_of_instances: 0
max_number_of_instances: 1
sw_image_data:
name: sample_image
version: '1.0'
checksum:
algorithm: sha-512
hash: 6513f21e44aa3da349f248188a44bc304a3653a04122d8fb4535423c8e1d14cd6a153f735bb0982e2161b5b5186106570c17a9e58b64dd39390617cd5a350f78
container_format: bare
disk_format: qcow2
min_disk: 0 GB
size: 1869 MB
capabilities:
virtual_compute:
properties:
requested_additional_capabilities:
properties:
requested_additional_capability_name: sample_flavor
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: 1 GB
VDU0_CP0:
type: tosca.nodes.nfv.VduCp
properties:
order: 0
bitrate_requirement: 1
vnic_type: normal
layer_protocols: [ ipv4 ]
protocol:
- associated_layer_protocol: ipv4
address_data:
- address_type: ip_address
l3_address_data:
ip_address_assignment: true
floating_ip_activated: false
requirements:
- virtual_binding: VDU_0
- virtual_link: int_net
VDU0_CP1:
type: tosca.nodes.nfv.VduCp
properties:
order: 0
bitrate_requirement: 1
vnic_type: normal
layer_protocols: [ ipv4 ]
protocol:
- associated_layer_protocol: ipv4
address_data:
- address_type: ip_address
l3_address_data:
ip_address_assignment: true
floating_ip_activated: false
requirements:
- virtual_binding: VDU_0
VDU1_CP0:
type: tosca.nodes.nfv.VduCp
properties:
order: 0
bitrate_requirement: 1
vnic_type: normal
layer_protocols: [ ipv4 ]
protocol:
- associated_layer_protocol: ipv4
address_data:
- address_type: ip_address
l3_address_data:
ip_address_assignment: true
floating_ip_activated: false
requirements:
- virtual_binding: VDU_1
- virtual_link: int_net
VDU1_CP1:
type: tosca.nodes.nfv.VduCp
properties:
order: 0
bitrate_requirement: 1
vnic_type: normal
layer_protocols: [ ipv4 ]
protocol:
- associated_layer_protocol: ipv4
address_data:
- address_type: ip_address
l3_address_data:
ip_address_assignment: true
floating_ip_activated: false
requirements:
- virtual_binding: VDU_1
VDU2_CP0:
type: tosca.nodes.nfv.VduCp
properties:
order: 0
bitrate_requirement: 1
vnic_type: normal
layer_protocols: [ ipv4 ]
protocol:
- associated_layer_protocol: ipv4
address_data:
- address_type: ip_address
l3_address_data:
ip_address_assignment: true
floating_ip_activated: false
requirements:
- virtual_binding: VDU_2
- virtual_link: int_net
VDU2_CP1:
type: tosca.nodes.nfv.VduCp
properties:
order: 0
bitrate_requirement: 1
vnic_type: normal
layer_protocols: [ ipv4 ]
protocol:
- associated_layer_protocol: ipv4
address_data:
- address_type: ip_address
l3_address_data:
ip_address_assignment: true
floating_ip_activated: false
requirements:
- virtual_binding: VDU_2
int_net:
type: tosca.nodes.nfv.VnfVirtualLink
properties:
connectivity_type:
layer_protocols: [ ipv4 ]
vl_profile:
max_bitrate_requirements:
root: 1000000
min_bitrate_requirements:
root: 100000
virtual_link_protocol_data:
- associated_layer_protocol: ipv4
l2_protocol_data:
network_type: vxlan
l3_protocol_data:
ip_version: ipv4
cidr: '192.168.1.0/24'
groups:
VDU_AntiAffinityGroup:
type: tosca.groups.nfv.PlacementGroup
members: [ VDU_0, VDU_1, VDU_2 ]
policies:
- VDU_placement_policy:
type: tosca.policies.nfv.AntiAffinityRule
targets: [ VDU_AntiAffinityGroup ]
properties:
scope: nfvi_node
- vdu_scale:
type: tosca.policies.nfv.ScalingAspects
properties:
aspects:
VDU_2:
name: VDU_2
description: VDU_2
max_scale_level: 1
step_deltas:
- delta_1
- vdu_0_initial_delta:
type: tosca.policies.nfv.VduInitialDelta
properties:
initial_delta:
number_of_instances: 1
targets: [ VDU_0 ]
- vdu_1_initial_delta:
type: tosca.policies.nfv.VduInitialDelta
properties:
initial_delta:
number_of_instances: 1
targets: [ VDU_1 ]
- vdu_2_initial_delta:
type: tosca.policies.nfv.VduInitialDelta
properties:
initial_delta:
number_of_instances: 0
targets: [ VDU_2 ]
- vdu_2_scaling_aspect_deltas:
type: tosca.policies.nfv.VduScalingAspectDeltas
properties:
aspect: VDU_2
deltas:
delta_1:
number_of_instances: 1
targets: [ VDU_2 ]
- instantiation_levels:
type: tosca.policies.nfv.InstantiationLevels
properties:
levels:
r-node-min:
description: vdu-min structure
scale_info:
VDU_2:
scale_level: 0
r-node-max:
description: vdu-max structure
scale_info:
VDU_2:
scale_level: 1
- vdu_0_instantiation_levels:
type: tosca.policies.nfv.VduInstantiationLevels
properties:
levels:
r-node-min:
number_of_instances: 1
r-node-max:
number_of_instances: 1
targets: [ VDU_0 ]
- vdu_1_instantiation_levels:
type: tosca.policies.nfv.VduInstantiationLevels
properties:
levels:
r-node-min:
number_of_instances: 1
r-node-max:
number_of_instances: 1
targets: [ VDU_1 ]
- vdu_2_instantiation_levels:
type: tosca.policies.nfv.VduInstantiationLevels
properties:
levels:
r-node-min:
number_of_instances: 0
r-node-max:
number_of_instances: 1
targets: [ VDU_2 ]

View File

@ -0,0 +1,203 @@
tosca_definitions_version: tosca_simple_yaml_1_2
description: ETSI NFV SOL 001 common types definitions version 2.6.1
metadata:
template_name: etsi_nfv_sol001_common_types
template_author: ETSI_NFV
template_version: 2.6.1
data_types:
tosca.datatypes.nfv.L2AddressData:
derived_from: tosca.datatypes.Root
description: Describes the information on the MAC addresses to be assigned to a connection point.
properties:
mac_address_assignment:
type: boolean
description: Specifies if the address assignment is the responsibility of management and orchestration function or not. If it is set to True, it is the management and orchestration function responsibility
required: true
tosca.datatypes.nfv.L3AddressData:
derived_from: tosca.datatypes.Root
description: Provides information about Layer 3 level addressing scheme and parameters applicable to a CP
properties:
ip_address_assignment:
type: boolean
description: Specifies if the address assignment is the responsibility of management and orchestration function or not. If it is set to True, it is the management and orchestration function responsibility
required: true
floating_ip_activated:
type: boolean
description: Specifies if the floating IP scheme is activated on the Connection Point or not
required: true
ip_address_type:
type: string
description: Defines address type. The address type should be aligned with the address type supported by the layer_protocols properties of the parent VnfExtCp
required: false
constraints:
- valid_values: [ ipv4, ipv6 ]
number_of_ip_address:
type: integer
description: Minimum number of IP addresses to be assigned
required: false
constraints:
- greater_than: 0
tosca.datatypes.nfv.AddressData:
derived_from: tosca.datatypes.Root
description: Describes information about the addressing scheme and parameters applicable to a CP
properties:
address_type:
type: string
description: Describes the type of the address to be assigned to a connection point. The content type shall be aligned with the address type supported by the layerProtocol property of the connection point
required: true
constraints:
- valid_values: [ mac_address, ip_address ]
l2_address_data:
type: tosca.datatypes.nfv.L2AddressData
description: Provides the information on the MAC addresses to be assigned to a connection point.
required: false
l3_address_data:
type: tosca.datatypes.nfv.L3AddressData
description: Provides the information on the IP addresses to be assigned to a connection point
required: false
tosca.datatypes.nfv.ConnectivityType:
derived_from: tosca.datatypes.Root
description: describes additional connectivity information of a virtualLink
properties:
layer_protocols:
type: list
description: Identifies the protocol a virtualLink gives access to (ethernet, mpls, odu2, ipv4, ipv6, pseudo-wire).The top layer protocol of the virtualLink protocol stack shall always be provided. The lower layer protocols may be included when there are specific requirements on these layers.
required: true
entry_schema:
type: string
constraints:
- valid_values: [ ethernet, mpls, odu2, ipv4, ipv6, pseudo-wire ]
flow_pattern:
type: string
description: Identifies the flow pattern of the connectivity
required: false
constraints:
- valid_values: [ line, tree, mesh ]
tosca.datatypes.nfv.LinkBitrateRequirements:
derived_from: tosca.datatypes.Root
description: describes the requirements in terms of bitrate for a virtual link
properties:
root:
type: integer # in bits per second
description: Specifies the throughput requirement in bits per second of the link (e.g. bitrate of E-Line, root bitrate of E-Tree, aggregate capacity of E-LAN).
required: true
constraints:
- greater_or_equal: 0
leaf:
type: integer # in bits per second
description: Specifies the throughput requirement in bits per second of leaf connections to the link when applicable to the connectivity type (e.g. for E-Tree and E LAN branches).
required: false
constraints:
- greater_or_equal: 0
tosca.datatypes.nfv.CpProtocolData:
derived_from: tosca.datatypes.Root
description: Describes and associates the protocol layer that a CP uses together with other protocol and connection point information
properties:
associated_layer_protocol:
type: string
required: true
description: One of the values of the property layer_protocols of the CP
constraints:
- valid_values: [ ethernet, mpls, odu2, ipv4, ipv6, pseudo-wire ]
address_data:
type: list
description: Provides information on the addresses to be assigned to the CP
entry_schema:
type: tosca.datatypes.nfv.AddressData
required: false
tosca.datatypes.nfv.VnfProfile:
derived_from: tosca.datatypes.Root
description: describes a profile for instantiating VNFs of a particular NS DF according to a specific VNFD and VNF DF.
properties:
instantiation_level:
type: string
description: Identifier of the instantiation level of the VNF DF to be used for instantiation. If not present, the default instantiation level as declared in the VNFD shall be used.
required: false
min_number_of_instances:
type: integer
description: Minimum number of instances of the VNF based on this VNFD that is permitted to exist for this VnfProfile.
required: true
constraints:
- greater_or_equal: 0
max_number_of_instances:
type: integer
description: Maximum number of instances of the VNF based on this VNFD that is permitted to exist for this VnfProfile.
required: true
constraints:
- greater_or_equal: 0
tosca.datatypes.nfv.Qos:
derived_from: tosca.datatypes.Root
description: describes QoS data for a given VL used in a VNF deployment flavour
properties:
latency:
type: scalar-unit.time #Number
description: Specifies the maximum latency
required: true
constraints:
- greater_than: 0 s
packet_delay_variation:
type: scalar-unit.time #Number
description: Specifies the maximum jitter
required: true
constraints:
- greater_or_equal: 0 s
packet_loss_ratio:
type: float
description: Specifies the maximum packet loss ratio
required: false
constraints:
- in_range: [ 0.0, 1.0 ]
capability_types:
tosca.capabilities.nfv.VirtualLinkable:
derived_from: tosca.capabilities.Node
description: A node type that includes the VirtualLinkable capability indicates that it can be pointed by tosca.relationships.nfv.VirtualLinksTo relationship type
relationship_types:
tosca.relationships.nfv.VirtualLinksTo:
derived_from: tosca.relationships.DependsOn
description: Represents an association relationship between the VduCp and VnfVirtualLink node types
valid_target_types: [ tosca.capabilities.nfv.VirtualLinkable ]
node_types:
tosca.nodes.nfv.Cp:
derived_from: tosca.nodes.Root
description: Provides information regarding the purpose of the connection point
properties:
layer_protocols:
type: list
description: Identifies which protocol the connection point uses for connectivity purposes
required: true
entry_schema:
type: string
constraints:
- valid_values: [ ethernet, mpls, odu2, ipv4, ipv6, pseudo-wire ]
role: #Name in ETSI NFV IFA011 v0.7.3: cpRole
type: string
description: Identifies the role of the port in the context of the traffic flow patterns in the VNF or parent NS
required: false
constraints:
- valid_values: [ root, leaf ]
description:
type: string
description: Provides human-readable information on the purpose of the connection point
required: false
protocol:
type: list
description: Provides information on the addresses to be assigned to the connection point(s) instantiated from this Connection Point Descriptor
required: false
entry_schema:
type: tosca.datatypes.nfv.CpProtocolData
trunk_mode:
type: boolean
description: Provides information about whether the CP instantiated from this Cp is in Trunk mode (802.1Q or other), When operating in "trunk mode", the Cp is capable of carrying traffic for several VLANs. Absence of this property implies that trunkMode is not configured for the Cp i.e. It is equivalent to boolean value "false".
required: false

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
TOSCA-Meta-File-Version: 1.0
CSAR-Version: 1.1
Created-by: Onboarding portal
Entry-Definitions: Definitions/Node.yaml

View File

@ -0,0 +1,409 @@
# 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.
from tacker.vnfm.lcm_user_data.abstract_user_data import AbstractUserData
import tacker.vnfm.lcm_user_data.utils as UserDataUtil
t_vdu = ('tosca.nodes.nfv.Vdu.Compute', )
t_blk = ('tosca.nodes.nfv.Vdu.VirtualBlockStorage', )
t_cpd = ('tosca.nodes.nfv.VduCp', 'tosca.nodes.nfv.VnfExtCp', )
t_anti_affinity = 'tosca.policies.nfv.AntiAffinityRule'
t_affinity = 'tosca.policies.nfv.AffinityRule'
t_grprule = (t_anti_affinity, t_affinity)
t_sc_aspect = ('tosca.policies.nfv.ScalingAspects')
t_vdu_sc_asp_delta = ('tosca.policies.nfv.VduScalingAspectDeltas')
t_vdu_init_delta = ('tosca.policies.nfv.VduInitialDelta')
t_inst_lv = ('tosca.policies.nfv.InstantiationLevels')
t_vdu_inst_lv = ('tosca.policies.nfv.VduInstantiationLevels')
def from_key_arrangement(value, key_arrangement):
for key in key_arrangement:
if isinstance(value, list) and key >= len(value):
return None
if isinstance(value, dict) and key not in value:
return None
value = value[key]
return value
def get_volumes(value):
bind_blk_names = dict()
for idx, el in enumerate(value.get('requirements', [])):
key = 'virtual_storage'
if key not in el:
continue
vol_name = el[key]
bind_blk_names[vol_name] = {'order': idx}
return bind_blk_names
def generate_vdu_compute_dict(val):
ret = dict()
key_arrangement = [
'capabilities',
'virtual_compute',
'properties',
'requested_additional_capabilities',
'properties',
'requested_additional_capability_name'
]
flavor_name = from_key_arrangement(val, key_arrangement)
if flavor_name is not None:
ret['flavor'] = flavor_name
key_arrangement = ['properties', 'sw_image_data', 'name']
image_name = from_key_arrangement(val, key_arrangement)
if image_name is not None:
ret['image'] = image_name
key_arrangement = ['properties', 'boot_order', 0]
boot_volume = from_key_arrangement(val, key_arrangement)
if boot_volume is not None:
ret['boot_volume'] = boot_volume
volumes = get_volumes(val)
if len(volumes) > 0:
ret['volumes'] = volumes
return ret
def generate_vdu_block_dict(val):
ret = dict()
key_arrangement = ['properties', 'sw_image_data', 'name']
image_name = from_key_arrangement(val, key_arrangement)
if image_name is not None:
ret['image'] = image_name
key = ('properties', 'virtual_block_storage_data', 'size_of_storage')
volume_size = from_key_arrangement(val, key)
if volume_size is not None:
tmp = volume_size.split(" ", 1)
front = float(tmp[0])
end = "GB"
if len(tmp) >= 2:
end = tmp[1]
if end == "PB":
front *= 1000 * 1000
elif end == "TB":
front *= 1000
elif end == "MB":
front /= 1000
elif end == "KB":
front /= 1000 * 1000
elif end == "B":
front /= 1000 * 1000 * 1000
ret['size'] = int(front)
return ret
def bind_vdu_cpd(val):
bind_vdu_name = None
for el in val.get('requirements', []):
if 'virtual_binding' not in el:
continue
bind_vdu_name = el['virtual_binding']
order = from_key_arrangement(val, ('properties', 'order'))
if order is None:
order = 0
return bind_vdu_name, order
def create_initial_param_dict(vnfd_dict):
keys = ('topology_template', 'node_templates')
node_templates = from_key_arrangement(vnfd_dict, keys)
if node_templates is None:
return dict()
vdus = dict()
blks = dict()
cps = dict()
# sequential scanning for each node templates object
for rsc_id, val in node_templates.items():
rsc_type = val.get("type", None)
# in case of vdu compute
if rsc_type in t_vdu:
vdus[rsc_id] = generate_vdu_compute_dict(val)
# in case of vdu block storage
elif rsc_type in t_blk:
blks[rsc_id] = generate_vdu_block_dict(val)
# in case of vdu cpd
elif rsc_type in t_cpd:
bind_vdu_name, order = bind_vdu_cpd(val)
if bind_vdu_name not in cps:
cps[bind_vdu_name] = dict()
cps[bind_vdu_name][rsc_id] = {"order": order}
# unknown type, ignore
# merge to single vdu info
for name, info in vdus.items():
# merge cps
info['connection_points'] = cps.get(name, {})
# merge volumes
for vol_name, vol_info in info.get('volumes', {}).items():
vol_info.update(blks.get(vol_name, {}))
# set boot image form volume
blk = info.get('boot_volume', None)
if blk is None:
continue
info['image'] = blks[blk].get('image', None)
return vdus
def get_cps_instantiate_parameters(inst_req_info):
connection_points = dict()
ext_vls = inst_req_info.ext_virtual_links
if ext_vls is None:
return {}
for ext_vl in ext_vls:
ext_cps = ext_vl.ext_cps
net_rsc_id = ext_vl.resource_id
if ext_cps is None:
continue
for ext_cp in ext_cps:
cp_dict = dict()
connection_points[ext_cp.cpd_id] = cp_dict
cp_dict['network_id'] = net_rsc_id
cp_configs = ext_cp.cp_config
if cp_configs is None:
continue
for cp_config in ext_cp.cp_config:
cp_list = list()
cp_dict['subnets'] = cp_list
cp_protos = cp_config.cp_protocol_data
if cp_protos is None:
continue
for cp_proto in cp_protos:
ipoe = cp_proto.ip_over_ethernet
if ipoe is None:
continue
addrs = ipoe.ip_addresses
if addrs is None:
continue
for addr in addrs:
port_dict = dict()
cp_list.append(port_dict)
if addr.subnet_id is not None:
port_dict['subnet_id'] = addr.subnet_id
ip_addrs = addr.fixed_addresses
if ip_addrs is not None:
port_dict['fixed_ip_addresses'] = ip_addrs
if addr.type is not None:
port_dict['ethertype'] = addr.type
return connection_points
def get_policies(vnfd_dict):
pols = dict()
policies = vnfd_dict.get('topology_template', {}).get('policies', [])
policies_dict = dict()
for policy in policies:
policies_dict.update(policy)
for policy_name, policy_value in policies_dict.items():
pol_type = policy_value.get('type', None)
if pol_type in t_grprule:
tgt_grp = from_key_arrangement(policy_value, ('targets', 0))
rule = 'anti-affinity'
if pol_type == t_affinity:
rule = 'affinity'
if 'groups' not in pols:
pols['groups'] = dict()
pols['groups'][tgt_grp] = rule
elif pol_type in t_vdu_inst_lv:
lvs = from_key_arrangement(policy_value, ('properties', 'levels'))
if 'instantiation_levels' not in pols:
pols['instantiation_levels'] = dict()
inst_lvs = pols['instantiation_levels']
tgts = policy_value.get('targets', [])
for lv_name, lv_value in lvs.items():
for tgt in tgts:
key = 'number_of_instances'
num_of_instance = lv_value.get(key, None)
if num_of_instance is None:
continue
if lv_name not in inst_lvs:
inst_lvs[lv_name] = dict()
if key not in inst_lvs[lv_name]:
inst_lvs[lv_name][key] = dict()
inst_lvs[lv_name][key][tgt] = num_of_instance
return pols
def calculate_current_vdu_size(vnfd_dict, current_aspect):
policies = vnfd_dict.get('topology_template', {}).get('policies', [])
policies_dict = dict()
for policy in policies:
policies_dict.update(policy)
aspects = {}
vdu_aspect = {}
for policy_name, policy_value in policies_dict.items():
pol_type = policy_value.get('type', None)
if pol_type in t_sc_aspect:
key = ('properties', 'aspects')
_aspects = from_key_arrangement(policy_value, key)
for aspect_id, aspect_value in _aspects.items():
max_scale_level = int(aspect_value.get('max_scale_level', 0))
step_deltas = aspect_value.get('step_deltas', [])
aspects[aspect_id] = {'max_scale_level': max_scale_level,
'step_deltas': step_deltas}
if pol_type in t_vdu_sc_asp_delta:
key = ('properties', 'aspect')
aspect_id = from_key_arrangement(policy_value, key)
key = ('properties', 'deltas')
deltas = from_key_arrangement(policy_value, key)
aspect_deltas = {}
for delta_id, value in deltas.items():
num_of_ins_delta = int(value['number_of_instances'])
if aspect_id not in aspect_deltas:
aspect_deltas[aspect_id] = {}
aspect_deltas[aspect_id][delta_id] = num_of_ins_delta
vdus = from_key_arrangement(policy_value, ('targets', ))
for vdu in vdus:
if vdu not in vdu_aspect:
vdu_aspect[vdu] = {}
vdu_aspect[vdu]['aspects'] = aspect_deltas
if pol_type in t_vdu_init_delta:
key = ('properties', 'initial_delta', 'number_of_instances')
initial_num = from_key_arrangement(policy_value, key)
key = ('properties', 'initial_delta', 'number_of_instances')
initial_num = from_key_arrangement(policy_value, key)
vdus = from_key_arrangement(policy_value, ('targets', ))
for vdu in vdus:
if vdu not in vdu_aspect:
vdu_aspect[vdu] = {}
vdu_aspect[vdu]['initial_delta'] = initial_num
output = {}
for vdu, vdu_aspect_value in vdu_aspect.items():
vdu_num = vdu_aspect_value['initial_delta']
if 'aspects' in vdu_aspect_value:
for aspect_id, aspect_value in vdu_aspect_value['aspects'].items():
current_level = current_aspect[aspect_id]
deltas = aspects[aspect_id].get('step_deltas', [])
max_scale_level = aspects[aspect_id].get('max_scale_level', 0)
for i in range(max_scale_level - len(deltas)):
deltas.append(deltas[-1])
for i in range(min(current_level, max_scale_level)):
delta_id = deltas[i]
vdu_num += aspect_value[delta_id]
output[vdu] = vdu_num
return output
class ETSICompatibleUserData(AbstractUserData):
@staticmethod
def instantiate(base_hot_dict=None, vnfd_dict=None,
inst_req_info=None, grant_info=None):
# Create initial params from vnfd
# about VDU information
vdus = create_initial_param_dict(vnfd_dict)
# Get connection points information(Like IP addr, etc.)
# from VNF Instantiat Request, ExtVirtualLink section
cps = get_cps_instantiate_parameters(inst_req_info)
# Update connection point orders in VDU if present
for vdu_name, vdu_value in vdus.items():
vdu_cps = vdu_value.get('connection_points', {})
for vdu_cp_id, vdu_cp_info in vdu_cps.items():
if vdu_cp_id not in cps:
cps[vdu_cp_id] = dict()
cps[vdu_cp_id].update(vdu_cp_info)
# Get policies information from vnfd_dict
# about instantiation levels and
# affinity or anti-affinity server group information
policies = get_policies(vnfd_dict)
# Update VDU number of instance information
# from policies to VDU
selected_instantiation_level = inst_req_info.instantiation_level_id
keys = ('instantiation_levels',
selected_instantiation_level,
'number_of_instances')
num_of_instances = from_key_arrangement(policies, keys)
if num_of_instances is not None:
for vdu_name, vdu_value in vdus.items():
num_of_instance = num_of_instances.get(vdu_name, None)
if num_of_instance is None:
continue
vdu_value.update({'number_of_instance': num_of_instance})
# Get additional params from VNF InstantiateVnfRequest
api_param = UserDataUtil.get_diff_base_hot_param_from_api(
base_hot_dict, inst_req_info)
return {"nfv": {"VDU": vdus, "CP": cps}, **api_param}
@staticmethod
def heal(base_hot_dict=None,
vnfd_dict=None,
heal_vnf_request=None,
vnf_instances=None,
inst_vnf_info=None,
param=None, vnfc_resource_info=None):
# Create initial params from vnfd
# about VDU information
vdus = create_initial_param_dict(vnfd_dict)
# in each vnfc which requested heal api,
# update vdu information from current vnfd
vnfc_resource_info_list = vnfc_resource_info
if not isinstance(vnfc_resource_info, list):
vnfc_resource_info_list = [vnfc_resource_info]
# Update VDU scale size from VNFD and current vnf scale level
current_aspect = {}
for scale_aspect in inst_vnf_info.scale_status:
aspect_id = scale_aspect.aspect_id
scale_level = scale_aspect.scale_level
current_aspect[aspect_id] = scale_level
size_of_vdus = calculate_current_vdu_size(vnfd_dict, current_aspect)
for vdu_name, num_of_instance in size_of_vdus.items():
vdus[vdu_name].update({'number_of_instance': num_of_instance})
# Replaces healing requested VDU information
for vnfc in vnfc_resource_info_list:
vdu_id = vnfc.vdu_id
param["nfv"]["VDU"][vdu_id] = vdus[vdu_id]
return param
@staticmethod
def scale(base_hot_dict=None,
vnfd_dict=None,
scale_vnf_request=None,
vnf_instances=None,
inst_vnf_info=None,
param=None, resource_number=None):
# Update VDU scale size from VNFD and current vnf scale level
current_aspect = {}
for scale_aspect in inst_vnf_info.scale_status:
aspect_id = scale_aspect.aspect_id
scale_level = scale_aspect.scale_level
current_aspect[aspect_id] = scale_level
next_aspect = current_aspect
scale_aspect = scale_vnf_request.aspect_id
scale_enum = {'SCALE_OUT': 1, 'SCALE_IN': -1}
scale_factor = scale_enum[scale_vnf_request.type]
scale_step = scale_factor * scale_vnf_request.number_of_steps
next_aspect[scale_aspect] += scale_step
size_of_vdus = calculate_current_vdu_size(vnfd_dict, current_aspect)
for vdu_name, num_of_instance in size_of_vdus.items():
param['nfv']['VDU'][vdu_name].update(
{'number_of_instance': num_of_instance})
return param