Getting Started with v2 Tacker

Summary

This lecture enables you to:

  • create & delete a sample VNF on the OpenStack with Tacker v2 API

Following two types of VNF deployment supported by Tacker are introduced in this lecture.

“VNF Deployment with LCM Operation User Data” is optional. The part will be clarified with the notation [This is UserData specific part].

The following figure shows a sample VNF used in this lecture.

../../../_images/sample-vnf.svg

Note

VIM config, a VNF package, and instantiation parameters files used in this tutorial are placed at the repository.

Note

You can see logs of Tacker with this command:

$ sudo journalctl -u devstack@tacker.service
$ sudo journalctl -u devstack@tacker-conductor.service

Prerequisites

The following packages should be installed:

  • tacker

  • python-tackerclient

Configuration

Load credentials for client operations

Before any Tacker commands can be run, your credentials need to be sourced.

Note

See Create OpenStack client environment scripts for details. In this document, the settings are as follows:

OS_REGION_NAME=RegionOne
OS_PROJECT_DOMAIN_ID=default
OS_CACERT=
OS_AUTH_URL=http://192.168.56.10/identity
OS_TENANT_NAME=nfv
OS_USER_DOMAIN_ID=default
OS_USERNAME=nfv_user
OS_VOLUME_API_VERSION=3
OS_AUTH_TYPE=password
OS_PROJECT_NAME=nfv
OS_PASSWORD=devstack
OS_IDENTITY_API_VERSION=3

You can confirm that Tacker is available by checking this command works without error:

$ openstack vim list

Note

See Command-Line Interface Reference to find all the available commands.

Register VIM

  1. Prepare VIM configuration file:

    You can use a setup script for generating VIM configuration or edit it from scratch as described in Configuration File for Registering VIM. This script finds parameters for the configuration, such as user name or password, from your environment variables. Here is an example of generating OpenStack VIM configuration as vim_config.yaml. In this document, TACKER_ROOT is the root of tacker’s repository on your server.

    $ bash TACKER_ROOT/tools/gen_vim_config.sh -p nfv --os-user nfv_user \
      --os-disable-cert-verify
    Config for OpenStack VIM 'vim_config.yaml' generated.
    

    There are several options for configuring parameters from command line supported. Refer help with -h for details.

    Note

    See Configuration File for Registering VIM for tool details.

    You can also use a sample configuration file (vim_config.yaml) instead of using the script.

    $ cp TACKER_ROOT/doc/source/user/v2/getting_started/conf/vim_config.yaml ./
    $ vi vim_config.yaml
    
    auth_url: 'http://192.168.56.10/identity'
    username: "nfv_user"
    password: "devstack"
    project_name: "nfv"
    domain_name: "default"
    project_domain_name: "default"
    user_domain_name: "default"
    cert_verify: "False"
    
  2. Register Default VIM:

    Once you setup VIM configuration file, you register default VIM via openstack command with --is-default option.

    $ openstack vim register --config-file ./vim_config.yaml \
      --is-default --fit-width openstack-admin-vim
    +----------------+-----------------------------------------------------+
    | Field          | Value                                               |
    +----------------+-----------------------------------------------------+
    | auth_cred      | {                                                   |
    |                |     "username": "nfv_user",                         |
    |                |     "user_domain_name": "default",                  |
    |                |     "cert_verify": "False",                         |
    |                |     "project_id": null,                             |
    |                |     "project_name": "nfv",                          |
    |                |     "project_domain_name": "default",               |
    |                |     "auth_url": "http://192.168.56.10/identity/v3", |
    |                |     "key_type": "barbican_key",                     |
    |                |     "secret_uuid": "***",                           |
    |                |     "password": "***"                               |
    |                | }                                                   |
    | auth_url       | http://192.168.56.10/identity/v3                    |
    | created_at     | 2023-11-30 08:32:48.869451                          |
    | description    |                                                     |
    | extra          |                                                     |
    | id             | bff267c4-6fc9-46b5-be53-15a6a3680033                |
    | is_default     | True                                                |
    | name           | openstack-admin-vim                                 |
    | placement_attr | {                                                   |
    |                |     "regions": [                                    |
    |                |         "RegionOne"                                 |
    |                |     ]                                               |
    |                | }                                                   |
    | project_id     | ebbc6cf1a03d49918c8e408535d87268                    |
    | status         | ACTIVE                                              |
    | type           | openstack                                           |
    | updated_at     | None                                                |
    | vim_project    | {                                                   |
    |                |     "name": "nfv",                                  |
    |                |     "project_domain_name": "default"                |
    |                | }                                                   |
    +----------------+-----------------------------------------------------+
    

Create and Upload VNF Package

