aboutsummaryrefslogtreecommitdiffstats
path: root/src/onapsdk
diff options
context:
space:
mode:
authorLukasz Rajewski <lukasz.rajewski@t-mobile.pl>2023-02-27 14:18:18 +0100
committerLukasz Rajewski <lukasz.rajewski@t-mobile.pl>2023-03-01 18:37:40 +0000
commit04d216408b1fe94337775a6e528175733d055f25 (patch)
tree0f7f52004f0e963f441f0b16dd906bdce8247adb /src/onapsdk
parent21e9eda103d2cb5228f20a1518d10ba55e610983 (diff)
Update K8sPlugin API
- add new methods for Instance API - added option to use K8sPlugin without MSB Issue-ID: TEST-391 Signed-off-by: Lukasz Rajewski <lukasz.rajewski@t-mobile.pl> Signed-off-by: Michal Jagiello <michal.jagiello@t-mobile.pl> Change-Id: I35b6c8ba9574ca2385c97edde5dbb036b30aebc9
Diffstat (limited to 'src/onapsdk')
-rw-r--r--src/onapsdk/configuration/global_settings.py1
-rw-r--r--src/onapsdk/k8s/__init__.py20
-rw-r--r--src/onapsdk/k8s/connectivity_info.py103
-rw-r--r--src/onapsdk/k8s/definition.py507
-rw-r--r--src/onapsdk/k8s/instance.py621
-rw-r--r--src/onapsdk/k8s/k8splugin_service.py160
-rw-r--r--src/onapsdk/k8s/region.py111
-rw-r--r--src/onapsdk/k8s/templates/msb_esr_vim_registration.json.j2 (renamed from src/onapsdk/msb/templates/msb_esr_vim_registration.json.j2)0
-rw-r--r--src/onapsdk/k8s/templates/multicloud_k8s_add_connectivity_info.json.j2 (renamed from src/onapsdk/msb/templates/multicloud_k8s_add_connectivity_info.json.j2)0
-rw-r--r--src/onapsdk/k8s/templates/multicloud_k8s_add_definition.json.j2 (renamed from src/onapsdk/msb/templates/multicloud_k8s_add_definition.json.j2)0
-rw-r--r--src/onapsdk/k8s/templates/multicloud_k8s_create_configuration_for_instance.json.j26
-rw-r--r--src/onapsdk/k8s/templates/multicloud_k8s_create_configuration_template.json.j2 (renamed from src/onapsdk/msb/templates/multicloud_k8s_create_configuration_template.json.j2)0
-rw-r--r--src/onapsdk/k8s/templates/multicloud_k8s_create_profile_for_definition.json.j2 (renamed from src/onapsdk/msb/templates/multicloud_k8s_create_profile_for_definition.json.j2)4
-rw-r--r--src/onapsdk/k8s/templates/multicloud_k8s_instantiate.json.j2 (renamed from src/onapsdk/msb/templates/multicloud_k8s_instantiate.json.j2)0
-rw-r--r--src/onapsdk/msb/k8s/__init__.py5
-rw-r--r--src/onapsdk/msb/k8s/connectivity_info.py94
-rw-r--r--src/onapsdk/msb/k8s/definition.py413
-rw-r--r--src/onapsdk/msb/k8s/instance.py183
-rw-r--r--src/onapsdk/msb/k8s/k8splugin_msb_service.py20
-rw-r--r--src/onapsdk/utils/headers_creator.py3
-rw-r--r--src/onapsdk/utils/jinja.py2
21 files changed, 1575 insertions, 678 deletions
diff --git a/src/onapsdk/configuration/global_settings.py b/src/onapsdk/configuration/global_settings.py
index 7672abc..45dc249 100644
--- a/src/onapsdk/configuration/global_settings.py
+++ b/src/onapsdk/configuration/global_settings.py
@@ -31,6 +31,7 @@ CPS_URL = "http://portal.api.simpledemo.onap.org:8080"
CPS_AUTH = ("cpsuser", "cpsr0cks!")
CPS_VERSION = "v1"
MSB_URL = "https://msb.api.simpledemo.onap.org:30283"
+K8SPLUGIN_URL = "http://k8splugin.api.simpledemo.onap.org:30455"
SDC_BE_URL = "https://sdc.api.be.simpledemo.onap.org:30204"
SDC_FE_URL = "https://sdc.api.fe.simpledemo.onap.org:30207"
SDC_AUTH = "Basic YWFpOktwOGJKNFNYc3pNMFdYbGhhazNlSGxjc2UyZ0F3ODR2YW9HR21KdlV5MlU="
diff --git a/src/onapsdk/k8s/__init__.py b/src/onapsdk/k8s/__init__.py
new file mode 100644
index 0000000..c450319
--- /dev/null
+++ b/src/onapsdk/k8s/__init__.py
@@ -0,0 +1,20 @@
+"""K8s package."""
+# Copyright 2023 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 .definition import Definition, Profile, ConfigurationTemplate
+from .connectivity_info import ConnectivityInfo
+from .instance import InstantiationParameter, InstantiationRequest, Instance
+from .instance import InstanceStatus, Configuration, ConfigurationTag
+from .k8splugin_service import K8sPlugin, GVK, ResourceStatus
+from .region import CloudRegionStatus, CloudRegion
diff --git a/src/onapsdk/k8s/connectivity_info.py b/src/onapsdk/k8s/connectivity_info.py
new file mode 100644
index 0000000..512c366
--- /dev/null
+++ b/src/onapsdk/k8s/connectivity_info.py
@@ -0,0 +1,103 @@
+"""Connectivity-Info 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 onapsdk.utils.jinja import jinja_env
+from .k8splugin_service import RemovableK8sPlugin
+
+
+class ConnectivityInfo(RemovableK8sPlugin):
+ """Connectivity-Info class."""
+
+ def __init__(self, cloud_region_id: str,
+ cloud_owner: str,
+ other_connectivity_list: dict,
+ kubeconfig: str) -> None:
+ """Connectivity-info object initialization.
+
+ Args:
+ cloud_region_id (str): Cloud region ID
+ cloud_owner (str): Cloud owner name
+ other_connectivity_list (dict): Optional other connectivity list
+ kubeconfig (str): kubernetes cluster kubeconfig
+ """
+ super().__init__()
+ self.cloud_region_id: str = cloud_region_id
+ self.cloud_owner: str = cloud_owner
+ self.other_connectivity_list: dict = other_connectivity_list
+ self.kubeconfig: str = kubeconfig
+
+ @property
+ def url(self) -> str:
+ """URL address for Definition Based calls.
+
+ Returns:
+ str: URL to RB Definition
+
+ """
+ return f"{self.base_url_and_version()}/connectivity-info/{self.cloud_region_id}"
+
+ @classmethod
+ def get_connectivity_info_by_region_id(cls, cloud_region_id: str) -> "ConnectivityInfo":
+ """Get connectivity-info by its name (cloud region id).
+
+ Args:
+ cloud_region_id (str): Cloud region ID
+
+ Returns:
+ ConnectivityInfo: Connectivity-Info object
+
+ """
+ url: str = f"{cls.base_url_and_version()}/connectivity-info/{cloud_region_id}"
+ connectivity_info: dict = cls.send_message_json(
+ "GET",
+ "Get Connectivity Info",
+ url
+ )
+ return cls(
+ connectivity_info["cloud-region"],
+ connectivity_info["cloud-owner"],
+ connectivity_info.get("other-connectivity-list"),
+ connectivity_info["kubeconfig"]
+ )
+
+ @classmethod
+ def create(cls,
+ cloud_region_id: str,
+ cloud_owner: str,
+ kubeconfig: bytes = None) -> "ConnectivityInfo":
+ """Create Connectivity Info.
+
+ Args:
+ cloud_region_id (str): Cloud region ID
+ cloud_owner (str): Cloud owner name
+ kubeconfig (bytes): kubernetes cluster kubeconfig file
+
+ Returns:
+ ConnectivityInfo: Created object
+
+ """
+ json_file = jinja_env().get_template("multicloud_k8s_add_connectivity_info.json.j2").render(
+ cloud_region_id=cloud_region_id,
+ cloud_owner=cloud_owner
+ )
+ url: str = f"{cls.base_url_and_version()}/connectivity-info"
+ cls.send_message(
+ "POST",
+ "Create Connectivity Info",
+ url,
+ files={"file": kubeconfig,
+ "metadata": (None, json_file)},
+ headers={}
+ )
+ return cls.get_connectivity_info_by_region_id(cloud_region_id)
diff --git a/src/onapsdk/k8s/definition.py b/src/onapsdk/k8s/definition.py
new file mode 100644
index 0000000..4d86afc
--- /dev/null
+++ b/src/onapsdk/k8s/definition.py
@@ -0,0 +1,507 @@
+"""Definition 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 Iterator
+from dataclasses import dataclass
+from onapsdk.utils.jinja import jinja_env
+from .k8splugin_service import GVK, RemovableK8sPlugin
+
+
+# pylint: disable=too-many-arguments, too-few-public-methods
+class DefinitionBase(RemovableK8sPlugin):
+ """DefinitionBase class."""
+
+ def __init__(self, rb_name: str,
+ rb_version: str) -> None:
+ """Definition-Base object initialization.
+
+ Args:
+ rb_name (str): Definition name
+ rb_version (str): Definition version
+ """
+ super().__init__()
+ self.rb_name: str = rb_name
+ self.rb_version: str = rb_version
+
+ @property
+ def url(self) -> str:
+ """URL address for Definition Based calls.
+
+ Returns:
+ str: URL to RB Definition
+
+ """
+ return f"{self.base_url_and_version()}/rb/definition/{self.rb_name}/{self.rb_version}"
+
+ def upload_artifact(self, package: bytes = None):
+ """Upload artifact.
+
+ Args:
+ package (bytes): Artifact to be uploaded to multicloud-k8s plugin
+
+ """
+ url: str = f"{self.url}/content"
+ self.send_message(
+ "POST",
+ "Upload Artifact content",
+ url,
+ data=package,
+ headers={}
+ )
+
+
+@dataclass
+class Profile(DefinitionBase):
+ """Profile class."""
+
+ def __init__(self, rb_name: str,
+ rb_version: str,
+ profile_name: str,
+ namespace: str,
+ kubernetes_version: str,
+ labels: dict = None,
+ release_name: str = None,
+ extra_resource_types: list = None) -> None:
+ """Profile object initialization.
+
+ Args:
+ rb_name (str): Definition name
+ rb_version (str): Definition version
+ profile_name (str): Name of profile
+ release_name (str): Release name, if release_name is not provided,
+ namespace (str): Namespace that service is created in
+ kubernetes_version (str): Required Kubernetes version
+ labels (dict): Extra Labels for k8s resources
+ extra_resource_types (list): Extra k8s resources types (GVK) for status monitoring
+ """
+ super().__init__(rb_name, rb_version)
+ self.profile_name: str = profile_name
+ if release_name is None:
+ release_name = profile_name
+ self.release_name: str = release_name
+ self.namespace: str = namespace
+ self.kubernetes_version: str = kubernetes_version
+ self.labels: dict = labels
+ if self.labels is None:
+ self.labels = dict()
+ self.extra_resource_types: dict = extra_resource_types
+ if self.extra_resource_types is None:
+ self.extra_resource_types = dict()
+
+ @property
+ def url(self) -> str:
+ """URL address for Profile calls.
+
+ Returns:
+ str: URL to RB Profile
+
+ """
+ return f"{self.base_url_and_version()}/rb/definition/{self.rb_name}/{self.rb_version}"\
+ f"/profile/{self.profile_name}"
+
+ def update(self) -> "Profile":
+ """Update Profile for Definition.
+
+ Returns:
+ Profile: Updated object
+
+ """
+ profile: dict = self.send_message_json(
+ "PUT",
+ "Update profile for definition",
+ self.url,
+ data=jinja_env().get_template("multicloud_k8s_create_profile_"
+ "for_definition.json.j2").render(
+ rb_name=self.rb_name,
+ rb_version=self.rb_version,
+ profile_name=self.profile_name,
+ release_name=self.release_name,
+ namespace=self.namespace,
+ kubernetes_version=self.kubernetes_version,
+ labels=self.labels,
+ extra_types=self.extra_resource_types
+ )
+ )
+ return self.__class__(
+ self.rb_name,
+ self.rb_version,
+ profile["profile-name"],
+ profile["namespace"],
+ profile.get("kubernetes-version"),
+ profile.get("labels"),
+ profile.get("release-name")
+ )
+
+
+@dataclass
+class ConfigurationTemplate(DefinitionBase):
+ """ConfigurationTemplate class."""
+
+ @property
+ def url(self) -> str:
+ """URL address for ConfigurationTemplate calls.
+
+ Returns:
+ str: URL to Configuration template in Multicloud-k8s API.
+
+ """
+ return f"{self.base_url_and_version()}/rb/definition/{self.rb_name}/{self.rb_version}"\
+ f"/config-template/{self.template_name}"
+
+ def __init__(self, rb_name: str,
+ rb_version: str,
+ template_name: str,
+ description: str,
+ chart_name="",
+ has_content=False) -> None:
+ """Configuration-Template object initialization.
+
+ Args:
+ rb_name (str): Definition name
+ rb_version (str): Definition version
+ template_name (str): Configuration template name
+ description (str): Namespace that service is created in
+ chart_name (str): Name of the charft of uploaded content
+ has_content (bool): If false cotent is taken fro mthe main definition
+ """
+ super().__init__(rb_name, rb_version)
+ self.template_name: str = template_name
+ self.description: str = description
+ self.chart_name: str = chart_name
+ self.has_content: bool = has_content
+
+ def update(self) -> "ConfigurationTemplate":
+ """Update Configuration Template for Definition.
+
+ Returns:
+ ConfigurationTemplate: Updated object
+
+ """
+ template: dict = self.send_message_json(
+ "PUT",
+ "Update config template for definition",
+ self.url,
+ data=jinja_env().get_template("multicloud_k8s_create_configuration_"
+ "template.json.j2").render(
+ template_name=self.template_name,
+ description=self.description
+ )
+ )
+ return self.__class__(
+ self.rb_name,
+ self.rb_version,
+ template["template-name"],
+ template.get("description"),
+ template.get("chart-name"),
+ template.get("has-content")
+ )
+
+
+@dataclass
+class Definition(DefinitionBase):
+ """Definition class."""
+
+ profile_class = Profile
+ config_template_class = ConfigurationTemplate
+
+ def __init__(self, rb_name: str,
+ rb_version: str,
+ chart_name: str,
+ description: str,
+ labels: dict) -> None:
+ """Definition object initialization.
+
+ Args:
+ rb_name (str): Definition name
+ rb_version (str): Definition version
+ chart_name (str): Chart name, optional field, will be detected if it is not provided
+ description (str): Definition description
+ labels (str): Labels
+ """
+ super().__init__(rb_name, rb_version)
+ self.chart_name: str = chart_name
+ self.description: str = description
+ self.labels: dict = labels
+
+ @classmethod
+ def get_all(cls):
+ """Get all definitions.
+
+ Yields:
+ Definition: Definition object
+
+ """
+ for definition in cls.send_message_json("GET",
+ "Get definitions",
+ f"{cls.base_url_and_version()}/rb/definition"):
+ yield cls(
+ definition["rb-name"],
+ definition["rb-version"],
+ definition.get("chart-name"),
+ definition.get("description"),
+ definition.get("labels")
+ )
+
+ @classmethod
+ def get_definition_by_name_version(cls, rb_name: str, rb_version: str) -> "Definition":
+ """Get definition by it's name and version.
+
+ Args:
+ rb_name (str): definition name
+ rb_version (str): definition version
+
+ Returns:
+ Definition: Definition object
+
+ """
+ url: str = f"{cls.base_url_and_version()}/rb/definition/{rb_name}/{rb_version}"
+ definition: dict = cls.send_message_json(
+ "GET",
+ "Get definition",
+ url
+ )
+ return cls(
+ definition["rb-name"],
+ definition["rb-version"],
+ definition.get("chart-name"),
+ definition.get("description"),
+ definition.get("labels")
+ )
+
+ @classmethod
+ def create(cls, rb_name: str,
+ rb_version: str,
+ chart_name: str = "",
+ description: str = "",
+ labels=None) -> "Definition":
+ """Create Definition.
+
+ Args:
+ rb_name (str): Definition name
+ rb_version (str): Definition version
+ chart_name (str): Chart name, optional field, will be detected if it is not provided
+ description (str): Definition description
+ labels (str): Labels
+
+ Returns:
+ Definition: Created object
+
+ """
+ if labels is None:
+ labels = {}
+ url: str = f"{cls.base_url_and_version()}/rb/definition"
+ cls.send_message(
+ "POST",
+ "Create definition",
+ url,
+ data=jinja_env().get_template("multicloud_k8s_add_definition.json.j2").render(
+ rb_name=rb_name,
+ rb_version=rb_version,
+ chart_name=chart_name,
+ description=description,
+ labels=labels
+ )
+ )
+ return cls.get_definition_by_name_version(rb_name, rb_version)
+
+ def update(self) -> "Definition":
+ """Update Definition.
+
+ Returns:
+ Definition: Updated object
+
+ """
+ self.send_message(
+ "PUT",
+ "Update definition",
+ self.url,
+ data=jinja_env().get_template("multicloud_k8s_add_definition.json.j2").render(
+ rb_name=self.rb_name,
+ rb_version=self.rb_version,
+ chart_name=self.chart_name,
+ description=self.description,
+ labels=self.labels
+ )
+ )
+ return self.get_definition_by_name_version(self.rb_name, self.rb_version)
+
+ def create_profile(self, profile_name: str,
+ namespace: str,
+ kubernetes_version: str,
+ release_name: str = None,
+ labels: dict = None,
+ extra_resource_types: list = None) -> "Profile":
+ """Create Profile for Definition.
+
+ Args:
+ profile_name (str): Name of profile
+ namespace (str): Namespace that service is created in
+ kubernetes_version (str): Required Kubernetes version
+ release_name (str): Release name
+ labels (dict): Extra labels to assign for each
+ extra_resource_types (list): GVK list for extra k8s resource types to check status
+
+ Returns:
+ Profile: Created object
+
+ """
+ url: str = f"{self.url}/profile"
+ if release_name is None:
+ release_name = profile_name
+ if labels is None:
+ labels = {}
+ if extra_resource_types is None:
+ extra_resource_types = []
+ self.send_message(
+ "POST",
+ "Create profile for definition",
+ url,
+ data=jinja_env().get_template("multicloud_k8s_create_profile_"
+ "for_definition.json.j2").render(
+ rb_name=self.rb_name,
+ rb_version=self.rb_version,
+ profile_name=profile_name,
+ release_name=release_name,
+ namespace=namespace,
+ kubernetes_version=kubernetes_version,
+ labels=labels,
+ extra_types=extra_resource_types
+ )
+ )
+ return self.get_profile_by_name(profile_name)
+
+ def get_all_profiles(self) -> Iterator["Profile"]:
+ """Get all profiles.
+
+ Yields:
+ Profile: Profile object
+
+ """
+ url: str = f"{self.url}/profile"
+
+ for profile in self.send_message_json("GET",
+ "Get profiles",
+ url):
+ yield self.profile_class(
+ profile["rb-name"],
+ profile["rb-version"],
+ profile["profile-name"],
+ profile["namespace"],
+ profile.get("kubernetes-version"),
+ profile.get("labels"),
+ profile.get("release-name"),
+ GVK.to_list_of_gvk(profile.get("extra-resource-types"))
+ )
+
+ def get_profile_by_name(self, profile_name: str) -> "Profile":
+ """Get profile by it's name.
+
+ Args:
+ profile_name (str): profile name
+
+ Returns:
+ Profile: Profile object
+
+ """
+ url: str = f"{self.url}/profile/{profile_name}"
+
+ profile: dict = self.send_message_json(
+ "GET",
+ "Get profile",
+ url
+ )
+ return self.profile_class(
+ profile["rb-name"],
+ profile["rb-version"],
+ profile["profile-name"],
+ profile["namespace"],
+ profile.get("kubernetes-version"),
+ profile.get("labels"),
+ profile.get("release-name"),
+ GVK.to_list_of_gvk(profile.get("extra-resource-types"))
+ )
+
+ def get_all_configuration_templates(self):
+ """Get all configuration templates.
+
+ Yields:
+ ConfigurationTemplate: ConfigurationTemplate object
+
+ """
+ url: str = f"{self.url}/config-template"
+
+ for template in self.send_message_json("GET",
+ "Get configuration templates",
+ url):
+ yield self.config_template_class(
+ self.rb_name,
+ self.rb_version,
+ template["template-name"],
+ template.get("description"),
+ template.get("chart-name"),
+ template.get("has-content")
+ )
+
+ def create_configuration_template(self, template_name: str,
+ description="") -> "ConfigurationTemplate":
+ """Create configuration template.
+
+ Args:
+ template_name (str): Name of the template
+ description (str): Description
+
+ Returns:
+ ConfigurationTemplate: Created object
+
+ """
+ url: str = f"{self.url}/config-template"
+
+ self.send_message(
+ "POST",
+ "Create configuration template",
+ url,
+ data=jinja_env().get_template("multicloud_k8s_create_configuration_"
+ "template.json.j2").render(
+ template_name=template_name,
+ description=description
+ )
+ )
+
+ return self.get_configuration_template_by_name(template_name)
+
+ def get_configuration_template_by_name(self, template_name: str) -> "ConfigurationTemplate":
+ """Get configuration template.
+
+ Args:
+ template_name (str): Name of the template
+
+ Returns:
+ ConfigurationTemplate: object
+
+ """
+ url: str = f"{self.url}/config-template/{template_name}"
+
+ template: dict = self.send_message_json(
+ "GET",
+ "Get Configuration template",
+ url
+ )
+ return self.config_template_class(
+ self.rb_name,
+ self.rb_version,
+ template["template-name"],
+ template.get("description"),
+ template.get("chart-name"),
+ template.get("has-content")
+ )
diff --git a/src/onapsdk/k8s/instance.py b/src/onapsdk/k8s/instance.py
new file mode 100644
index 0000000..4b93258
--- /dev/null
+++ b/src/onapsdk/k8s/instance.py
@@ -0,0 +1,621 @@
+"""Instantiation 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 typing import Any, Dict, Iterator
+from dataclasses import dataclass
+
+from onapsdk.utils.jinja import jinja_env
+from .k8splugin_service import QueryResourceStatusMixin, ResourceStatus, RemovableK8sPlugin
+
+
+# pylint: disable=too-many-arguments
+@dataclass
+class InstantiationRequest:
+ """Instantiation Request class."""
+
+ def __init__(self, request: dict) -> None:
+ """Request object initialization.
+
+ Args:
+ cloud_region_id (str): Cloud region ID
+ profile_name (str): Name of profile
+ rb_name (str): Definition name
+ rb_version (str): Definition version
+ override_values (dict): Optional parameters
+ labels (dict): Optional labels
+ """
+ super().__init__()
+ self.cloud_region_id: str = request["cloud-region"]
+ self.profile_name: str = request["profile-name"]
+ self.rb_name: str = request["rb-name"]
+ self.rb_version: str = request["rb-version"]
+ self.override_values: dict = request["override-values"]
+ self.labels: dict = request["labels"]
+
+
+@dataclass
+class InstantiationParameter:
+ """Class to store instantiation parameters used to pass override_values and labels.
+
+ Contains two values: name of parameter and it's value
+ """
+
+ name: str
+ value: str
+
+
+class InstanceBase(RemovableK8sPlugin):
+ """InstanceBase class."""
+
+ def __init__(self, instance_id: str) -> None:
+ """Instance-Base object initialization.
+
+ Args:
+ instance_id (str): instance ID
+ """
+ super().__init__()
+ self.instance_id: str = instance_id
+
+ @property
+ def url(self) -> str:
+ """URL address.
+
+ Returns:
+ str: URL to Instance
+
+ """
+ return f"{self.base_url_and_version()}/instance/{self.instance_id}"
+
+
+@dataclass
+class ConfigurationTag:
+ """Class to store configuration tag information.
+
+ Contains two values: name of tag and version of associated configuration
+ """
+
+ config_tag: str
+ config_version: str
+
+
+class Configuration(InstanceBase):
+ """Configuration class."""
+
+ def __init__(self, instance_id: str,
+ config_name: str,
+ template_name: str,
+ description: str,
+ config_version: str,
+ config_tag: str,
+ values: dict = None) -> None:
+ """Initialize Configuration object.
+
+ Args:
+ instance_id (str): instance ID
+ config_name (str): Name of the configuration
+ template_name (str): Name of the template
+ description (str): Description
+ config_version (str): Config version
+ config_tag (str): Config tag
+ values (dict): Overrides values used to create configuration
+ """
+ super().__init__(instance_id)
+ self.name = config_name
+ self.template_name = template_name
+ self.config_version = str(config_version)
+ self.config_tag = config_tag
+ self.description = description
+ self.values = values
+
+ @property
+ def url(self) -> str:
+ """URL address for Configuration calls.
+
+ Returns:
+ str: URL to Configuration
+
+ """
+ return f"{self.base_url_and_version()}/instance/{self.instance_id}/config/{self.name}"
+
+ def rollback_to(self, config_version: str, config_tag: str) -> None:
+ """Rollback configuration to specific version.
+
+ Args:
+ config_version (str): version of configuration
+ config_tag (str): tag of configuration
+
+ """
+ url: str = f"{self.url}/rollback"
+
+ params = dict()
+ if config_version is not None:
+ params["config-version"] = config_version
+ if config_tag is not None:
+ params["config-tag"] = config_tag
+ self.send_message_json(
+ "POST",
+ "Rollback Configuration",
+ url,
+ data=json.dumps(params),
+ headers={}
+ )
+ self.config_version = config_version
+ self.config_tag = config_tag
+
+ def update(self, override_values: dict) -> "Configuration":
+ """Update configuration.
+
+ Args:
+ override_values (dict): Override values
+
+ Returns:
+ Configuration: Updated object
+
+ """
+ body = json.dumps(override_values)
+
+ config: dict = self.send_message_json(
+ "PUT",
+ "Update configuration",
+ self.url,
+ data=jinja_env().get_template("multicloud_k8s_create_configuration_for_"
+ "instance.json.j2").render(
+ config_name=self.name,
+ template_name=self.template_name,
+ description=self.description,
+ override_values=body
+ )
+ )
+ return self.get_config_by_version(str(config["config-version"]))
+
+ def tag_config_version(self, config_tag: str) -> None:
+ """Tag configuration.
+
+ Args:
+ config_tag (str): Tag name of the configuration version
+
+ """
+ body = json.dumps({"tag-name": config_tag})
+
+ self.send_message(
+ "POST",
+ "Tag configuration",
+ f"{self.url}/tagit",
+ data=body
+ )
+
+ def get_config_by_version(self, config_version: str) -> "Configuration":
+ """Get configuration by version.
+
+ Args:
+ config_version (str): Config version
+
+ Returns:
+ Configuration: object
+
+ """
+ config: dict = self.send_message_json(
+ "GET",
+ "Get Configuration",
+ f"{self.url}/version/{config_version}"
+ )
+ return self.__class__(
+ self.instance_id,
+ self.name,
+ config["template-name"],
+ config["description"],
+ config["config-version"],
+ config["config-tag"],
+ config["values"]
+ )
+
+ def get_config_versions(self) -> Iterator["Configuration"]:
+ """Get List of configuration versions.
+
+ Returns:
+ List of versions for configuration
+
+ """
+ for config in self.send_message_json("GET",
+ "Get config versions",
+ f"{self.url}/version"):
+ yield self.__class__(
+ self.instance_id,
+ self.name,
+ config["template-name"],
+ config["description"],
+ config["config-version"],
+ config["config-tag"],
+ config["values"]
+ )
+
+ def get_config_by_tag(self, config_tag: str) -> "Configuration":
+ """Get configuration by tag.
+
+ Args:
+ config_tag (str): Name of tag
+
+ Returns:
+ Configuration: object
+
+ """
+ config: dict = self.send_message_json(
+ "GET",
+ "Get Configuration",
+ f"{self.url}/tag/{config_tag}"
+ )
+ return self.__class__(
+ self.instance_id,
+ self.name,
+ config["template-name"],
+ config["description"],
+ config["config-version"],
+ config["config-tag"],
+ config["values"]
+ )
+
+ def get_config_tags(self) -> Iterator["ConfigurationTag"]:
+ """Get List of Tags.
+
+ Returns:
+ List of tags for configuration
+
+ """
+ for tag in self.send_message_json("GET",
+ "Get config tags",
+ f"{self.url}/tag"):
+ yield ConfigurationTag(
+ config_tag=tag["config-tag"],
+ config_version=str(tag["config-version"])
+ )
+
+ def create_delete_version(self) -> "Configuration":
+ """Create delete version of configuration."""
+ url: str = f"{self.url}/delete"
+
+ config: dict = self.send_message_json(
+ "POST",
+ "Delete Resources Configuration",
+ url
+ )
+ return self.__class__(
+ self.instance_id,
+ self.name,
+ config["template-name"],
+ config["description"],
+ config["config-version"],
+ config["config-tag"],
+ config["values"]
+ )
+
+ def delete_without_resources(self) -> None:
+ """Delete Instance Based object."""
+ self.send_message(
+ "DELETE",
+ f"Delete {self.__class__.__name__}",
+ f"{self.url}?deleteConfigOnly=true"
+ )
+
+
+@dataclass
+class InstanceStatus:
+ """Class to store status of the Instance."""
+
+ instance_id: str
+ request: InstantiationRequest
+ resource_count: str
+ ready: bool
+ resources_status: list
+
+
+class Instance(InstanceBase, QueryResourceStatusMixin):
+ """Instance class."""
+
+ config_class = Configuration
+ request_class = InstantiationRequest
+
+ def __init__(self, instance_id: str,
+ namespace: str,
+ request: InstantiationRequest,
+ resources: dict = None,
+ override_values: dict = None) -> None:
+ """Instance object initialization.
+
+ Args:
+ instance_id (str): instance ID
+ namespace (str): namespace that instance is created in
+ request (InstantiationRequest): datails of the instantiation request
+ resources (dict): Created resources
+ override_values (dict): Optional values
+ """
+ super().__init__(instance_id)
+ self.namespace: str = namespace
+ self.request: InstantiationRequest = request
+ self.resources: dict = resources
+ self.override_values: dict = override_values
+
+ @classmethod
+ def get_all(cls) -> Iterator["Instance"]:
+ """Get all instantiated Kubernetes resources.
+
+ Yields:
+ Instantiation: Instantiation object
+
+ """
+ for resource in cls.send_message_json("GET",
+ "Get Kubernetes resources",
+ f"{cls.base_url_and_version()}/instance"):
+ yield cls(
+ instance_id=resource["id"],
+ namespace=resource["namespace"],
+ request=cls.request_class(resource["request"])
+ )
+
+ @classmethod
+ def get_by_id(cls, instance_id: str) -> "Instance":
+ """Get Kubernetes resource by id.
+
+ Args:
+ instance_id (str): instance ID
+
+ Returns:
+ Instantiation: Instantiation object
+
+ """
+ url: str = f"{cls.base_url_and_version()}/instance/{instance_id}"
+ resource: dict = cls.send_message_json(
+ "GET",
+ "Get Kubernetes resource by id",
+ url
+ )
+ return cls(
+ instance_id=resource["id"],
+ namespace=resource["namespace"],
+ request=cls.request_class(resource["request"]),
+ resources=resource["resources"],
+ override_values=resource.get("override-values")
+ )
+
+ @classmethod
+ def create(cls,
+ cloud_region_id: str,
+ profile_name: str,
+ rb_name: str,
+ rb_version: str,
+ override_values: dict = None,
+ labels: dict = None) -> "Instance":
+ """Create Instance.
+
+ Args:
+ cloud_region_id (str): Cloud region ID
+ profile_name (str): Name of profile to be instantiated
+ rb_name: (bytes): Definition name
+ rb_version (str): Definition version
+ override_values (dict): List of optional override values
+ labels (dict): List of optional labels
+
+ Returns:
+ Instance: Created object
+
+ """
+ if labels is None:
+ labels = {}
+ if override_values is None:
+ override_values = {}
+ url: str = f"{cls.base_url_and_version()}/instance"
+ response: dict = cls.send_message_json(
+ "POST",
+ "Create Instance",
+ url,
+ data=jinja_env().get_template("multicloud_k8s_instantiate.json.j2").render(
+ cloud_region_id=cloud_region_id,
+ profile_name=profile_name,
+ rb_name=rb_name,
+ rb_version=rb_version,
+ override_values=override_values,
+ labels=labels),
+ headers={}
+ )
+ return cls(
+ instance_id=response["id"],
+ namespace=response["namespace"],
+ request=cls.request_class(response["request"]),
+ resources=response["resources"],
+ override_values=response.get("override-values")
+ )
+
+ def upgrade(self,
+ cloud_region_id: str,
+ profile_name: str,
+ rb_name: str,
+ rb_version: str,
+ override_values: dict = None,
+ labels: dict = None) -> "Instance":
+ """Upgrade Instance.
+
+ Args:
+ cloud_region_id (str): Cloud region ID
+ profile_name (str): Name of profile to be instantiated
+ rb_name: (bytes): Definition name
+ rb_version (str): Definition version
+ override_values (dict): List of optional override values
+ labels (dict): List of optional labels
+
+ Returns:
+ Instance: Created object
+
+ """
+ if labels is None:
+ labels = {}
+ if override_values is None:
+ override_values = {}
+ url: str = f"{self.url}/upgrade"
+ response: dict = self.send_message_json(
+ "POST",
+ "Upgrade Instance",
+ url,
+ data=jinja_env().get_template("multicloud_k8s_instantiate.json.j2").render(
+ cloud_region_id=cloud_region_id,
+ profile_name=profile_name,
+ rb_name=rb_name,
+ rb_version=rb_version,
+ override_values=override_values,
+ labels=labels),
+ headers={}
+ )
+ return self.__class__(
+ instance_id=response["id"],
+ namespace=response["namespace"],
+ request=self.request_class(response["request"]),
+ resources=response["resources"],
+ override_values=response.get("override-values")
+ )
+
+ def create_configuration(self, config_name: str,
+ template_name: str,
+ override_values: dict = None,
+ description="") -> "Configuration":
+ """Create configuration instance.
+
+ Args:
+ config_name (str): Name of the configuration
+ template_name (str): Name of the template
+ description (str): Description
+ override_values (dict): Override values
+
+ Returns:
+ Configuration: Created object
+
+ """
+ url: str = f"{self.url}/config"
+
+ body = json.dumps(override_values)
+
+ self.send_message(
+ "POST",
+ "Create configuration",
+ url,
+ data=jinja_env().get_template("multicloud_k8s_create_configuration_for_"
+ "instance.json.j2").render(
+ config_name=config_name,
+ template_name=template_name,
+ description=description,
+ override_values=body
+ )
+ )
+
+ return self.get_configuration_by_name(config_name)
+
+ def get_all_configurations(self) -> Iterator["Configuration"]:
+ """Get List of configurations.
+
+ Returns:
+ List of configurations
+
+ """
+ for config in self.send_message_json("GET",
+ "Get configurations",
+ f"{self.url}/config"):
+ yield self.config_class(
+ self.instance_id,
+ config["config-name"],
+ config["template-name"],
+ config["description"],
+ config["config-version"],
+ config["config-tag"],
+ config["values"]
+ )
+
+ def get_configuration_by_name(self, config_name: str) -> "Configuration":
+ """Get configuration.
+
+ Args:
+ config_name (str): Name of the configuration
+
+ Returns:
+ Configuration: object
+
+ """
+ url: str = f"{self.url}/config/{config_name}"
+
+ config: dict = self.send_message_json(
+ "GET",
+ "Get Configuration",
+ url
+ )
+ return self.config_class(
+ self.instance_id,
+ config_name,
+ config["template-name"],
+ config["description"],
+ config["config-version"],
+ config["config-tag"],
+ config["values"]
+ )
+
+ def get_status(self) -> "InstanceStatus":
+ """Get instance status.
+
+ Returns:
+ Status of the instance
+
+ """
+ status: dict = self.send_message_json(
+ "GET",
+ "Get status",
+ f"{self.url}/status"
+ )
+ resources_status = []
+ for res_status in status["resourcesStatus"]:
+ resources_status.append(ResourceStatus(res_status))
+ return InstanceStatus(
+ self.instance_id,
+ request=self.request_class(status["request"]),
+ resource_count=int(status["resourceCount"]),
+ ready=bool(status["ready"]),
+ resources_status=resources_status
+ )
+
+ def query_status(self,
+ kind: str,
+ api_version: str,
+ name: str = None,
+ labels: dict = None) -> "InstanceStatus":
+ """Query instance status.
+
+ Args:
+ kind (str): Kind of k8s resource
+ api_version (str): Api version of k8s resource
+ name (str): Name of k8s resource
+ labels (dict): Lables of k8s resource
+
+ Returns:
+ Filtered status of the instance
+
+ """
+ url = f"{self.url}/query"
+ status: Dict[Any] = self.query_resource_status(url,
+ api_version=api_version,
+ kind=kind,
+ name=name,
+ labels=labels)
+ return InstanceStatus(
+ self.instance_id,
+ request=self.request_class(status["request"]),
+ resource_count=int(status["resourceCount"]),
+ ready=bool(status["ready"]),
+ resources_status=[ResourceStatus(res_status) for
+ res_status in status["resourcesStatus"]]
+ )
diff --git a/src/onapsdk/k8s/k8splugin_service.py b/src/onapsdk/k8s/k8splugin_service.py
new file mode 100644
index 0000000..fd11ebb
--- /dev/null
+++ b/src/onapsdk/k8s/k8splugin_service.py
@@ -0,0 +1,160 @@
+"""K8s package."""
+# Copyright 2023 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 abc import ABC
+from dataclasses import dataclass
+from typing import Any, Dict
+from urllib.parse import urlsplit, parse_qs, urlencode, SplitResult
+
+from onapsdk.configuration import settings
+from onapsdk.onap_service import OnapService
+
+
+@dataclass
+class GVK:
+ """Class to store GVK info of k8s resource.
+
+ Contains group, version, and kind information
+ """
+
+ def __init__(self, gvk: dict) -> None:
+ """Gvk object initialization.
+
+ Args:
+ Group (str): Group of resource
+ Version (str): Version of resource
+ Kind (str): Kind name
+ """
+ super().__init__()
+ self.group: str = gvk["Group"]
+ self.version: str = gvk["Version"]
+ self.kind: str = gvk["Kind"]
+
+ @classmethod
+ def to_list_of_gvk(cls, gvk_list: list) -> list:
+ """Convert list of dicts to list of GVK.
+
+ Args:
+ gvk_list (list): list of gvk dicts
+
+ Returns:
+ Converted list
+
+ """
+ final_list = []
+ if gvk_list is not None:
+ for gvk in gvk_list:
+ final_list.append(cls(gvk))
+ return final_list
+
+
+@dataclass
+class ResourceStatus:
+ """Class to store status of singular k8s resource."""
+
+ def __init__(self, status: dict) -> None:
+ """Status object initialization.
+
+ Args:
+ GVK (str): GVK of resource
+ name (str): name of resource
+ status (str): full status of resource
+ """
+ super().__init__()
+ self.name: str = status["name"]
+ self.gvk: GVK = GVK(status["GVK"])
+ self.status: dict = status["status"]
+
+
+class QueryResourceStatusMixin(ABC): # pylint: disable=too-few-public-methods
+ """Query resource status mixin class."""
+
+ def query_resource_status(self, # pylint: disable=too-many-arguments
+ query_url: str,
+ api_version: str,
+ kind: str,
+ namespace: str = None,
+ name: str = None,
+ labels: dict = None,
+ cloud_region: str = None) -> Dict[str, Any]:
+ """Call a query request.
+
+ Args:
+ query_url (str): A query base url
+ kind (str): Kind of k8s resource
+ api_version (str): Api version of k8s resource
+ namespace (str): Namespace of k8s resource
+ name (str): Name of k8s resource
+ labels (dict): Lables of k8s resource
+ cloud_region (str): Cloud region ID
+
+ Returns:
+ Query request response dictionary
+
+ """
+ splitted_url: SplitResult = urlsplit(query_url)
+ query: Dict[str, str] = parse_qs(splitted_url.query)
+ query["ApiVersion"] = api_version
+ query["Kind"] = kind
+ if cloud_region is not None:
+ query["CloudRegion"] = cloud_region
+ if name is not None:
+ query["Name"] = name
+ if namespace is not None:
+ query["Namespace"] = namespace
+ if labels is not None and len(labels) > 0:
+ query["Labels"] = ",".join([f"{key}={value}" for key, value in labels.items()])
+ return self.send_message_json(
+ "GET",
+ "Query region status",
+ splitted_url._replace(query=urlencode(query)).geturl()
+ )
+
+
+class K8sPlugin(OnapService):
+ """K8sPlugin base class."""
+
+ base_url = settings.K8SPLUGIN_URL
+ api_version = "/v1"
+ headers = OnapService.headers
+
+ @classmethod
+ def base_url_and_version(cls):
+ """Return base url with api version.
+
+ Returns base url with api version
+ """
+ return f"{K8sPlugin.base_url}{K8sPlugin.api_version}"
+
+
+class RemovableK8sPlugin(K8sPlugin):
+ """K8S plugin resource which could be removed."""
+
+ @property
+ def url(self) -> str:
+ """Object url.
+
+ Returns:
+ str: Object's url
+
+ """
+ raise NotImplementedError
+
+ def delete(self) -> None:
+ """Delete k8s plugin object."""
+ self.send_message(
+ "DELETE",
+ f"Delete {self.__class__.__name__}",
+ self.url
+ )
diff --git a/src/onapsdk/k8s/region.py b/src/onapsdk/k8s/region.py
new file mode 100644
index 0000000..a5cf197
--- /dev/null
+++ b/src/onapsdk/k8s/region.py
@@ -0,0 +1,111 @@
+"""Query module."""
+# Copyright 2023 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 dataclasses import dataclass
+from typing import Any, Dict
+
+from .k8splugin_service import K8sPlugin, QueryResourceStatusMixin, ResourceStatus
+from .connectivity_info import ConnectivityInfo
+
+
+@dataclass
+class CloudRegionStatus:
+ """Class to store status of the Region."""
+
+ resource_count: str
+ resources_status: list
+
+
+# pylint: disable=too-many-arguments
+@dataclass
+class CloudRegion(K8sPlugin, QueryResourceStatusMixin):
+ """Cloud region information."""
+
+ def __init__(self,
+ cloud_region_id: str,
+ info: ConnectivityInfo) -> None:
+ """Region object initialization.
+
+ Args:
+ cloud_region_id (str): Cloud region ID
+ info (ConnectivityInfo): Connectivity Info
+
+ """
+ super().__init__()
+ self.cloud_region_id = cloud_region_id
+ self.connectivity_info = info
+
+ @classmethod
+ def create(cls,
+ cloud_region_id: str,
+ cloud_owner: str = None,
+ kubeconfig: bytes = None) -> "CloudRegion":
+ """Create Cloud Region.
+
+ Args:
+ cloud_region_id (str): Cloud region ID
+ cloud_owner (str): Cloud owner name
+ kubeconfig (str): kubernetes cluster kubeconfig
+
+ Returns:
+ CloudRegion: Created region object
+
+ """
+ if cloud_owner is None:
+ cloud_owner = cloud_region_id
+ info = ConnectivityInfo.create(cloud_region_id, cloud_owner, kubeconfig)
+ return CloudRegion(cloud_region_id, info)
+
+ def delete(self) -> None:
+ """Delete Region and associated Connectivity Information."""
+ self.connectivity_info.delete()
+
+ @classmethod
+ def get_by_region_id(cls, cloud_region_id: str) -> "CloudRegion":
+ """Get Region Information."""
+ info = ConnectivityInfo.get_connectivity_info_by_region_id(cloud_region_id)
+ return CloudRegion(cloud_region_id, info)
+
+ def query_resources(self,
+ kind: str,
+ api_version: str,
+ namespace: str = None,
+ name: str = None,
+ labels: dict = None) -> "CloudRegionStatus":
+ """Query for resources in the cloud region.
+
+ Args:
+ kind (str): Kind of k8s resource
+ api_version (str): Api version of k8s resource
+ namespace (str): Namespace of k8s resource
+ name (str): Name of k8s resource
+ labels (dict): Lables of k8s resource
+
+ Returns:
+ Filtered status of the cloud region
+
+ """
+ url = f"{self.base_url_and_version()}/query"
+ status: Dict[Any] = self.query_resource_status(url,
+ cloud_region=self.cloud_region_id,
+ api_version=api_version,
+ kind=kind,
+ namespace=namespace,
+ name=name,
+ labels=labels)
+ return CloudRegionStatus(
+ resource_count=int(status["resourceCount"]),
+ resources_status=[ResourceStatus(res_status) for
+ res_status in status["resourcesStatus"]]
+ )
diff --git a/src/onapsdk/msb/templates/msb_esr_vim_registration.json.j2 b/src/onapsdk/k8s/templates/msb_esr_vim_registration.json.j2
index ba19258..ba19258 100644
--- a/src/onapsdk/msb/templates/msb_esr_vim_registration.json.j2
+++ b/src/onapsdk/k8s/templates/msb_esr_vim_registration.json.j2
diff --git a/src/onapsdk/msb/templates/multicloud_k8s_add_connectivity_info.json.j2 b/src/onapsdk/k8s/templates/multicloud_k8s_add_connectivity_info.json.j2
index 4a3dc2d..4a3dc2d 100644
--- a/src/onapsdk/msb/templates/multicloud_k8s_add_connectivity_info.json.j2
+++ b/src/onapsdk/k8s/templates/multicloud_k8s_add_connectivity_info.json.j2
diff --git a/src/onapsdk/msb/templates/multicloud_k8s_add_definition.json.j2 b/src/onapsdk/k8s/templates/multicloud_k8s_add_definition.json.j2
index 866d577..866d577 100644
--- a/src/onapsdk/msb/templates/multicloud_k8s_add_definition.json.j2
+++ b/src/onapsdk/k8s/templates/multicloud_k8s_add_definition.json.j2
diff --git a/src/onapsdk/k8s/templates/multicloud_k8s_create_configuration_for_instance.json.j2 b/src/onapsdk/k8s/templates/multicloud_k8s_create_configuration_for_instance.json.j2
new file mode 100644
index 0000000..f20c452
--- /dev/null
+++ b/src/onapsdk/k8s/templates/multicloud_k8s_create_configuration_for_instance.json.j2
@@ -0,0 +1,6 @@
+{
+ "template-name": "{{ template_name }}",
+ "description": "{{ description }}",
+ "config-name": "{{ config_name }}",
+ "values": {{ override_values }}
+} \ No newline at end of file
diff --git a/src/onapsdk/msb/templates/multicloud_k8s_create_configuration_template.json.j2 b/src/onapsdk/k8s/templates/multicloud_k8s_create_configuration_template.json.j2
index 61e6d2b..61e6d2b 100644
--- a/src/onapsdk/msb/templates/multicloud_k8s_create_configuration_template.json.j2
+++ b/src/onapsdk/k8s/templates/multicloud_k8s_create_configuration_template.json.j2
diff --git a/src/onapsdk/msb/templates/multicloud_k8s_create_profile_for_definition.json.j2 b/src/onapsdk/k8s/templates/multicloud_k8s_create_profile_for_definition.json.j2
index 5ea2de1..e7459b7 100644
--- a/src/onapsdk/msb/templates/multicloud_k8s_create_profile_for_definition.json.j2
+++ b/src/onapsdk/k8s/templates/multicloud_k8s_create_profile_for_definition.json.j2
@@ -4,5 +4,7 @@
"profile-name": "{{ profile_name }}",
"release-name": "{{ release_name }}",
"namespace": "{{ namespace }}",
- "kubernetes-version": "{{ kubernetes_version }}"
+ "kubernetes-version": "{{ kubernetes_version }}",
+ "labels": {{ labels }},
+ "extra-resource-types": {{ extra_types }}
} \ No newline at end of file
diff --git a/src/onapsdk/msb/templates/multicloud_k8s_instantiate.json.j2 b/src/onapsdk/k8s/templates/multicloud_k8s_instantiate.json.j2
index fa5ef66..fa5ef66 100644
--- a/src/onapsdk/msb/templates/multicloud_k8s_instantiate.json.j2
+++ b/src/onapsdk/k8s/templates/multicloud_k8s_instantiate.json.j2
diff --git a/src/onapsdk/msb/k8s/__init__.py b/src/onapsdk/msb/k8s/__init__.py
index 655502d..91f4206 100644
--- a/src/onapsdk/msb/k8s/__init__.py
+++ b/src/onapsdk/msb/k8s/__init__.py
@@ -1,4 +1,4 @@
-"""K8s package."""
+"""K8s MSB package."""
# Copyright 2022 Orange, Deutsche Telekom AG
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,4 +14,5 @@
# limitations under the License.
from .definition import Definition, Profile, ConfigurationTemplate
from .connectivity_info import ConnectivityInfo
-from .instance import InstantiationParameter, InstantiationRequest, Instance
+from .instance import InstantiationParameter, InstantiationRequest, Instance, Configuration
+from .k8splugin_msb_service import K8sPlugin
diff --git a/src/onapsdk/msb/k8s/connectivity_info.py b/src/onapsdk/msb/k8s/connectivity_info.py
index 71a43c1..5faf8db 100644
--- a/src/onapsdk/msb/k8s/connectivity_info.py
+++ b/src/onapsdk/msb/k8s/connectivity_info.py
@@ -12,94 +12,8 @@
# 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 onapsdk.utils.jinja import jinja_env
-from ..msb_service import MSB
+import warnings
+from onapsdk.k8s.connectivity_info import ConnectivityInfo # pylint: disable=unused-import
-
-class ConnectivityInfo(MSB):
- """Connectivity-Info class."""
-
- api_version = "/api/multicloud-k8s/v1/v1"
- url = f"{MSB.base_url}{api_version}/connectivity-info"
-
- def __init__(self, cloud_region_id: str,
- cloud_owner: str,
- other_connectivity_list: dict,
- kubeconfig: str) -> None:
- """Connectivity-info object initialization.
-
- Args:
- cloud_region_id (str): Cloud region ID
- cloud_owner (str): Cloud owner name
- other_connectivity_list (dict): Optional other connectivity list
- kubeconfig (str): kubernetes cluster kubeconfig
- """
- super().__init__()
- self.cloud_region_id: str = cloud_region_id
- self.cloud_owner: str = cloud_owner
- self.other_connectivity_list: dict = other_connectivity_list
- self.kubeconfig: str = kubeconfig
-
- @classmethod
- def get_connectivity_info_by_region_id(cls, cloud_region_id: str) -> "ConnectivityInfo":
- """Get connectivity-info by its name (cloud region id).
-
- Args:
- cloud_region_id (str): Cloud region ID
-
- Returns:
- ConnectivityInfo: Connectivity-Info object
-
- """
- url: str = f"{cls.url}/{cloud_region_id}"
- connectivity_info: dict = cls.send_message_json(
- "GET",
- "Get Connectivity Info",
- url
- )
- return cls(
- connectivity_info["cloud-region"],
- connectivity_info["cloud-owner"],
- connectivity_info.get("other-connectivity-list"),
- connectivity_info["kubeconfig"]
- )
-
- def delete(self) -> None:
- """Delete connectivity info."""
- url: str = f"{self.url}/{self.cloud_region_id}"
- self.send_message(
- "DELETE",
- "Delete Connectivity Info",
- url
- )
-
- @classmethod
- def create(cls,
- cloud_region_id: str,
- cloud_owner: str,
- kubeconfig: bytes = None) -> "ConnectivityInfo":
- """Create Connectivity Info.
-
- Args:
- cloud_region_id (str): Cloud region ID
- cloud_owner (str): Cloud owner name
- kubeconfig (bytes): kubernetes cluster kubeconfig file
-
- Returns:
- ConnectivityInfo: Created object
-
- """
- json_file = jinja_env().get_template("multicloud_k8s_add_connectivity_info.json.j2").render(
- cloud_region_id=cloud_region_id,
- cloud_owner=cloud_owner
- )
- url: str = f"{cls.url}"
- cls.send_message(
- "POST",
- "Create Connectivity Info",
- url,
- files={"file": kubeconfig,
- "metadata": (None, json_file)},
- headers={}
- )
- return cls.get_connectivity_info_by_region_id(cloud_region_id)
+warnings.warn("onapsdk.msb.k8s.connectivity_info module is deprecated and will be removed with "
+ "the next version of ONAP SDK. Use onapsdk.k8s.connectivity_info")
diff --git a/src/onapsdk/msb/k8s/definition.py b/src/onapsdk/msb/k8s/definition.py
index 6c0def2..a8c5d6d 100644
--- a/src/onapsdk/msb/k8s/definition.py
+++ b/src/onapsdk/msb/k8s/definition.py
@@ -12,413 +12,8 @@
# 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 Iterator
-from dataclasses import dataclass
+import warnings
+from onapsdk.k8s.definition import Definition, Profile, ConfigurationTemplate # pylint: disable=unused-import
-from onapsdk.utils.jinja import jinja_env
-from ..msb_service import MSB
-
-
-# pylint: disable=too-many-arguments, too-few-public-methods
-class DefinitionBase(MSB):
- """DefinitionBase class."""
-
- base_url = f"{MSB.base_url}/api/multicloud-k8s/v1/v1/rb/definition"
-
- def __init__(self, rb_name: str,
- rb_version: str) -> None:
- """Definition-Base object initialization.
-
- Args:
- rb_name (str): Definition name
- rb_version (str): Definition version
- """
- super().__init__()
- self.rb_name: str = rb_name
- self.rb_version: str = rb_version
-
- @property
- def url(self) -> str:
- """URL address for Definition Based calls.
-
- Returns:
- str: URL to RB Definition
-
- """
- return f"{self.base_url}/{self.rb_name}/{self.rb_version}"
-
- def delete(self) -> None:
- """Delete Definition Based object."""
- self.send_message(
- "DELETE",
- f"Delete {self.__class__.__name__}",
- self.url
- )
-
- def upload_artifact(self, package: bytes = None):
- """Upload artifact.
-
- Args:
- package (bytes): Artifact to be uploaded to multicloud-k8s plugin
-
- """
- url: str = f"{self.url}/content"
- self.send_message(
- "POST",
- "Upload Artifact content",
- url,
- data=package,
- headers={}
- )
-
-
-class Definition(DefinitionBase):
- """Definition class."""
-
- def __init__(self, rb_name: str,
- rb_version: str,
- chart_name: str,
- description: str,
- labels: dict) -> None:
- """Definition object initialization.
-
- Args:
- rb_name (str): Definition name
- rb_version (str): Definition version
- chart_name (str): Chart name, optional field, will be detected if it is not provided
- description (str): Definition description
- labels (str): Labels
- """
- super().__init__(rb_name, rb_version)
- self.rb_name: str = rb_name
- self.rb_version: str = rb_version
- self.chart_name: str = chart_name
- self.description: str = description
- self.labels: dict = labels
-
- @classmethod
- def get_all(cls):
- """Get all definitions.
-
- Yields:
- Definition: Definition object
-
- """
- for definition in cls.send_message_json("GET",
- "Get definitions",
- cls.base_url):
- yield cls(
- definition["rb-name"],
- definition["rb-version"],
- definition.get("chart-name"),
- definition.get("description"),
- definition.get("labels")
- )
-
- @classmethod
- def get_definition_by_name_version(cls, rb_name: str, rb_version: str) -> "Definition":
- """Get definition by it's name and version.
-
- Args:
- rb_name (str): definition name
- rb_version (str): definition version
-
- Returns:
- Definition: Definition object
-
- """
- url: str = f"{cls.base_url}/{rb_name}/{rb_version}"
- definition: dict = cls.send_message_json(
- "GET",
- "Get definition",
- url
- )
- return cls(
- definition["rb-name"],
- definition["rb-version"],
- definition.get("chart-name"),
- definition.get("description"),
- definition.get("labels")
- )
-
- @classmethod
- def create(cls, rb_name: str,
- rb_version: str,
- chart_name: str = "",
- description: str = "",
- labels=None) -> "Definition":
- """Create Definition.
-
- Args:
- rb_name (str): Definition name
- rb_version (str): Definition version
- chart_name (str): Chart name, optional field, will be detected if it is not provided
- description (str): Definition description
- labels (str): Labels
-
- Returns:
- Definition: Created object
-
- """
- if labels is None:
- labels = {}
- url: str = f"{cls.base_url}"
- cls.send_message(
- "POST",
- "Create definition",
- url,
- data=jinja_env().get_template("multicloud_k8s_add_definition.json.j2").render(
- rb_name=rb_name,
- rb_version=rb_version,
- chart_name=chart_name,
- description=description,
- labels=labels
- )
- )
- return cls.get_definition_by_name_version(rb_name, rb_version)
-
- def create_profile(self, profile_name: str,
- namespace: str,
- kubernetes_version: str,
- release_name=None) -> "Profile":
- """Create Profile for Definition.
-
- Args:
- profile_name (str): Name of profile
- namespace (str): Namespace that service is created in
- kubernetes_version (str): Required Kubernetes version
- release_name (str): Release name
-
- Returns:
- Profile: Created object
-
- """
- url: str = f"{self.url}/profile"
- if release_name is None:
- release_name = profile_name
- self.send_message(
- "POST",
- "Create profile for definition",
- url,
- data=jinja_env().get_template("multicloud_k8s_create_profile_"
- "for_definition.json.j2").render(
- rb_name=self.rb_name,
- rb_version=self.rb_version,
- profile_name=profile_name,
- release_name=release_name,
- namespace=namespace,
- kubernetes_version=kubernetes_version
- )
- )
- return self.get_profile_by_name(profile_name)
-
- def get_all_profiles(self) -> Iterator["Profile"]:
- """Get all profiles.
-
- Yields:
- Profile: Profile object
-
- """
- url: str = f"{self.url}/profile"
-
- for profile in self.send_message_json("GET",
- "Get profiles",
- url):
- yield Profile(
- profile["rb-name"],
- profile["rb-version"],
- profile["profile-name"],
- profile["namespace"],
- profile.get("kubernetes-version"),
- profile.get("labels"),
- profile.get("release-name")
- )
-
- def get_profile_by_name(self, profile_name: str) -> "Profile":
- """Get profile by it's name.
-
- Args:
- profile_name (str): profile name
-
- Returns:
- Profile: Profile object
-
- """
- url: str = f"{self.url}/profile/{profile_name}"
-
- profile: dict = self.send_message_json(
- "GET",
- "Get profile",
- url
- )
- return Profile(
- profile["rb-name"],
- profile["rb-version"],
- profile["profile-name"],
- profile["namespace"],
- profile.get("kubernetes-version"),
- profile.get("labels"),
- profile.get("release-name")
- )
-
- def get_all_configuration_templates(self):
- """Get all configuration templates.
-
- Yields:
- ConfigurationTemplate: ConfigurationTemplate object
-
- """
- url: str = f"{self.url}/config-template"
-
- for template in self.send_message_json("GET",
- "Get configuration templates",
- url):
- yield ConfigurationTemplate(
- self.rb_name,
- self.rb_version,
- template["template-name"],
- template.get("description")
- )
-
- def create_configuration_template(self, template_name: str,
- description="") -> "ConfigurationTemplate":
- """Create configuration template.
-
- Args:
- template_name (str): Name of the template
- description (str): Description
-
- Returns:
- ConfigurationTemplate: Created object
-
- """
- url: str = f"{self.url}/config-template"
-
- self.send_message(
- "POST",
- "Create configuration template",
- url,
- data=jinja_env().get_template("multicloud_k8s_create_configuration_"
- "template.json.j2").render(
- template_name=template_name,
- description=description
- )
- )
-
- return self.get_configuration_template_by_name(template_name)
-
- def get_configuration_template_by_name(self, template_name: str) -> "ConfigurationTemplate":
- """Get configuration template.
-
- Args:
- template_name (str): Name of the template
-
- Returns:
- ConfigurationTemplate: object
-
- """
- url: str = f"{self.url}/config-template/{template_name}"
-
- template: dict = self.send_message_json(
- "GET",
- "Get Configuration template",
- url
- )
- return ConfigurationTemplate(
- self.rb_name,
- self.rb_version,
- template["template-name"],
- template.get("description")
- )
-
-
-class ProfileBase(DefinitionBase):
- """ProfileBase class."""
-
- def __init__(self, rb_name: str,
- rb_version: str,
- profile_name: str) -> None:
- """Profile-Base object initialization.
-
- Args:
- rb_name (str): Definition name
- rb_version (str): Definition version
- profile_name (str): Name of profile
- """
- super().__init__(rb_name, rb_version)
- self.rb_name: str = rb_name
- self.rb_version: str = rb_version
- self.profile_name: str = profile_name
-
- @property
- def url(self) -> str:
- """URL address for Profile calls.
-
- Returns:
- str: URL to RB Profile
-
- """
- return f"{super().url}/profile/{self.profile_name}"
-
-
-@dataclass
-class Profile(ProfileBase):
- """Profile class."""
-
- def __init__(self, rb_name: str,
- rb_version: str,
- profile_name: str,
- namespace: str,
- kubernetes_version: str,
- labels=None,
- release_name=None) -> None:
- """Profile object initialization.
-
- Args:
- rb_name (str): Definition name
- rb_version (str): Definition version
- profile_name (str): Name of profile
- release_name (str): Release name, if release_name is not provided,
- namespace (str): Namespace that service is created in
- kubernetes_version (str): Required Kubernetes version
- labels (dict): Labels
- """
- super().__init__(rb_name, rb_version, profile_name)
- if release_name is None:
- release_name = profile_name
- self.release_name: str = release_name
- self.namespace: str = namespace
- self.kubernetes_version: str = kubernetes_version
- self.labels: dict = labels
- if self.labels is None:
- self.labels = dict()
-
-
-class ConfigurationTemplate(DefinitionBase):
- """ConfigurationTemplate class."""
-
- @property
- def url(self) -> str:
- """URL address for ConfigurationTemplate calls.
-
- Returns:
- str: URL to Configuration template in Multicloud-k8s API.
-
- """
- return f"{super().url}/config-template/{self.template_name}"
-
- def __init__(self, rb_name: str,
- rb_version: str,
- template_name: str,
- description="") -> None:
- """Configuration-Template object initialization.
-
- Args:
- rb_name (str): Definition name
- rb_version (str): Definition version
- template_name (str): Configuration template name
- description (str): Namespace that service is created in
- """
- super().__init__(rb_name, rb_version)
- self.template_name: str = template_name
- self.description: str = description
+warnings.warn("onapsdk.msb.k8s.definition module is deprecated and will be removed with "
+ "the next version of ONAP SDK. Use onapsdk.k8s.definition")
diff --git a/src/onapsdk/msb/k8s/instance.py b/src/onapsdk/msb/k8s/instance.py
index 196b9d2..d85e8c6 100644
--- a/src/onapsdk/msb/k8s/instance.py
+++ b/src/onapsdk/msb/k8s/instance.py
@@ -12,179 +12,14 @@
# 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 Iterator
-from dataclasses import dataclass
-from onapsdk.msb import MSB
-from onapsdk.utils.jinja import jinja_env
+import warnings
+from onapsdk.k8s.instance import ( # pylint: disable=unused-import
+ InstantiationParameter,
+ InstantiationRequest,
+ Instance,
+ Configuration
+)
-
-# pylint: disable=too-many-arguments
-@dataclass
-class InstantiationRequest:
- """Instantiation Request class."""
-
- def __init__(self, request: dict) -> None:
- """Request object initialization.
-
- Args:
- cloud_region_id (str): Cloud region ID
- profile_name (str): Name of profile
- rb_name (str): Definition name
- rb_version (str): Definition version
- override_values (dict): Optional parameters
- labels (dict): Optional labels
- """
- super().__init__()
- self.cloud_region_id: str = request["cloud-region"]
- self.profile_name: str = request["profile-name"]
- self.rb_name: str = request["rb-name"]
- self.rb_version: str = request["rb-version"]
- self.override_values: dict = request["override-values"]
- self.labels: dict = request["labels"]
-
-
-@dataclass
-class InstantiationParameter:
- """Class to store instantiation parameters used to pass override_values and labels.
-
- Contains two values: name of parameter and it's value
- """
-
- name: str
- value: str
-
-
-class Instance(MSB):
- """Instance class."""
-
- base_url = f"{MSB.base_url}/api/multicloud-k8s/v1/v1/instance"
-
- def __init__(self, instance_id: str,
- namespace: str,
- request: InstantiationRequest,
- resources: dict = None,
- override_values: dict = None) -> None:
- """Instance object initialization.
-
- Args:
- instance_id (str): instance ID
- namespace (str): namespace that instance is created in
- request (InstantiationRequest): datails of the instantiation request
- resources (dict): Created resources
- override_values (dict): Optional values
- """
- super().__init__()
- self.instance_id: str = instance_id
- self.namespace: str = namespace
- self.request: InstantiationRequest = request
- self.resources: dict = resources
- self.override_values: dict = override_values
-
- @property
- def url(self) -> str:
- """URL address.
-
- Returns:
- str: URL to Instance
-
- """
- return f"{self.base_url}/{self.instance_id}"
-
- @classmethod
- def get_all(cls) -> Iterator["Instance"]:
- """Get all instantiated Kubernetes resources.
-
- Yields:
- Instantiation: Instantiation object
-
- """
- for resource in cls.send_message_json("GET",
- "Get Kubernetes resources",
- cls.base_url):
- yield cls(
- instance_id=resource["id"],
- namespace=resource["namespace"],
- request=InstantiationRequest(resource["request"])
- )
-
- @classmethod
- def get_by_id(cls, instance_id: str) -> "Instance":
- """Get Kubernetes resource by id.
-
- Args:
- instance_id (str): instance ID
-
- Returns:
- Instantiation: Instantiation object
-
- """
- url: str = f"{cls.base_url}/{instance_id}"
- resource: dict = cls.send_message_json(
- "GET",
- "Get Kubernetes resource by id",
- url
- )
- return cls(
- instance_id=resource["id"],
- namespace=resource["namespace"],
- request=InstantiationRequest(resource["request"]),
- resources=resource["resources"],
- override_values=resource.get("override-values")
- )
-
- @classmethod
- def create(cls,
- cloud_region_id: str,
- profile_name: str,
- rb_name: str,
- rb_version: str,
- override_values: dict = None,
- labels: dict = None) -> "Instance":
- """Create Instance.
-
- Args:
- cloud_region_id (str): Cloud region ID
- profile_name (str): Name of profile to be instantiated
- rb_name: (bytes): Definition name
- rb_version (str): Definition version
- override_values (dict): List of optional override values
- labels (dict): List of optional labels
-
- Returns:
- Instance: Created object
-
- """
- if labels is None:
- labels = {}
- if override_values is None:
- override_values = {}
- url: str = f"{cls.base_url}"
- response: dict = cls.send_message_json(
- "POST",
- "Create Instance",
- url,
- data=jinja_env().get_template("multicloud_k8s_instantiate.json.j2").render(
- cloud_region_id=cloud_region_id,
- profile_name=profile_name,
- rb_name=rb_name,
- rb_version=rb_version,
- override_values=override_values,
- labels=labels),
- headers={}
- )
- return cls(
- instance_id=response["id"],
- namespace=response["namespace"],
- request=InstantiationRequest(response["request"]),
- resources=response["resources"],
- override_values=response.get("override-values")
- )
-
- def delete(self) -> None:
- """Delete Instance object."""
- self.send_message(
- "DELETE",
- f"Delete {self.instance_id} instance",
- self.url
- )
+warnings.warn("onapsdk.msb.k8s.instance module is deprecated and will be removed with "
+ "the next version of ONAP SDK. Use onapsdk.k8s.instance")
diff --git a/src/onapsdk/msb/k8s/k8splugin_msb_service.py b/src/onapsdk/msb/k8s/k8splugin_msb_service.py
new file mode 100644
index 0000000..d1e38df
--- /dev/null
+++ b/src/onapsdk/msb/k8s/k8splugin_msb_service.py
@@ -0,0 +1,20 @@
+"""K8s package."""
+# Copyright 2023 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 warnings
+from onapsdk.k8s.k8splugin_service import K8sPlugin # pylint: disable=unused-import
+
+warnings.warn("onapsdk.msb.k8s.k8splugin_service module is deprecated and will be removed with "
+ "the next version of ONAP SDK. Use onapsdk.k8s.k8splugin_service")
diff --git a/src/onapsdk/utils/headers_creator.py b/src/onapsdk/utils/headers_creator.py
index ae03a38..0f1bc79 100644
--- a/src/onapsdk/utils/headers_creator.py
+++ b/src/onapsdk/utils/headers_creator.py
@@ -223,7 +223,8 @@ def headers_sdc_artifact_upload(base_header: Dict[str, str], data: str):
headers["Accept"] = "application/json, text/plain, */*"
headers["Accept-Encoding"] = "gzip, deflate, br"
headers["Content-Type"] = "application/json; charset=UTF-8"
- md5_content = hashlib.new('md5', data.encode('UTF-8'), usedforsecurity=False).hexdigest()
+ md5_content = hashlib.new('md5', data.encode('UTF-8'),
+ usedforsecurity=False).hexdigest() # nosec
content = base64.b64encode(md5_content.encode('ascii')).decode('UTF-8')
headers["Content-MD5"] = content
return headers
diff --git a/src/onapsdk/utils/jinja.py b/src/onapsdk/utils/jinja.py
index fe59eae..8af130c 100644
--- a/src/onapsdk/utils/jinja.py
+++ b/src/onapsdk/utils/jinja.py
@@ -39,7 +39,7 @@ def jinja_env() -> Environment:
PackageLoader("onapsdk.aai"),
PackageLoader("onapsdk.cds"),
PackageLoader("onapsdk.clamp"),
- PackageLoader("onapsdk.msb"),
+ PackageLoader("onapsdk.k8s"),
PackageLoader("onapsdk.nbi"),
PackageLoader("onapsdk.sdc"),
PackageLoader("onapsdk.sdnc"),