aboutsummaryrefslogtreecommitdiffstats
path: root/src/onapsdk/so/so_element.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/onapsdk/so/so_element.py')
-rw-r--r--src/onapsdk/so/so_element.py223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/onapsdk/so/so_element.py b/src/onapsdk/so/so_element.py
new file mode 100644
index 0000000..fca6ba7
--- /dev/null
+++ b/src/onapsdk/so/so_element.py
@@ -0,0 +1,223 @@
+"""SO Element 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.
+import json
+from abc import ABC
+from dataclasses import dataclass
+from enum import Enum
+from typing import Dict
+
+from onapsdk.configuration import settings
+from onapsdk.sdc.service import Service
+from onapsdk.sdc.vf import Vf
+from onapsdk.onap_service import OnapService
+from onapsdk.utils.headers_creator import headers_so_creator
+from onapsdk.utils.jinja import jinja_env
+from onapsdk.utils.mixins import WaitForFinishMixin
+from onapsdk.utils.tosca_file_handler import get_modules_list_from_tosca_file
+from onapsdk.utils.gui import GuiItem, GuiList
+
+@dataclass
+class SoElement(OnapService):
+ """Mother Class of all SO elements."""
+
+ name: str = None
+ _server: str = "SO"
+ base_url = settings.SO_URL
+ api_version = settings.SO_API_VERSION
+ _status: str = None
+
+ @property
+ def headers(self):
+ """Create headers for SO request.
+
+ It is used as a property because x-transactionid header should be unique for each request.
+ """
+ return headers_so_creator(OnapService.headers)
+
+ @classmethod
+ def get_subscription_service_type(cls, vf_name):
+ """Retrieve the model info of the VFs."""
+ vf_object = Vf(name=vf_name)
+ return vf_object.name
+
+ @classmethod
+ def get_service_model_info(cls, service_name):
+ """Retrieve Service Model info."""
+ service = Service(name=service_name)
+ template_service = jinja_env().get_template("service_instance_model_info.json.j2")
+ # Get service instance model
+ parsed = json.loads(
+ template_service.render(
+ model_invariant_id=service.unique_uuid,
+ model_name_version_id=service.identifier,
+ model_name=service.name,
+ model_version=service.version,
+ )
+ )
+ return json.dumps(parsed, indent=4)
+
+ @classmethod
+ def get_vnf_model_info(cls, vf_name):
+ """Retrieve the model info of the VFs."""
+ vf_object = Vf(name=vf_name)
+ template_service = jinja_env().get_template("vnf_model_info.json.j2")
+ parsed = json.loads(
+ template_service.render(
+ vnf_model_invariant_uuid=vf_object.unique_uuid,
+ vnf_model_customization_id="????",
+ vnf_model_version_id=vf_object.identifier,
+ vnf_model_name=vf_object.name,
+ vnf_model_version=vf_object.version,
+ vnf_model_instance_name=(vf_object.name + " 0"),
+ )
+ )
+ # we need also a vnf instance Name
+ # Usually it is found like that
+ # name: toto
+ # instance name: toto 0
+ # it can be retrieved from the toscafrom onapsdk.configuration import settings
+ return json.dumps(parsed, indent=4)
+
+ @classmethod
+ def get_vf_model_info(cls, vf_model: str) -> str:
+ """Retrieve the VF model info From Tosca?."""
+ modules: Dict = get_modules_list_from_tosca_file(vf_model)
+ template_service = jinja_env().get_template("vf_model_info.json.j2")
+ parsed = json.loads(template_service.render(modules=modules))
+ return json.dumps(parsed, indent=4)
+
+ @classmethod
+ def _base_create_url(cls) -> str:
+ """
+ Give back the base url of SO.
+
+ Returns:
+ str: the base url
+
+ """
+ return "{}/onap/so/infra/serviceInstantiation/{}/serviceInstances".format(
+ cls.base_url, cls.api_version
+ )
+
+ @classmethod
+ def get_guis(cls) -> GuiItem:
+ """Retrieve the status of the SO GUIs.
+
+ Only one GUI is referenced for SO: SO monitor
+
+ Return the list of GUIs
+ """
+ gui_url = settings.SO_MONITOR_GUI_SERVICE
+ so_gui_response = cls.send_message(
+ "GET", "Get SO GUI Status", gui_url)
+ guilist = GuiList([])
+ guilist.add(GuiItem(
+ gui_url,
+ so_gui_response.status_code))
+ return guilist
+
+
+class OrchestrationRequest(SoElement, WaitForFinishMixin, ABC):
+ """Base SO orchestration request class."""
+
+ WAIT_FOR_SLEEP_TIME = 10
+
+ def __init__(self,
+ request_id: str) -> None:
+ """Instantiate object initialization.
+
+ Initializator used by classes inherited from this abstract class.
+
+ Args:
+ request_id (str): request ID
+ """
+ super().__init__()
+ self.request_id: str = request_id
+
+ class StatusEnum(Enum):
+ """Status enum.
+
+ Store possible statuses for instantiation:
+ - IN_PROGRESS,
+ - FAILED,
+ - COMPLETE.
+ If instantiation has status which is not covered by these values
+ UNKNOWN value is used.
+
+ """
+
+ IN_PROGRESS = "IN_PROGRESS"
+ FAILED = "FAILED"
+ COMPLETED = "COMPLETE"
+ UNKNOWN = "UNKNOWN"
+
+ @property
+ def status(self) -> "StatusEnum":
+ """Object instantiation status.
+
+ It's populated by call SO orchestation request endpoint.
+
+ Returns:
+ StatusEnum: Instantiation status.
+
+ """
+ response: dict = self.send_message_json(
+ "GET",
+ f"Check {self.request_id} orchestration request status",
+ (f"{self.base_url}/onap/so/infra/"
+ f"orchestrationRequests/{self.api_version}/{self.request_id}"),
+ headers=headers_so_creator(OnapService.headers)
+ )
+ try:
+ return self.StatusEnum(response["request"]["requestStatus"]["requestState"])
+ except (KeyError, ValueError):
+ self._logger.exception("Invalid status")
+ return self.StatusEnum.UNKNOWN
+
+ @property
+ def finished(self) -> bool:
+ """Store an information if instantion is finished or not.
+
+ Instantiation is finished if it's status is COMPLETED or FAILED.
+
+ Returns:
+ bool: True if instantiation is finished, False otherwise.
+
+ """
+ return self.status in [self.StatusEnum.COMPLETED, self.StatusEnum.FAILED]
+
+ @property
+ def completed(self) -> bool:
+ """Store an information if instantion is completed or not.
+
+ Instantiation is completed if it's status is COMPLETED.
+
+ Returns:
+ bool: True if instantiation is completed, False otherwise.
+
+ """
+ return self.finished and self.status == self.StatusEnum.COMPLETED
+
+ @property
+ def failed(self) -> bool:
+ """Store an information if instantion is failed or not.
+
+ Instantiation is failed if it's status is FAILED.
+
+ Returns:
+ bool: True if instantiation is failed, False otherwise.
+
+ """
+ return self.finished and self.status == self.StatusEnum.FAILED