Prepare VNF Package

  1. Create VNF Package CSAR directories:

    $ mkdir -p ./sample_vnf_package_csar/TOSCA-Metadata \
      ./sample_vnf_package_csar/Definitions \
      ./sample_vnf_package_csar/BaseHOT/simple/nested \
      ./sample_vnf_package_csar/Files
    

    [This is UserData specific part] When using UserData, create the following directories in addition.

    $ mkdir -p ./sample_vnf_package_csar/UserData
    
  2. Create a TOSCA.meta file:

    $ vi ./sample_vnf_package_csar/TOSCA-Metadata/TOSCA.meta
    
    TOSCA-Meta-File-Version: 1.0
    Created-by: Dummy User
    CSAR-Version: 1.1
    Entry-Definitions: Definitions/sample_vnfd_top.yaml
    
  3. Download ETSI definition files:

    You should set ${TOSCA_VERSION} to one of the appropriate TOSCA service template versions (SOL001), e.g., export TOSCA_VERSION=v2.6.1.

    Important

    You should also check if the version of TOSCA service template is supported by tacker. See VNF Descriptor (VNFD) based on ETSI NFV-SOL001 for supported version.

    $ cd ./sample_vnf_package_csar/Definitions
    $ wget https://forge.etsi.org/rep/nfv/SOL001/raw/${TOSCA_VERSION}/etsi_nfv_sol001_common_types.yaml
    $ wget https://forge.etsi.org/rep/nfv/SOL001/raw/${TOSCA_VERSION}/etsi_nfv_sol001_vnfd_types.yaml
    
  4. Create VNFD files:

    • Create sample_vnfd_top.yaml

      $ vi ./sample_vnfd_top.yaml
      
      tosca_definitions_version: tosca_simple_yaml_1_2
      
      description: Sample VNF
      
      imports:
        - etsi_nfv_sol001_common_types.yaml
        - etsi_nfv_sol001_vnfd_types.yaml
        - sample_vnfd_types.yaml
        - sample_vnfd_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-4840d70a1177
              provider: Company
              product_name: Sample VNF
              software_version: '1.0'
              descriptor_version: '1.0'
              vnfm_info:
                - Tacker
      
    • Create sample_vnfd_types.yaml

      $ vi ./sample_vnfd_types.yaml
      
      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-4840d70a1177 ] ]
              default: b1bb0ce7-ebca-4fa7-95ed-4840d70a1177
            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: This is the default flavour description
          requirements:
            - virtual_link_internal:
                capability: tosca.capabilities.nfv.VirtualLinkable
          interfaces:
            Vnflcm:
              type: tosca.interfaces.nfv.Vnflcm
      

      Note

      description_id shall be globally unique, i.e., you cannot create multiple VNFDs with the same description_id.

    • Create sample_vnfd_df_simple.yaml

      $ vi ./sample_vnfd_df_simple.yaml
      
      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
        - sample_vnfd_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
      
        node_templates:
          VNF:
            type: company.provider.VNF
            properties:
              flavour_description: A simple flavour
            interfaces:
              Vnflcm:
                instantiate_start: []
                instantiate_end: []
                terminate_start: []
                terminate_end: []
                modify_information_start: []
                modify_information_end: []
                heal_start: []
                heal_end: []
                scale_start: []
                scale_end: []
      
          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: 1 GB
                size: 1 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: 1 GB
      
          CP1:
            type: tosca.nodes.nfv.VduCp
            properties:
              layer_protocols: [ ipv4 ]
              order: 4
            requirements:
              - virtual_binding: VDU1
              - virtual_link: internalVL1
      
          internalVL1:
            type: tosca.nodes.nfv.VnfVirtualLink
            properties:
              connectivity_type:
                layer_protocols: [ ipv4 ]
              description: Internal 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: 10.0.0.0/24
      
        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 ]
      
          - 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: 2
                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: 3
              targets: [ VDU1 ]
      
          - 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 ]
      

      Note

      The flavour_description should be updated by the property in “VNF” but Tacker cannot handle it. After the instantiation, the default value in sample_vnfd_types.yaml is always used.

  5. Create BaseHOT files:

    $ cd -
    $ vi ./sample_vnf_package_csar/BaseHOT/simple/sample_lcm_hot.yaml
    $ vi ./sample_vnf_package_csar/BaseHOT/simple/nested/VDU1.yaml
    
    • sample_lcm_hot.yaml

      heat_template_version: 2013-05-23
      description: 'imple Base HOT for Sample VNF'
      
      parameters:
        nfv:
          type: json
      
      resources:
        VDU1:
          type: VDU1.yaml
          properties:
            flavor: { get_param: [ nfv, VDU, VDU1, computeFlavourId ] }
            image: { get_param: [ nfv, VDU, VDU1, vcImageId ] }
            net: { get_resource: internalVL1 }
      
        internalVL1:
          type: OS::Neutron::Net
      
        internalVL1_subnet:
          type: OS::Neutron::Subnet
          properties:
            ip_version: 4
            network:
              get_resource: internalVL1
            cidr: 10.0.0.0/24
      
      outputs: {}
      
    • VDU1.yaml

      heat_template_version: 2013-05-23
      description: 'VDU1 HOT for Sample VNF'
      
      parameters:
        flavor:
          type: string
        image:
          type: string
        net:
          type: string
      
      resources:
        VDU1:
          type: OS::Nova::Server
          properties:
            flavor: { get_param: flavor }
            image: { get_param: image }
            name: VDU1
            networks:
            - port:
                get_resource: VDU1_CP1
      
        VDU1_CP1:
          type: OS::Neutron::Port
          properties:
            network: { get_param: net }
      
  6. [This is UserData specific part] Create UserData files:

    $ cd ./sample_vnf_package_csar/UserData/
    $ touch ./__init__.py
    $ vi ./lcm_user_data.py
    

    Note

    See UserData script (VNF LCM v2) for details. In this document, the following “StandardUserData” is used.

    # 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 copy
    import yaml
    
    from tacker.sol_refactored.common import common_script_utils
    from tacker.sol_refactored.common import vnf_instance_utils as inst_utils
    from tacker.sol_refactored.infra_drivers.openstack import userdata_utils
    
    
    def add_idx(name, index):
        return f'{name}-{index}'
    
    
    def rm_idx(name_idx):
        return name_idx.rpartition('-')[0]
    
    
    def add_idx_to_vdu_template(vdu_template, vdu_idx):
        """Add index to the third element of get_param
    
        ex. input VDU template:
        ---
        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 ] }
        ---
    
        output VDU template:
        ---
        VDU1:
          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 ] }
        ---
        """
        res = copy.deepcopy(vdu_template)
        for prop_value in res.get('properties', {}).values():
            get_param = prop_value.get('get_param')
            if (get_param is not None and
                    isinstance(get_param, list) and len(get_param) >= 4):
                get_param[2] = add_idx(get_param[2], vdu_idx)
        return res
    
    
    def _get_new_cps_from_req(cps, req, grant):
        # used by change_ext_conn and change_vnfpkg
        new_cps = {}
        for cp_name_idx, cp_value in cps.items():
            cp_name = rm_idx(cp_name_idx)
            if 'network' in cp_value:
                network = common_script_utils.get_param_network(
                    cp_name, grant, req)
                if network is None:
                    continue
                new_cps.setdefault(cp_name_idx, {})
                new_cps[cp_name_idx]['network'] = network
            if 'fixed_ips' in cp_value:
                ext_fixed_ips = common_script_utils.get_param_fixed_ips(
                    cp_name, grant, req)
                fixed_ips = []
                for i in range(len(ext_fixed_ips)):
                    if i not in cp_value['fixed_ips']:
                        break
                    ips_i = cp_value['fixed_ips'][i]
                    if 'subnet' in ips_i:
                        ips_i['subnet'] = ext_fixed_ips[i].get('subnet')
                    if 'ip_address' in ips_i:
                        ips_i['ip_address'] = ext_fixed_ips[i].get(
                            'ip_address')
                    fixed_ips.append(ips_i)
                new_cps.setdefault(cp_name_idx, {})
                new_cps[cp_name_idx]['fixed_ips'] = fixed_ips
    
        return new_cps
    
    
    def _merge_additional_params(nfv_dict, req, grant):
        if 'nfv' in req.get('additionalParams', {}):
            nfv_dict = inst_utils.json_merge_patch(
                nfv_dict, req['additionalParams']['nfv'])
        if 'nfv' in grant.get('additionalParams', {}):
            nfv_dict = inst_utils.json_merge_patch(
                nfv_dict, grant['additionalParams']['nfv'])
        return nfv_dict
    
    
    class StandardUserData(userdata_utils.AbstractUserData):
    
        @staticmethod
        def instantiate(req, inst, grant_req, grant, tmp_csar_dir):
            vnfd = common_script_utils.get_vnfd(inst['vnfdId'], tmp_csar_dir)
            flavour_id = req['flavourId']
    
            hot_dict = vnfd.get_base_hot(flavour_id)
            top_hot = hot_dict['template']
    
            # first modify VDU resources
            popped_vdu = {}
            vdu_idxes = {}
            for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
                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 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(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)
    
            vdus = nfv_dict.get('VDU', {})
            for vdu_name_idx, vdu_value in vdus.items():
                vdu_name = rm_idx(vdu_name_idx)
                if 'computeFlavourId' in vdu_value:
                    vdu_value['computeFlavourId'] = (
                        common_script_utils.get_param_flavor(
                            vdu_name, flavour_id, vnfd, grant))
                if 'vcImageId' in vdu_value:
                    vdu_value['vcImageId'] = common_script_utils.get_param_image(
                        vdu_name, flavour_id, vnfd, grant)
                if 'locationConstraints' in vdu_value:
                    vdu_value['locationConstraints'] = zones[vdu_name_idx]
    
            cps = nfv_dict.get('CP', {})
            for cp_name, cp_value in cps.items():
                cp_name = rm_idx(cp_name)
                if 'network' in cp_value:
                    cp_value['network'] = common_script_utils.get_param_network(
                        cp_name, grant, req)
                if 'fixed_ips' in cp_value:
                    ext_fixed_ips = common_script_utils.get_param_fixed_ips(
                        cp_name, grant, req)
                    fixed_ips = []
                    for i in range(len(ext_fixed_ips)):
                        if i not in cp_value['fixed_ips']:
                            break
                        ips_i = cp_value['fixed_ips'][i]
                        if 'subnet' in ips_i:
                            ips_i['subnet'] = ext_fixed_ips[i].get('subnet')
                        if 'ip_address' in ips_i:
                            ips_i['ip_address'] = ext_fixed_ips[i].get(
                                'ip_address')
                        fixed_ips.append(ips_i)
                    cp_value['fixed_ips'] = fixed_ips
    
            common_script_utils.apply_ext_managed_vls(top_hot, req, grant)
            nfv_dict = _merge_additional_params(nfv_dict, req, grant)
    
            fields = {
                'template': yaml.safe_dump(top_hot),
                'parameters': {'nfv': nfv_dict},
                'files': {}
            }
            for key, value in hot_dict.get('files', {}).items():
                fields['files'][key] = yaml.safe_dump(value)
    
            return fields
    
        @staticmethod
        def scale(req, inst, grant_req, grant, tmp_csar_dir):
            if req['type'] == 'SCALE_OUT':
                return StandardUserData._scale_out(req, inst, grant_req, grant,
                                                  tmp_csar_dir)
            else:
                return StandardUserData._scale_in(req, inst, grant_req, grant,
                                                 tmp_csar_dir)
    
        @staticmethod
        def _scale_out(req, inst, grant_req, grant, tmp_csar_dir):
            vnfd = common_script_utils.get_vnfd(inst['vnfdId'], tmp_csar_dir)
            flavour_id = inst['instantiatedVnfInfo']['flavourId']
    
            hot_dict = vnfd.get_base_hot(flavour_id)
            top_hot = hot_dict['template']
    
            # first modify VDU resources
            popped_vdu = {}
            vdu_idxes = {}
            for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
                popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
                vdu_idxes[vdu_name] = common_script_utils.get_current_capacity(
                    vdu_name, inst)
    
            zones = {}
            for res in grant_req['addResources']:
                if res['type'] != 'COMPUTE':
                    continue
                vdu_name = res['resourceTemplateId']
                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(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)
    
            vdus = nfv_dict.get('VDU', {})
            for vdu_name_idx, vdu_value in vdus.items():
                vdu_name = rm_idx(vdu_name_idx)
                if 'computeFlavourId' in vdu_value:
                    vdu_value['computeFlavourId'] = (
                        common_script_utils.get_param_flavor(
                            vdu_name, flavour_id, vnfd, grant))
                if 'vcImageId' in vdu_value:
                    vdu_value['vcImageId'] = common_script_utils.get_param_image(
                        vdu_name, flavour_id, vnfd, grant)
                if 'locationConstraints' in vdu_value:
                    vdu_value['locationConstraints'] = zones[vdu_name_idx]
                exclude_params = [param for param, value in vdu_value.items()
                                  if value is None]
                for exclude_param in exclude_params:
                    del vdu_value[exclude_param]
    
            cps = nfv_dict.get('CP', {})
            for cp_name, cp_value in cps.items():
                cp_name = rm_idx(cp_name)
                if 'network' in cp_value:
                    cp_value['network'] = (
                        common_script_utils.get_param_network_from_inst(
                            cp_name, inst))
                if 'fixed_ips' in cp_value:
                    ext_fixed_ips = (
                        common_script_utils.get_param_fixed_ips_from_inst(
                            cp_name, inst))
                    fixed_ips = []
                    for i in range(len(ext_fixed_ips)):
                        if i not in cp_value['fixed_ips']:
                            break
                        ips_i = cp_value['fixed_ips'][i]
                        if 'subnet' in ips_i:
                            ips_i['subnet'] = ext_fixed_ips[i].get('subnet')
                        if 'ip_address' in ips_i:
                            ips_i['ip_address'] = ext_fixed_ips[i].get(
                                'ip_address')
                        fixed_ips.append(ips_i)
                    cp_value['fixed_ips'] = fixed_ips
                exclude_params = [param for param, value in cp_value.items()
                                  if value is None]
                for exclude_param in exclude_params:
                    del cp_value[exclude_param]
    
            common_script_utils.apply_ext_managed_vls_from_inst(top_hot, inst)
            nfv_dict = _merge_additional_params(nfv_dict, req, grant)
    
            fields = {
                'template': yaml.safe_dump(top_hot),
                'parameters': {'nfv': nfv_dict}
            }
    
            return fields
    
        @staticmethod
        def _scale_in(req, inst, grant_req, grant, tmp_csar_dir):
            template = {'resources': {}}
    
            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']
                template['resources'][add_idx(vdu_name, vdu_idx)] = None
    
            fields = {
                'template': yaml.safe_dump(template),
            }
    
            return fields
    
        @staticmethod
        def scale_rollback(req, inst, grant_req, grant, tmp_csar_dir):
            vnfd = common_script_utils.get_vnfd(inst['vnfdId'], tmp_csar_dir)
            flavour_id = inst['instantiatedVnfInfo']['flavourId']
    
            vdu_nodes = vnfd.get_vdu_nodes(flavour_id)
            vdu_idxes = {}
            for vdu_name in vdu_nodes.keys():
                vdu_idxes[vdu_name] = common_script_utils.get_current_capacity(
                    vdu_name, inst)
    
            template = {'resources': {}}
            for res in grant_req['addResources']:
                if res['type'] != 'COMPUTE':
                    continue
                vdu_name = res['resourceTemplateId']
                vdu_idx = vdu_idxes[vdu_name]
                vdu_idxes[vdu_name] += 1
                template['resources'][add_idx(vdu_name, vdu_idx)] = None
    
            fields = {
                'template': yaml.safe_dump(template),
            }
    
            return fields
    
        @staticmethod
        def change_ext_conn(req, inst, grant_req, grant, tmp_csar_dir):
            # change_ext_conn is interested in 'CP' only.
            # This method returns only 'CP' part in the 'nfv' dict from
            # ChangeExtVnfConnectivityRequest.
            # It is applied to json merge patch against the existing 'nfv'
            # dict by the caller.
            # NOTE: complete 'nfv' dict can not be made at the moment
            # since InstantiateVnfRequest is necessary to make it.
    
            vnfd = common_script_utils.get_vnfd(inst['vnfdId'], tmp_csar_dir)
            flavour_id = inst['instantiatedVnfInfo']['flavourId']
    
            hot_dict = vnfd.get_base_hot(flavour_id)
            top_hot = hot_dict['template']
    
            # first modify VDU resources
            popped_vdu = {}
            for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
                popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
    
            for inst_vnfc in inst['instantiatedVnfInfo'].get(
                    'vnfcResourceInfo', []):
                vdu_idx = inst_vnfc['metadata'].get('vdu_idx')
                if vdu_idx is None:
                    continue
                vdu_name = inst_vnfc['vduId']
                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)
    
            cps = nfv_dict.get('CP', {})
            new_cps = _get_new_cps_from_req(cps, req, grant)
    
            nfv_dict = _merge_additional_params({'CP': new_cps}, req, grant)
            fields = {'parameters': {'nfv': nfv_dict}}
    
            return fields
    
        @staticmethod
        def change_ext_conn_rollback(req, inst, grant_req, grant, tmp_csar_dir):
            fields = {
                'parameters': {
                    'nfv': inst['instantiatedVnfInfo']['metadata']['nfv']
                }
            }
    
            return fields
    
        @staticmethod
        def heal(req, inst, grant_req, grant, tmp_csar_dir):
            vnfd = common_script_utils.get_vnfd(inst['vnfdId'], tmp_csar_dir)
            flavour_id = inst['instantiatedVnfInfo']['flavourId']
    
            vdus = inst['instantiatedVnfInfo']['metadata']['nfv'].get('VDU', {})
            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_name = inst_vnfc['vduId']
                        vdu_idx = inst_vnfc['metadata']['vdu_idx']
                        image = common_script_utils.get_param_image(
                            vdu_name, flavour_id, vnfd, grant, fallback_vnfd=False)
                        if image is not None:
                            vdus[add_idx(vdu_name, vdu_idx)]['vcImageId'] = image
                        break
    
            nfv_dict = _merge_additional_params({'VDU': vdus}, req, grant)
            fields = {'parameters': {'nfv': nfv_dict}}
    
            return fields
    
        @staticmethod
        def change_vnfpkg(req, inst, grant_req, grant, tmp_csar_dir):
            vnfd = common_script_utils.get_vnfd(grant_req['dstVnfdId'],
                                                tmp_csar_dir)
            flavour_id = inst['instantiatedVnfInfo']['flavourId']
    
            hot_dict = vnfd.get_base_hot(flavour_id)
            top_hot = hot_dict['template']
    
            # first modify VDU resources
            popped_vdu = {}
            for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
                popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
    
            target_vnfc_res_ids = [
                res['resource']['resourceId']
                for res in grant_req['removeResources']
                if res['type'] == 'COMPUTE'
            ]
    
            cur_hot_reses = {}
            new_hot_reses = {}
            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']
                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
    
                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
    
            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})
            new_vdus = new_nfv_dict.get('VDU', {})
            vdus = inst['instantiatedVnfInfo']['metadata']['nfv'].get('VDU', {})
    
            for vdu_name_idx, vdu_value in new_vdus.items():
                vdu_name = rm_idx(vdu_name_idx)
                if 'computeFlavourId' in vdu_value:
                    vdus[vdu_name_idx]['computeFlavourId'] = (
                        common_script_utils.get_param_flavor(
                            vdu_name, flavour_id, vnfd, grant))
                if 'vcImageId' in vdu_value:
                    vdus[vdu_name_idx]['vcImageId'] = (
                        common_script_utils.get_param_image(
                            vdu_name, flavour_id, vnfd, grant))
    
            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 = inst['instantiatedVnfInfo']['metadata']['nfv'].get('CP', {})
            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)
    
            nfv_dict = _merge_additional_params({'VDU': vdus, 'CP': cps},
                                                req, grant)
    
            fields = {
                'template': yaml.safe_dump(top_hot),
                'parameters': {'nfv': nfv_dict},
                'files': {},
                'existing': False
            }
            for key, value in hot_dict.get('files', {}).items():
                fields['files'][key] = yaml.safe_dump(value)
    
            return fields
    
        @staticmethod
        def change_vnfpkg_rollback(req, inst, grant_req, grant, tmp_csar_dir):
            vnfd = common_script_utils.get_vnfd(inst['vnfdId'], tmp_csar_dir)
            flavour_id = inst['instantiatedVnfInfo']['flavourId']
    
            hot_dict = vnfd.get_base_hot(flavour_id)
            top_hot = hot_dict['template']
    
            # first modify VDU resources
            popped_vdu = {}
            for vdu_name in vnfd.get_vdu_nodes(flavour_id).keys():
                popped_vdu[vdu_name] = top_hot.get('resources', {}).pop(vdu_name)
    
            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']
                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
    
            common_script_utils.apply_ext_managed_vls(top_hot, req, grant)
    
            fields = {
                'template': yaml.safe_dump(top_hot),
                'parameters': {
                    'nfv': inst['instantiatedVnfInfo']['metadata']['nfv']},
                'files': {},
                'existing': False
            }
            for key, value in hot_dict.get('files', {}).items():
                fields['files'][key] = yaml.safe_dump(value)
    
            return fields
    
  7. Compress the VNF Package CSAR to zip:

    $ cd -
    $ cd ./sample_vnf_package_csar
    $ zip sample_vnf_package_csar.zip \
      -r TOSCA-Metadata/ Definitions/ BaseHOT/ Files/
    

    The contents of the zip file should look something like this.

    $ unzip -Z -1 sample_vnf_package_csar.zip
    TOSCA-Metadata/
    TOSCA-Metadata/TOSCA.meta
    Definitions/
    Definitions/sample_vnfd_types.yaml
    Definitions/etsi_nfv_sol001_vnfd_types.yaml
    Definitions/etsi_nfv_sol001_common_types.yaml
    Definitions/sample_vnfd_df_simple.yaml
    Definitions/sample_vnfd_top.yaml
    BaseHOT/
    BaseHOT/simple/
    BaseHOT/simple/nested/
    BaseHOT/simple/nested/VDU1.yaml
    BaseHOT/simple/sample_lcm_hot.yaml
    Files/
    
    • [This is UserData specific part] When using UserData, add UserData directories.

      $ zip sample_vnf_package_csar.zip -r UserData/
      

      The contents of the zip file should look something like this.

      $ unzip -Z -1 sample_vnf_package_csar.zip
      TOSCA-Metadata/
      TOSCA-Metadata/TOSCA.meta
      Definitions/
      Definitions/sample_vnfd_types.yaml
      Definitions/etsi_nfv_sol001_vnfd_types.yaml
      Definitions/etsi_nfv_sol001_common_types.yaml
      Definitions/sample_vnfd_df_simple.yaml
      Definitions/sample_vnfd_top.yaml
      BaseHOT/
      BaseHOT/simple/
      BaseHOT/simple/nested/
      BaseHOT/simple/nested/VDU1.yaml
      BaseHOT/simple/sample_lcm_hot.yaml
      Files/
      UserData/
      UserData/__init__.py
      UserData/lcm_user_data.py
      

    Here, you can find the structure of the sample VNF Package CSAR as a zip file.

