aboutsummaryrefslogtreecommitdiffstats
path: root/src/onapsdk/aai/business/vnf.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/onapsdk/aai/business/vnf.py')
-rw-r--r--src/onapsdk/aai/business/vnf.py536
1 files changed, 536 insertions, 0 deletions
diff --git a/src/onapsdk/aai/business/vnf.py b/src/onapsdk/aai/business/vnf.py
new file mode 100644
index 0000000..2045291
--- /dev/null
+++ b/src/onapsdk/aai/business/vnf.py
@@ -0,0 +1,536 @@
+"""Vnf instance module."""
+# Copyright 2022 Orange, Deutsche Telekom AG
+#
+# 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 typing import Iterable, Iterator
+
+from onapsdk.exceptions import ResourceNotFound, StatusError
+from onapsdk.so.deletion import VnfDeletionRequest
+from onapsdk.so.instantiation import VfModuleInstantiation, VnfInstantiation, SoService, \
+ InstantiationParameter, VnfOperation
+from onapsdk.configuration import settings
+
+from .instance import Instance
+from .vf_module import VfModuleInstance
+
+
+class VnfInstance(Instance): # pylint: disable=too-many-instance-attributes
+ """VNF Instance class."""
+
+ def __init__(self, # pylint: disable=too-many-arguments, too-many-locals
+ service_instance: "ServiceInstance",
+ vnf_id: str,
+ vnf_type: str,
+ in_maint: bool,
+ is_closed_loop_disabled: bool,
+ vnf_name: str = None,
+ service_id: str = None,
+ regional_resource_zone: str = None,
+ prov_status: str = None,
+ operational_status: str = None,
+ equipment_role: str = None,
+ orchestration_status: str = None,
+ vnf_package_name: str = None,
+ vnf_discriptor_name: str = None,
+ job_id: str = None,
+ heat_stack_id: str = None,
+ mso_catalog_key: str = None,
+ management_option: str = None,
+ ipv4_oam_address: str = None,
+ ipv4_loopback0_address: str = None,
+ nm_lan_v6_address: str = None,
+ management_v6_address: str = None,
+ vcpu: int = None,
+ vcpu_units: str = None,
+ vmemory: int = None,
+ vmemory_units: str = None,
+ vdisk: int = None,
+ vdisk_units: str = None,
+ nshd: int = None,
+ nvm: int = None,
+ nnet: int = None,
+ resource_version: str = None,
+ encrypted_access_flag: bool = None,
+ model_invariant_id: str = None,
+ model_version_id: str = None,
+ persona_model_version: str = None,
+ model_customization_id: str = None,
+ widget_model_id: str = None,
+ widget_model_version: str = None,
+ as_number: str = None,
+ regional_resource_subzone: str = None,
+ nf_type: str = None,
+ nf_function: str = None,
+ nf_role: str = None,
+ nf_naming_code: str = None,
+ selflink: str = None,
+ ipv4_oam_gateway_address: str = None,
+ ipv4_oam_gateway_address_prefix_length: int = None,
+ vlan_id_outer: int = None,
+ nm_profile_name: str = None) -> None:
+ """Vnf instance object initialization.
+
+ Args:
+ vnf_id (str): Unique id of VNF. This is unique across the graph.
+ vnf_type (str): String capturing type of vnf, that was intended to identify
+ the ASDC resource. This field has been overloaded in service-specific ways and
+ clients should expect changes to occur in the future to this field as ECOMP
+ matures.
+ in_maint (bool): used to indicate whether or not this object is in maintenance mode
+ (maintenance mode = true). This field (in conjunction with prov-status)
+ is used to suppress alarms and vSCL on VNFs/VMs.
+ is_closed_loop_disabled (bool): used to indicate whether closed loop function is
+ enabled on this node
+ vnf_name (str, optional): Name of VNF. Defaults to None.
+ service_id (str, optional): Unique identifier of service, does not necessarily map to
+ ASDC service models. Defaults to None.
+ regional_resource_zone (str, optional): Regional way of organizing pservers, source of
+ truth should define values. Defaults to None.
+ prov_status (str, optional): Trigger for operational monitoring of this resource by
+ Service Assurance systems. Defaults to None.
+ operational_status (str, optional): Indicator for whether the resource is considered
+ operational. Valid values are in-service-path and out-of-service-path.
+ Defaults to None.
+ equipment_role (str, optional): Client should send valid enumerated value.
+ Defaults to None.
+ orchestration_status (str, optional): Orchestration status of this VNF, used by MSO.
+ Defaults to None.
+ vnf_package_name (str, optional): vnf package name. Defaults to None.
+ vnf_discriptor_name (str, optional): vnf discriptor name. Defaults to None.
+ job_id (str, optional): job id corresponding to vnf. Defaults to None.
+ heat_stack_id (str, optional): Heat stack id corresponding to this instance,
+ managed by MSO. Defaults to None.
+ mso_catalog_key (str, optional): Corresponds to the SDN-C catalog id used to
+ configure this VCE. Defaults to None.
+ management_option (str, optional): identifier of managed customer. Defaults to None.
+ ipv4_oam_address (str, optional): Address tail-f uses to configure generic-vnf,
+ also used for troubleshooting and is IP used for traps generated by generic-vnf.
+ Defaults to None.
+ ipv4_loopback0_address (str, optional): v4 Loopback0 address. Defaults to None.
+ nm_lan_v6_address (str, optional): v6 Loopback address. Defaults to None.
+ management_v6_address (str, optional): v6 management address. Defaults to None.
+ vcpu (int, optional): number of vcpus ordered for this instance of VNF,
+ used for VNFs with no vservers/flavors, to be used only by uCPE. Defaults to None.
+ vcpu_units (str, optional): units associated with vcpu, used for VNFs with no
+ vservers/flavors, to be used only by uCPE. Defaults to None.
+ vmemory (int, optional): number of GB of memory ordered for this instance of VNF,
+ used for VNFs with no vservers/flavors, to be used only by uCPE. Defaults to None.
+ vmemory_units (str, optional): units associated with vmemory, used for VNFs with
+ no vservers/flavors, to be used only by uCPE. Defaults to None.
+ vdisk (int, optional): number of vdisks ordered for this instance of VNF,
+ used for VNFs with no vservers/flavors, to be used only uCPE. Defaults to None.
+ vdisk_units (str, optional): units associated with vdisk, used for VNFs with
+ no vservers/flavors, to be used only by uCPE. Defaults to None.
+ nshd (int, optional): number of associated SHD in vnf. Defaults to None.
+ nvm (int, optional): number of vms in vnf. Defaults to None.
+ nnet (int, optional): number of network in vnf. Defaults to None.
+ resource_version (str, optional): Used for optimistic concurrency.
+ Must be empty on create, valid on update and delete. Defaults to None.
+ encrypted_access_flag (bool, optional): indicates whether generic-vnf access uses SSH.
+ Defaults to None.
+ model_invariant_id (str, optional): the ASDC model id for this resource or
+ service model. Defaults to None.
+ model_version_id (str, optional): the ASDC model version for this resource or
+ service model. Defaults to None.
+ persona_model_version (str, optional): the ASDC model version for this resource or
+ service model. Defaults to None.
+ model_customization_id (str, optional): captures the id of all the configuration used
+ to customize the resource for the service. Defaults to None.
+ widget_model_id (str, optional): the ASDC data dictionary widget model. This maps
+ directly to the A&AI widget. Defaults to None.
+ widget_model_version (str, optional): the ASDC data dictionary version of
+ the widget model.This maps directly to the A&AI version of the widget.
+ Defaults to None.
+ as_number (str, optional): as-number of the VNF. Defaults to None.
+ regional_resource_subzone (str, optional): represents sub zone of the rr plane.
+ Defaults to None.
+ nf_type (str, optional): Generic description of the type of NF. Defaults to None.
+ nf_function (str, optional): English description of Network function that
+ the specific VNF deployment is providing. Defaults to None.
+ nf_role (str, optional): role in the network that this model will be providing.
+ Defaults to None.
+ nf_naming_code (str, optional): string assigned to this model used for naming purposes.
+ Defaults to None.
+ selflink (str, optional): Path to the controller object. Defaults to None.
+ ipv4_oam_gateway_address (str, optional): Gateway address. Defaults to None.
+ ipv4_oam_gateway_address_prefix_length (int, optional): Prefix length for oam-address.
+ Defaults to None.
+ vlan_id_outer (int, optional): Temporary location for S-TAG to get to VCE.
+ Defaults to None.
+ nm_profile_name (str, optional): Network Management profile of this VNF.
+ Defaults to None.
+
+ """
+ super().__init__(resource_version=resource_version,
+ model_invariant_id=model_invariant_id,
+ model_version_id=model_version_id)
+ self.service_instance: "ServiceInstance" = service_instance
+ self.vnf_id: str = vnf_id
+ self.vnf_type: str = vnf_type
+ self.in_maint: bool = in_maint
+ self.is_closed_loop_disabled: bool = is_closed_loop_disabled
+ self.vnf_name: str = vnf_name
+ self.service_id: str = service_id
+ self.regional_resource_zone: str = regional_resource_zone
+ self.prov_status: str = prov_status
+ self.operational_status: str = operational_status
+ self.equipment_role: str = equipment_role
+ self.orchestration_status: str = orchestration_status
+ self.vnf_package_name: str = vnf_package_name
+ self.vnf_discriptor_name: str = vnf_discriptor_name
+ self.job_id: str = job_id
+ self.heat_stack_id: str = heat_stack_id
+ self.mso_catalog_key: str = mso_catalog_key
+ self.management_option: str = management_option
+ self.ipv4_oam_address: str = ipv4_oam_address
+ self.ipv4_loopback0_address: str = ipv4_loopback0_address
+ self.nm_lan_v6_address: str = nm_lan_v6_address
+ self.management_v6_address: str = management_v6_address
+ self.vcpu: int = vcpu
+ self.vcpu_units: str = vcpu_units
+ self.vmemory: int = vmemory
+ self.vmemory_units: str = vmemory_units
+ self.vdisk: int = vdisk
+ self.vdisk_units: str = vdisk_units
+ self.nshd: int = nshd
+ self.nvm: int = nvm
+ self.nnet: int = nnet
+ self.encrypted_access_flag: bool = encrypted_access_flag
+ self.model_customization_id: str = model_customization_id
+ self.as_number: str = as_number
+ self.regional_resource_subzone: str = regional_resource_subzone
+ self.nf_type: str = nf_type
+ self.nf_function: str = nf_function
+ self.nf_role: str = nf_role
+ self.nf_naming_code: str = nf_naming_code
+ self.selflink: str = selflink
+ self.ipv4_oam_gateway_address: str = ipv4_oam_gateway_address
+ self.ipv4_oam_gateway_address_prefix_length: int = ipv4_oam_gateway_address_prefix_length
+ self.vlan_id_outer: int = vlan_id_outer
+ self.nm_profile_name: str = nm_profile_name
+ self.persona_model_version: str = persona_model_version
+ self.widget_model_id: str = widget_model_id
+ self.widget_model_version: str = widget_model_version
+
+ self._vnf: "Vnf" = None
+
+ def __repr__(self) -> str:
+ """Vnf instance object representation.
+
+ Returns:
+ str: Human readable vnf instance representation
+
+ """
+ return (f"VnfInstance(vnf_id={self.vnf_id}, vnf_type={self.vnf_type}, "
+ f"in_maint={self.in_maint}, "
+ f"is_closed_loop_disabled={self.is_closed_loop_disabled})")
+
+ @classmethod
+ def get_all_url(cls) -> str: # pylint: disable=arguments-differ
+ """Return url to get all vnfs.
+
+ Returns:
+ str: Url to get all vnfs
+
+ """
+ return f"{cls.base_url}{cls.api_version}/network/generic-vnfs/"
+
+ @property
+ def url(self) -> str:
+ """Vnf instance url.
+
+ Returns:
+ str: VnfInstance url
+
+ """
+ return f"{self.base_url}{self.api_version}/network/generic-vnfs/generic-vnf/{self.vnf_id}"
+
+ @property
+ def vf_modules(self) -> Iterator[VfModuleInstance]:
+ """Vf modules associated with vnf instance.
+
+ Yields:
+ VfModuleInstance: VfModuleInstance associated with VnfInstance
+
+ """
+ for vf_module in self.send_message_json("GET",
+ f"GET VNF {self.vnf_name} VF modules",
+ f"{self.url}/vf-modules").get("vf-module", []):
+ yield VfModuleInstance.create_from_api_response(vf_module, self)
+
+ @property
+ def vnf(self) -> "Vnf":
+ """Vnf associated with that vnf instance.
+
+ Raises:
+ ResourceNotFound: Could not find VNF for that VNF instance
+
+ Returns:
+ Vnf: Vnf object associated with vnf instance
+
+ """
+ if not self._vnf:
+ for vnf in self.service_instance.sdc_service.vnfs:
+ if vnf.model_version_id == self.model_version_id:
+ self._vnf = vnf
+ return self._vnf
+
+ msg = (
+ f'Could not find VNF for the VNF instance'
+ f' with model version ID "{self.model_version_id}"'
+ )
+ raise ResourceNotFound(msg)
+ return self._vnf
+
+ @classmethod
+ def create_from_api_response(cls, api_response: dict,
+ service_instance: "ServiceInstance") -> "VnfInstance":
+ """Create vnf instance object using HTTP API response dictionary.
+
+ Returns:
+ VnfInstance: VnfInstance object
+
+ """
+ return cls(service_instance=service_instance,
+ vnf_id=api_response.get("vnf-id"),
+ vnf_type=api_response.get("vnf-type"),
+ in_maint=api_response.get("in-maint"),
+ is_closed_loop_disabled=api_response.get("is-closed-loop-disabled"),
+ vnf_name=api_response.get("vnf-name"),
+ service_id=api_response.get("service-id"),
+ regional_resource_zone=api_response.get("regional-resource-zone"),
+ prov_status=api_response.get("prov-status"),
+ operational_status=api_response.get("operational-status"),
+ equipment_role=api_response.get("equipment-role"),
+ orchestration_status=api_response.get("orchestration-status"),
+ vnf_package_name=api_response.get("vnf-package-name"),
+ vnf_discriptor_name=api_response.get("vnf-discriptor-name"),
+ job_id=api_response.get("job-id"),
+ heat_stack_id=api_response.get("heat-stack-id"),
+ mso_catalog_key=api_response.get("mso-catalog-key"),
+ management_option=api_response.get("management-option"),
+ ipv4_oam_address=api_response.get("ipv4-oam-address"),
+ ipv4_loopback0_address=api_response.get("ipv4-loopback0-address"),
+ nm_lan_v6_address=api_response.get("nm-lan-v6-address"),
+ management_v6_address=api_response.get("management-v6-address"),
+ vcpu=api_response.get("vcpu"),
+ vcpu_units=api_response.get("vcpu-units"),
+ vmemory=api_response.get("vmemory"),
+ vmemory_units=api_response.get("vmemory-units"),
+ vdisk=api_response.get("vdisk"),
+ vdisk_units=api_response.get("vdisk-units"),
+ nshd=api_response.get("nshd"),
+ nvm=api_response.get("nvm"),
+ nnet=api_response.get("nnet"),
+ resource_version=api_response.get("resource-version"),
+ model_invariant_id=api_response.get("model-invariant-id"),
+ model_version_id=api_response.get("model-version-id"),
+ encrypted_access_flag=api_response.get("encrypted-access-flag"),
+ persona_model_version=api_response.get("persona-model-version"),
+ model_customization_id=api_response.get("model-customization-id"),
+ widget_model_id=api_response.get("widget-model-id"),
+ widget_model_version=api_response.get("widget-model-version"),
+ as_number=api_response.get("as-number"),
+ regional_resource_subzone=api_response.get("regional-resource-subzone"),
+ nf_type=api_response.get("nf-type"),
+ nf_function=api_response.get("nf-function"),
+ nf_role=api_response.get("nf-role"),
+ nf_naming_code=api_response.get("nf-naming-code"),
+ selflink=api_response.get("selflink"),
+ ipv4_oam_gateway_address=api_response.get("ipv4-oam-gateway-address"),
+ ipv4_oam_gateway_address_prefix_length=\
+ api_response.get("ipv4-oam-gateway-address-prefix-length"),
+ vlan_id_outer=api_response.get("vlan-id-outer"),
+ nm_profile_name=api_response.get("nm-profile-name"))
+
+ def add_vf_module(self, # pylint: disable=too-many-arguments
+ vf_module: "VfModule",
+ cloud_region: "CloudRegion" = None,
+ tenant: "Tenant" = None,
+ vf_module_instance_name: str = None,
+ vnf_parameters: Iterable["InstantiationParameter"] = None,
+ use_preload: bool = True
+ ) -> "VfModuleInstantiation":
+ """Instantiate vf module for that VNF instance.
+
+ Args:
+ vf_module (VfModule): VfModule to instantiate
+ cloud_region (CloudRegion, optional): Cloud region to use in instantiation request.
+ Defaults to None.
+ THAT PROPERTY WILL BE REQUIRED IN ONE OF THE FUTURE RELEASE. REFACTOR YOUR CODE
+ TO USE IT!.
+ tenant (Tenant, optional): Tenant to use in instnatiation request.
+ Defaults to None.
+ THAT PROPERTY WILL BE REQUIRED IN ONE OF THE FUTURE RELEASE. REFACTOR YOUR CODE
+ TO USE IT!.
+ vf_module_instance_name (str, optional): VfModule instance name. Defaults to None.
+ vnf_parameters (Iterable[InstantiationParameter], optional): InstantiationParameter
+ to use for preloading or to be passed as "userParams". Defaults to None.
+ use_preload (bool, optional): Based on this flag InstantiationParameters are passed
+ in preload or as "userParam" in the request. Defaults to True
+
+ Returns:
+ VfModuleInstantiation: VfModuleInstantiation request object
+
+ """
+ return VfModuleInstantiation.instantiate_ala_carte(
+ vf_module,
+ self,
+ cloud_region=cloud_region,
+ tenant=tenant,
+ vf_module_instance_name=vf_module_instance_name,
+ vnf_parameters=vnf_parameters,
+ use_preload=use_preload
+ )
+
+ def update(self,
+ vnf_parameters: Iterable["InstantiationParameter"] = None
+ ) -> VnfInstantiation:
+ """Update vnf instance.
+
+ Args:
+ vnf_parameters (Iterable["InstantiationParameter"], Optional): list of instantiation
+ parameters for update operation.
+ Raises:
+ StatusError: Skip post instantiation configuration flag for VF to True.
+ It might cause problems with SO component.
+
+ Returns:
+ VnfInstantiation: VnfInstantiation object.
+
+ """
+ skip_flag = next(p for p in self.vnf.properties
+ if p.name == 'skip_post_instantiation_configuration')
+ if not skip_flag.value or skip_flag.value != "false":
+ raise StatusError("Operation for the vnf is not supported! "
+ "Skip_post_instantiation_configuration flag for VF should be False")
+
+ return self._execute_so_action(operation_type=VnfOperation.UPDATE,
+ vnf_parameters=vnf_parameters)
+
+ def healthcheck(self) -> VnfInstantiation:
+ """Execute healthcheck operation for vnf instance.
+
+ Returns:
+ VnfInstantiation: VnfInstantiation object.
+
+ """
+ return self._execute_so_action(operation_type=VnfOperation.HEALTHCHECK)
+
+ def _execute_so_action(self,
+ operation_type: VnfOperation,
+ vnf_parameters: Iterable["InstantiationParameter"] = None
+ ) -> VnfInstantiation:
+ """Execute SO workflow for selected operation.
+
+ Args:
+ operation_type (str): Name of the operation to execute.
+ vnf_parameters (Iterable["InstantiationParameter"], Optional): list of instantiation
+ parameters for update operation.
+
+ Returns:
+ VnfInstantiation: VnfInstantiation object.
+
+ """
+ if not self.service_instance.active:
+ msg = f'Service orchestration status must be "Active"'
+ raise StatusError(msg)
+
+ lob = settings.LOB
+ platform = settings.PLATFORM
+
+ for relationship in self.relationships:
+ if relationship.related_to == "line-of-business":
+ lob = relationship.relationship_data.pop().get("relationship-value")
+ if relationship.related_to == "platform":
+ platform = relationship.relationship_data.pop().get("relationship-value")
+
+ so_input = self._build_so_input(vnf_params=vnf_parameters)
+
+ return VnfInstantiation.so_action(
+ vnf_instance=self,
+ operation_type=operation_type,
+ aai_service_instance=self.service_instance,
+ line_of_business=lob,
+ platform=platform,
+ sdc_service=self.service_instance.sdc_service,
+ so_service=so_input
+ )
+
+ def _build_so_input(self, vnf_params: Iterable[InstantiationParameter] = None) -> SoService:
+ """Prepare so_input with params retrieved from existing service instance.
+
+ Args:
+ vnf_params (Iterable[InstantiationParameter], Optional): list of instantiation
+ parameters for update operation.
+
+ Returns:
+ SoService: SoService object to store SO Service parameters used for macro instantiation.
+
+ """
+ so_vnfs = []
+ so_pnfs = []
+
+ if not vnf_params:
+ vnf_params = []
+
+ for pnf in self.service_instance.pnfs:
+ _pnf = {
+ "model_name": pnf.pnf.model_name,
+ "instance_name": pnf.pnf_name
+ }
+
+ so_pnfs.append(_pnf)
+
+ for vnf in self.service_instance.vnf_instances:
+ _vnf = {"model_name": vnf.vnf.model_name,
+ "instance_name": vnf.vnf_name,
+ "parameters": {}}
+ if vnf.vnf_name == self.vnf_name:
+ for _param in vnf_params:
+ _vnf["parameters"][_param.name] = _param.value
+
+ _vf_modules = []
+ for vf_module in vnf.vf_modules:
+ _vf_module = {
+ "model_name": vf_module.vf_module.model_name.split('..')[1],
+ "instance_name": vf_module.vf_module_name,
+ "parameters": {}
+ }
+
+ _vf_modules.append(_vf_module)
+
+ _vnf["vf_modules"] = _vf_modules
+ so_vnfs.append(_vnf)
+
+ return SoService.load(data={
+ 'subscription_service_type': self.service_instance.service_subscription.service_type,
+ 'vnfs': so_vnfs,
+ 'pnfs': so_pnfs
+ })
+
+ def delete(self, a_la_carte: bool = True) -> "VnfDeletionRequest":
+ """Create VNF deletion request.
+
+ Send request to delete VNF instance
+
+ Args:
+ a_la_carte (boolean): deletion mode
+
+ Returns:
+ VnfDeletionRequest: Deletion request
+
+ """
+ self._logger.debug("Delete %s VNF", self.vnf_id)
+ return VnfDeletionRequest.send_request(self, a_la_carte)