From d3642111fa5de844d07cde2dc62a1a731867a918 Mon Sep 17 00:00:00 2001 From: garciadeblas Date: Tue, 1 Oct 2024 00:42:04 +0200 Subject: [PATCH] Add osmclient commands for cluster mgmt: get-creds, register Change-Id: I6a15751e612d929afa67c7b03a78b8808ecb8507 Signed-off-by: garciadeblas --- osmclient/cli_commands/cluster.py | 48 ++++++++++++++++++++++++++++++ osmclient/scripts/osm.py | 2 ++ osmclient/sol005/cluster.py | 35 ++++++++++++++++++++-- osmclient/sol005/osm_api_object.py | 12 ++++---- 4 files changed, 89 insertions(+), 8 deletions(-) diff --git a/osmclient/cli_commands/cluster.py b/osmclient/cli_commands/cluster.py index 15c83bc..53991b7 100755 --- a/osmclient/cli_commands/cluster.py +++ b/osmclient/cli_commands/cluster.py @@ -16,6 +16,7 @@ import click from osmclient.cli_commands import common import logging +import yaml logger = logging.getLogger("osmclient") @@ -145,3 +146,50 @@ def cluster_get_credentials(ctx, name, **kwargs): """ logger.debug("") ctx.obj.cluster.get_credentials(name) + + +@click.command(name="cluster-register", short_help="registers a K8s cluster to OSM") +@click.argument("name") +@click.option( + "--vim-account", + "--vim", + prompt=True, + help="VIM target or cloud account where the cluster will be created", +) +@click.option( + "--creds", prompt=True, help="credentials file, i.e. a valid `.kube/config` file" +) +@click.option("--description", default="", help="human readable description") +@click.pass_context +def cluster_register( + ctx, + name, + vim_account, + creds, + description, +): + """registers a K8s cluster to OSM + + NAME: name of the K8s cluster + """ + logger.debug("") + # kwargs = {k: v for k, v in kwargs.items() if v is not None} + cluster = {} + cluster["name"] = name + with open(creds, "r") as cf: + cluster["credentials"] = yaml.safe_load(cf.read()) + # cluster["k8s_version"] = version + cluster["vim_account"] = vim_account + # cluster["nets"] = yaml.safe_load(k8s_nets) + # if not (init_jujubundle and init_helm3): + # cluster["deployment_methods"] = { + # "juju-bundle": init_jujubundle, + # "helm-chart-v3": init_helm3, + # } + if description: + cluster["description"] = description + # if namespace: + # cluster["namespace"] = namespace + # if cni: + # cluster["cni"] = yaml.safe_load(cni) + ctx.obj.cluster.register(name, cluster) diff --git a/osmclient/scripts/osm.py b/osmclient/scripts/osm.py index 78d3fff..c90e513 100755 --- a/osmclient/scripts/osm.py +++ b/osmclient/scripts/osm.py @@ -193,6 +193,8 @@ def cli(): cli_osm.add_command(cluster.cluster_list) cli_osm.add_command(cluster.cluster_show) cli_osm.add_command(cluster.cluster_update) + cli_osm.add_command(cluster.cluster_get_credentials) + cli_osm.add_command(cluster.cluster_register) cli_osm.add_command(netslice_instance.nsi_create1) cli_osm.add_command(netslice_instance.nsi_create2) diff --git a/osmclient/sol005/cluster.py b/osmclient/sol005/cluster.py index 9aebeab..bc961a3 100644 --- a/osmclient/sol005/cluster.py +++ b/osmclient/sol005/cluster.py @@ -20,8 +20,9 @@ OSM Cluster API handling """ from osmclient.sol005.osm_api_object import GenericOSMAPIObject -from osmclient.common.exceptions import ClientException +from osmclient.common.exceptions import ClientException, NotFound import json +import yaml class Cluster(GenericOSMAPIObject): @@ -61,5 +62,33 @@ class Cluster(GenericOSMAPIObject): elif http_code == 204: print("Updated") - # def get_credentials(self, cluster_id): - # # TODO: + def get_credentials(self, name): + """ + Gets and shows an individual Generic OSM API Object + from the list of all objects of the same kind + """ + self._logger.debug("") + item = self.get(name) + resp = "" + try: + _, resp = self._http.get2_cmd(f"{self._apiBase}/{item['_id']}/get_creds") + if resp: + resp = json.loads(resp) + item = self.get(name) + print( + yaml.safe_dump( + item["credentials"], indent=4, default_flow_style=False + ) + ) + except NotFound: + raise NotFound(f"{self._logObjectName} '{name}' not found") + except Exception as e: + raise ClientException(f"{e}: unexpected response from server - {resp}") + + def register_cluster(self, name, cluster): + """ + Registers a K8s cluster + """ + self._logger.debug("") + endpoint = f"{self._apiBase}/register" + self.create(name, cluster, None, endpoint=endpoint) diff --git a/osmclient/sol005/osm_api_object.py b/osmclient/sol005/osm_api_object.py index 0c1ba1e..0e4b8cb 100644 --- a/osmclient/sol005/osm_api_object.py +++ b/osmclient/sol005/osm_api_object.py @@ -127,7 +127,7 @@ class GenericOSMAPIObject(ABC): def get_individual(self, name): """Gets and shows an individual Generic OSM API Object""" - # It is redundant, since the method getalready gets the whole item + # It is redundant, since the method `get` already gets the whole item # The only difference is that a different primitive is exercised self._logger.debug("") item = self.get(name) @@ -222,10 +222,12 @@ class GenericOSMAPIObject(ABC): f"failed to create {self._logObjectName}. Http code: {http_code}. Message: {msg}" ) - def create(self, name, content_dict=None, filename=None): + def create(self, name, content_dict=None, filename=None, endpoint=None): """Creates a new Generic OSM API Object""" self._logger.debug(f"Creating Generic OSM API Object {name}") self._client.get_token() + if not endpoint: + endpoint = self._apiBase # If filename is dir, generate a tar.gz file tempdir = None if filename: @@ -238,7 +240,7 @@ class GenericOSMAPIObject(ABC): # Typical case. Only a dict self._logger.debug("Sending only a dict") _, resp = self._http.post_cmd( - endpoint=self._apiBase, + endpoint=endpoint, postfields_dict=content_dict, skip_query_admin=True, ) @@ -260,13 +262,13 @@ class GenericOSMAPIObject(ABC): self._logger.debug(f"formfile: {formfile}") self.set_http_headers(filename, multipart=True) _, resp = self._http.post_cmd( - endpoint=self._apiBase, postdata=content_dict, formfile=formfile + endpoint=endpoint, postdata=content_dict, formfile=formfile ) elif not content_dict and filename: self._logger.debug("Sending only a file") # Only a file to be sent self.set_http_headers(filename) - _, resp = self._http.post_cmd(endpoint=self._apiBase, filename=filename) + _, resp = self._http.post_cmd(endpoint=endpoint, filename=filename) if resp: resp = json.loads(resp) self._logger.debug(f"Resp: {resp}") -- 2.25.1