Create VNF Package

  1. Execute vnfpkgm create:

    Take a note of “VNF Package ID” as it will be used in the next step.

    $ cd -
    $ openstack vnf package create
    +-------------------+-------------------------------------------------------------------------------------------------+
    | Field             | Value                                                                                           |
    +-------------------+-------------------------------------------------------------------------------------------------+
    | ID                | 6e6b7a6d-0ebe-4085-96c2-b34269d837f9                                                            |
    | Links             | {                                                                                               |
    |                   |     "self": {                                                                                   |
    |                   |         "href": "/vnfpkgm/v1/vnf_packages/6e6b7a6d-0ebe-4085-96c2-b34269d837f9"                 |
    |                   |     },                                                                                          |
    |                   |     "packageContent": {                                                                         |
    |                   |         "href": "/vnfpkgm/v1/vnf_packages/6e6b7a6d-0ebe-4085-96c2-b34269d837f9/package_content" |
    |                   |     }                                                                                           |
    |                   | }                                                                                               |
    | Onboarding State  | CREATED                                                                                         |
    | Operational State | DISABLED                                                                                        |
    | Usage State       | NOT_IN_USE                                                                                      |
    | User Defined Data | {}                                                                                              |
    +-------------------+-------------------------------------------------------------------------------------------------+
    

Upload VNF Package

  1. Execute vnfpkgm upload:

    The “VNF Package ID” 6e6b7a6d-0ebe-4085-96c2-b34269d837f9 needs to be replaced with the appropriate one that was obtained from Create VNF Package.

    $ openstack vnf package upload \
      --path ./sample_vnf_package_csar/sample_vnf_package_csar.zip \
      6e6b7a6d-0ebe-4085-96c2-b34269d837f9
    Upload request for VNF package 6e6b7a6d-0ebe-4085-96c2-b34269d837f9 has been accepted.
    

Check the created VNF Package

  1. Confirm the “Onboarding State” to be ONBOARDED:

    $ openstack vnf package list
    +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
    | Id                                   | Vnf Product Name | Onboarding State | Usage State | Operational State | Links                                                                                           |
    +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
    | 6e6b7a6d-0ebe-4085-96c2-b34269d837f9 | Sample VNF       | ONBOARDED        | NOT_IN_USE  | ENABLED           | {                                                                                               |
    |                                      |                  |                  |             |                   |     "self": {                                                                                   |
    |                                      |                  |                  |             |                   |         "href": "/vnfpkgm/v1/vnf_packages/6e6b7a6d-0ebe-4085-96c2-b34269d837f9"                 |
    |                                      |                  |                  |             |                   |     },                                                                                          |
    |                                      |                  |                  |             |                   |     "packageContent": {                                                                         |
    |                                      |                  |                  |             |                   |         "href": "/vnfpkgm/v1/vnf_packages/6e6b7a6d-0ebe-4085-96c2-b34269d837f9/package_content" |
    |                                      |                  |                  |             |                   |     }                                                                                           |
    |                                      |                  |                  |             |                   | }                                                                                               |
    +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
    

Create & Instantiate VNF

Create VNF

  1. Find “VNFD ID” to create VNF:

    The “VNFD ID” can be found to be b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 in the example.

    $ openstack vnf package show \
      6e6b7a6d-0ebe-4085-96c2-b34269d837f9 -c 'VNFD ID'
    +---------+--------------------------------------+
    | Field   | Value                                |
    +---------+--------------------------------------+
    | VNFD ID | b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 |
    +---------+--------------------------------------+
    
  2. Create VNF:

    The “VNFD ID” b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 needs to be replaced with the appropriate one.

    $ openstack vnflcm create b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 \
      --os-tacker-api-version 2
    +-----------------------------+------------------------------------------------------------------------------------------------------------------+
    | Field                       | Value                                                                                                            |
    +-----------------------------+------------------------------------------------------------------------------------------------------------------+
    | ID                          | c98b05c7-bc96-43f8-a688-4d8079ffa3bf                                                                             |
    | Instantiation State         | NOT_INSTANTIATED                                                                                                 |
    | Links                       | {                                                                                                                |
    |                             |     "self": {                                                                                                    |
    |                             |         "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/c98b05c7-bc96-43f8-a688-4d8079ffa3bf"             |
    |                             |     },                                                                                                           |
    |                             |     "instantiate": {                                                                                             |
    |                             |         "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/c98b05c7-bc96-43f8-a688-4d8079ffa3bf/instantiate" |
    |                             |     }                                                                                                            |
    |                             | }                                                                                                                |
    | VNF Configurable Properties |                                                                                                                  |
    | VNF Instance Description    |                                                                                                                  |
    | VNF Instance Name           |                                                                                                                  |
    | VNF Product Name            | Sample VNF                                                                                                       |
    | VNF Provider                | Company                                                                                                          |
    | VNF Software Version        | 1.0                                                                                                              |
    | VNFD ID                     | b1bb0ce7-ebca-4fa7-95ed-4840d70a1177                                                                             |
    | VNFD Version                | 1.0                                                                                                              |
    +-----------------------------+------------------------------------------------------------------------------------------------------------------+
    

Instantiate VNF

  1. Create <param-file>:

    Required parameter:

    • flavourId

    Optional parameters:

    • instantiationLevelId

    • extVirtualLinks

    • extManagedVirtualLinks

    • vimConnectionInfo

    • localizationLanguage

    • additionalParams

    • extensions

    • vnfConfigurableProperties

    Note

    You can skip vimConnectionInfo only when you have the default VIM.

    A sample <param-file> named as sample_request.json with minimal parameter:

    $ vi ./sample_request.json
    
    {
      "flavourId": "simple"
    }
    
    • [This is UserData specific part] When using UserData, use the following parameters instead.

      {
        "flavourId":"simple",
        "additionalParams": {
          "lcm-operation-user-data": "./UserData/userdata_standard.py",
          "lcm-operation-user-data-class": "StandardUserData"
        }
      }
      

      Note

      userdata_standard.py should be replaced with the UserData file name. And StandardUserData should be replaced with the UserData class name.

  2. Instantiate VNF:

    The “ID of vnf instance” and “path to <param-file>” are needed to instantiate vnf.

    $ openstack vnflcm instantiate c98b05c7-bc96-43f8-a688-4d8079ffa3bf \
      ./sample_request.json --os-tacker-api-version 2
    Instantiate request for VNF Instance c98b05c7-bc96-43f8-a688-4d8079ffa3bf has been accepted.
    

    Check the details of the instantiated vnf.

    $ openstack vnflcm list --os-tacker-api-version 2
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
    | ID                                   | VNF Instance Name | Instantiation State | VNF Provider | VNF Software Version | VNF Product Name | VNFD ID                              |
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
    | c98b05c7-bc96-43f8-a688-4d8079ffa3bf |                   | INSTANTIATED        | Company      | 1.0                  | Sample VNF       | b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 |
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
    
    $ openstack vnflcm show c98b05c7-bc96-43f8-a688-4d8079ffa3bf \
     --fit-width --os-tacker-api-version 2
    +-----------------------------+--------------------------------------------------------------------------------------------------------------------------------+
    | Field                       | Value                                                                                                                          |
    +-----------------------------+--------------------------------------------------------------------------------------------------------------------------------+
    | ID                          | c98b05c7-bc96-43f8-a688-4d8079ffa3bf                                                                                           |
    | Instantiated Vnf Info       | {                                                                                                                              |
    |                             |     "flavourId": "simple",                                                                                                     |
    |                             |     "vnfState": "STARTED",                                                                                                     |
    |                             |     "scaleStatus": [                                                                                                           |
    |                             |         {                                                                                                                      |
    |                             |             "aspectId": "VDU1_scale",                                                                                          |
    |                             |             "scaleLevel": 0                                                                                                    |
    |                             |         }                                                                                                                      |
    |                             |     ],                                                                                                                         |
    |                             |     "maxScaleLevels": [                                                                                                        |
    |                             |         {                                                                                                                      |
    |                             |             "aspectId": "VDU1_scale",                                                                                          |
    |                             |             "scaleLevel": 2                                                                                                    |
    |                             |         }                                                                                                                      |
    |                             |     ],                                                                                                                         |
    |                             |     "vnfcResourceInfo": [                                                                                                      |
    |                             |         {                                                                                                                      |
    |                             |             "id": "6d01be26-f2be-421d-8c87-a4aa9d39300e",                                                                      |
    |                             |             "vduId": "VDU1",                                                                                                   |
    |                             |             "computeResource": {                                                                                               |
    |                             |                 "vimConnectionId": "bff267c4-6fc9-46b5-be53-15a6a3680033",                                                     |
    |                             |                 "resourceId": "6d01be26-f2be-421d-8c87-a4aa9d39300e",                                                          |
    |                             |                 "vimLevelResourceType": "OS::Nova::Server"                                                                     |
    |                             |             },                                                                                                                 |
    |                             |             "vnfcCpInfo": [                                                                                                    |
    |                             |                 {                                                                                                              |
    |                             |                     "id": "CP1-6d01be26-f2be-421d-8c87-a4aa9d39300e",                                                          |
    |                             |                     "cpdId": "CP1"                                                                                             |
    |                             |                 }                                                                                                              |
    |                             |             ],                                                                                                                 |
    |                             |             "metadata": {                                                                                                      |
    |                             |                 "creation_time": "2023-12-01T06:57:11Z",                                                                       |
    |                             |                 "stack_id": "vnf-c98b05c7-bc96-43f8-a688-4d8079ffa3bf-VDU1-6523jolwu66g/09019137-3b71-426e-8726-8572657999b2", |
    |                             |                 "vdu_idx": null,                                                                                               |
    |                             |                 "flavor": "m1.tiny",                                                                                           |
    |                             |                 "image-VDU1": "cirros-0.5.2-x86_64-disk"                                                                       |
    |                             |             }                                                                                                                  |
    |                             |         }                                                                                                                      |
    |                             |     ],                                                                                                                         |
    |                             |     "vnfVirtualLinkResourceInfo": [                                                                                            |
    |                             |         {                                                                                                                      |
    |                             |             "id": "ffa3b9cf-5135-4dc6-a7a1-dd1912d72363",                                                                      |
    |                             |             "vnfVirtualLinkDescId": "internalVL1",                                                                             |
    |                             |             "networkResource": {                                                                                               |
    |                             |                 "vimConnectionId": "bff267c4-6fc9-46b5-be53-15a6a3680033",                                                     |
    |                             |                 "resourceId": "ffa3b9cf-5135-4dc6-a7a1-dd1912d72363",                                                          |
    |                             |                 "vimLevelResourceType": "OS::Neutron::Net"                                                                     |
    |                             |             }                                                                                                                  |
    |                             |         }                                                                                                                      |
    |                             |     ],                                                                                                                         |
    |                             |     "vnfcInfo": [                                                                                                              |
    |                             |         {                                                                                                                      |
    |                             |             "id": "VDU1-6d01be26-f2be-421d-8c87-a4aa9d39300e",                                                                 |
    |                             |             "vduId": "VDU1",                                                                                                   |
    |                             |             "vnfcResourceInfoId": "6d01be26-f2be-421d-8c87-a4aa9d39300e",                                                      |
    |                             |             "vnfcState": "STARTED"                                                                                             |
    |                             |         }                                                                                                                      |
    |                             |     ],                                                                                                                         |
    |                             |     "metadata": {                                                                                                              |
    |                             |         "stack_id": "0b1b274c-a493-4a2c-994f-ee8569ff111c",                                                                    |
    |                             |         "nfv": {                                                                                                               |
    |                             |             "VDU": {                                                                                                           |
    |                             |                 "VDU1": {                                                                                                      |
    |                             |                     "computeFlavourId": "m1.tiny",                                                                             |
    |                             |                     "vcImageId": "cirros-0.5.2-x86_64-disk"                                                                    |
    |                             |                 }                                                                                                              |
    |                             |             }                                                                                                                  |
    |                             |         },                                                                                                                     |
    |                             |         "tenant": "nfv"                                                                                                        |
    |                             |     }                                                                                                                          |
    |                             | }                                                                                                                              |
    | Instantiation State         | INSTANTIATED                                                                                                                   |
    | Links                       | {                                                                                                                              |
    |                             |     "self": {                                                                                                                  |
    |                             |         "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/c98b05c7-bc96-43f8-a688-4d8079ffa3bf"                           |
    |                             |     },                                                                                                                         |
    |                             |     "terminate": {                                                                                                             |
    |                             |         "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/c98b05c7-bc96-43f8-a688-4d8079ffa3bf/terminate"                 |
    |                             |     },                                                                                                                         |
    |                             |     "scale": {                                                                                                                 |
    |                             |         "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/c98b05c7-bc96-43f8-a688-4d8079ffa3bf/scale"                     |
    |                             |     },                                                                                                                         |
    |                             |     "heal": {                                                                                                                  |
    |                             |         "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/c98b05c7-bc96-43f8-a688-4d8079ffa3bf/heal"                      |
    |                             |     },                                                                                                                         |
    |                             |     "changeExtConn": {                                                                                                         |
    |                             |         "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/c98b05c7-bc96-43f8-a688-4d8079ffa3bf/change_ext_conn"           |
    |                             |     }                                                                                                                          |
    |                             | }                                                                                                                              |
    | VIM Connection Info         | {                                                                                                                              |
    |                             |     "default": {                                                                                                               |
    |                             |         "vimId": "bff267c4-6fc9-46b5-be53-15a6a3680033",                                                                       |
    |                             |         "vimType": "ETSINFV.OPENSTACK_KEYSTONE.V_3",                                                                           |
    |                             |         "interfaceInfo": {                                                                                                     |
    |                             |             "endpoint": "http://192.168.56.10/identity/v3",                                                                    |
    |                             |             "skipCertificateHostnameCheck": true,                                                                              |
    |                             |             "skipCertificateVerification": true                                                                                |
    |                             |         },                                                                                                                     |
    |                             |         "accessInfo": {                                                                                                        |
    |                             |             "username": "nfv_user",                                                                                            |
    |                             |             "region": "RegionOne",                                                                                             |
    |                             |             "project": "nfv",                                                                                                  |
    |                             |             "projectDomain": "default",                                                                                        |
    |                             |             "userDomain": "default"                                                                                            |
    |                             |         },                                                                                                                     |
    |                             |         "extra": {}                                                                                                            |
    |                             |     }                                                                                                                          |
    |                             | }                                                                                                                              |
    | VNF Configurable Properties |                                                                                                                                |
    | VNF Instance Description    |                                                                                                                                |
    | VNF Instance Name           |                                                                                                                                |
    | VNF Product Name            | Sample VNF                                                                                                                     |
    | VNF Provider                | Company                                                                                                                        |
    | VNF Software Version        | 1.0                                                                                                                            |
    | VNFD ID                     | b1bb0ce7-ebca-4fa7-95ed-4840d70a1177                                                                                           |
    | VNFD Version                | 1.0                                                                                                                            |
    +-----------------------------+--------------------------------------------------------------------------------------------------------------------------------+
    

Terminate & Delete VNF

Terminate VNF

  1. Check the VNF Instance ID to terminate:

    $ openstack vnflcm list --os-tacker-api-version 2
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
    | ID                                   | VNF Instance Name | Instantiation State | VNF Provider | VNF Software Version | VNF Product Name | VNFD ID                              |
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
    | c98b05c7-bc96-43f8-a688-4d8079ffa3bf |                   | INSTANTIATED        | Company      | 1.0                  | Sample VNF       | b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 |
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
    
  2. Terminate VNF Instance:

    Execute terminate command:

    $ openstack vnflcm terminate c98b05c7-bc96-43f8-a688-4d8079ffa3bf --os-tacker-api-version 2
    Terminate request for VNF Instance 'c98b05c7-bc96-43f8-a688-4d8079ffa3bf' has been accepted.
    

    Check the status of VNF Instance:

    $ openstack vnflcm list --os-tacker-api-version 2
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
    | ID                                   | VNF Instance Name | Instantiation State | VNF Provider | VNF Software Version | VNF Product Name | VNFD ID                              |
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
    | c98b05c7-bc96-43f8-a688-4d8079ffa3bf |                   | NOT_INSTANTIATED    | Company      | 1.0                  | Sample VNF       | b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 |
    +--------------------------------------+-------------------+---------------------+--------------+----------------------+------------------+--------------------------------------+
    

Delete VNF

  1. Delete VNF Instance:

    $ openstack vnflcm delete c98b05c7-bc96-43f8-a688-4d8079ffa3bf --os-tacker-api-version 2
    Vnf instance 'c98b05c7-bc96-43f8-a688-4d8079ffa3bf' is deleted successfully
    

Delete VNF Package

  1. Delete VNF Package:

    Check the VNF Package ID to delete:

    $ openstack vnf package list
    +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
    | Id                                   | Vnf Product Name | Onboarding State | Usage State | Operational State | Links                                                                                           |
    +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
    | 6e6b7a6d-0ebe-4085-96c2-b34269d837f9 | Sample VNF       | ONBOARDED        | NOT_IN_USE  | ENABLED           | {                                                                                               |
    |                                      |                  |                  |             |                   |     "self": {                                                                                   |
    |                                      |                  |                  |             |                   |         "href": "/vnfpkgm/v1/vnf_packages/6e6b7a6d-0ebe-4085-96c2-b34269d837f9"                 |
    |                                      |                  |                  |             |                   |     },                                                                                          |
    |                                      |                  |                  |             |                   |     "packageContent": {                                                                         |
    |                                      |                  |                  |             |                   |         "href": "/vnfpkgm/v1/vnf_packages/6e6b7a6d-0ebe-4085-96c2-b34269d837f9/package_content" |
    |                                      |                  |                  |             |                   |     }                                                                                           |
    |                                      |                  |                  |             |                   | }                                                                                               |
    +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
    

    Update the Operational State to DISABLED:

    $ openstack vnf package update --operational-state 'DISABLED' \
      6e6b7a6d-0ebe-4085-96c2-b34269d837f9
    +-------------------+----------+
    | Field             | Value    |
    +-------------------+----------+
    | Operational State | DISABLED |
    +-------------------+----------+
    

    Check the Operational State to be changed:

    $ openstack vnf package list
    +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
    | Id                                   | Vnf Product Name | Onboarding State | Usage State | Operational State | Links                                                                                           |
    +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
    | 6e6b7a6d-0ebe-4085-96c2-b34269d837f9 | Sample VNF       | ONBOARDED        | NOT_IN_USE  | DISABLED          | {                                                                                               |
    |                                      |                  |                  |             |                   |     "self": {                                                                                   |
    |                                      |                  |                  |             |                   |         "href": "/vnfpkgm/v1/vnf_packages/6e6b7a6d-0ebe-4085-96c2-b34269d837f9"                 |
    |                                      |                  |                  |             |                   |     },                                                                                          |
    |                                      |                  |                  |             |                   |     "packageContent": {                                                                         |
    |                                      |                  |                  |             |                   |         "href": "/vnfpkgm/v1/vnf_packages/6e6b7a6d-0ebe-4085-96c2-b34269d837f9/package_content" |
    |                                      |                  |                  |             |                   |     }                                                                                           |
    |                                      |                  |                  |             |                   | }                                                                                               |
    +--------------------------------------+------------------+------------------+-------------+-------------------+-------------------------------------------------------------------------------------------------+
    

    Delete the VNF Package:

    $ openstack vnf package delete 6e6b7a6d-0ebe-4085-96c2-b34269d837f9
    All specified vnf-package(s) deleted successfully