From 301824d4270a7aa09953cc38e2de8f7d035f8b61 Mon Sep 17 00:00:00 2001 From: carsonmh Date: Thu, 20 Jul 2023 15:16:58 -0700 Subject: [PATCH 01/10] Add: create_api_client_config helper function for the SDK --- src/codeflare_sdk/cluster/auth.py | 32 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/codeflare_sdk/cluster/auth.py b/src/codeflare_sdk/cluster/auth.py index 85db3d61d..fce410e97 100644 --- a/src/codeflare_sdk/cluster/auth.py +++ b/src/codeflare_sdk/cluster/auth.py @@ -97,17 +97,11 @@ def login(self) -> str: global config_path global api_client try: - configuration = client.Configuration() - configuration.api_key_prefix["authorization"] = "Bearer" - configuration.host = self.server - configuration.api_key["authorization"] = self.token - if self.skip_tls == False and self.ca_cert_path == None: - configuration.verify_ssl = True - elif self.skip_tls == False: - configuration.ssl_ca_cert = self.ca_cert_path - else: - configuration.verify_ssl = False - api_client = client.ApiClient(configuration) + api_client = client.ApiClient( + _create_api_client_config( + self.token, self.server, self.skip_tls, self.ca_cert_path + ) + ) client.AuthenticationApi(api_client).get_api_group() config_path = None return "Logged into %s" % self.server @@ -154,6 +148,22 @@ def load_kube_config(self): return response +def _create_api_client_config( + token: str, server: str, skip_tls: bool = False, ca_cert_path: str = None +): + configuration = client.Configuration() + configuration.api_key_prefix["authorization"] = "Bearer" + configuration.host = server + configuration.api_key["authorization"] = token + if skip_tls == False and ca_cert_path == None: + configuration.verify_ssl = True + elif skip_tls == False: + configuration.ssl_ca_cert = ca_cert_path + else: + configuration.verify_ssl = False + return configuration + + def config_check() -> str: """ Function for loading the config file at the default config location ~/.kube/config if the user has not From c1c701d02d05e17296c7397f845e692203f590fb Mon Sep 17 00:00:00 2001 From: carsonmh Date: Thu, 20 Jul 2023 16:02:50 -0700 Subject: [PATCH 02/10] Add: login function for CLI --- src/codeflare_sdk/cli/cli_utils.py | 44 +++++++++++++++++++++++++ src/codeflare_sdk/cli/commands/login.py | 28 ++++++++++++++++ src/codeflare_sdk/cluster/auth.py | 3 ++ 3 files changed, 75 insertions(+) create mode 100644 src/codeflare_sdk/cli/commands/login.py diff --git a/src/codeflare_sdk/cli/cli_utils.py b/src/codeflare_sdk/cli/cli_utils.py index 7152cc397..b6f31474c 100644 --- a/src/codeflare_sdk/cli/cli_utils.py +++ b/src/codeflare_sdk/cli/cli_utils.py @@ -1,5 +1,10 @@ import ast import click +from kubernetes import client +import pickle + +from codeflare_sdk.cluster.auth import _create_api_client_config +import codeflare_sdk.cluster.auth as sdk_auth class PythonLiteralOption(click.Option): @@ -10,3 +15,42 @@ def type_cast_value(self, ctx, value): return ast.literal_eval(value) except: raise click.BadParameter(value) + + +class AuthenticationConfig: + """ + Authentication configuration that will be stored in a file once + the user logs in using `codeflare login` + """ + + def __init__( + self, + token: str, + server: str, + skip_tls: bool, + ca_cert_path: str, + k8_config_path: str, + ): + self.api_client_config = _create_api_client_config( + token, server, skip_tls, ca_cert_path + ) + self.k8_config_path = k8_config_path + + def create_client(self): + return client.ApiClient(self.api_client_config) + + +def load_auth(): + """ + Loads AuthenticationConfiguration and stores it in global variables + which can be used by the SDK for authentication + """ + try: + with open("auth", "rb") as file: + auth = pickle.load(file) + sdk_auth.api_client = auth.create_client() + sdk_auth.config_path = auth.k8_config_path + except IOError: + raise "Not logged into Kubernetes cluster" + except EOFError: + raise "Not logged into Kubernetes cluster" diff --git a/src/codeflare_sdk/cli/commands/login.py b/src/codeflare_sdk/cli/commands/login.py new file mode 100644 index 000000000..88700daae --- /dev/null +++ b/src/codeflare_sdk/cli/commands/login.py @@ -0,0 +1,28 @@ +import click +import pickle + +from codeflare_sdk.cluster.auth import TokenAuthentication +from codeflare_sdk.cli.cli_utils import AuthenticationConfig +import codeflare_sdk.cluster.auth as sdk_auth + + +@click.command() +@click.argument("server") +@click.option("--token", "-t", type=str, required=True) +@click.option("--skip-tls", type=bool) +@click.option("--ca-cert-path", type=str) +def cli(server, token, skip_tls, ca_cert_path): + """ + Login to your Kubernetes cluster by specifying server and token + """ + try: + auth = TokenAuthentication(token, server, skip_tls, ca_cert_path) + auth.login() + authConfig = AuthenticationConfig( + token, server, skip_tls, ca_cert_path, sdk_auth.config_path + ) + with open("auth", "wb") as file: + pickle.dump(authConfig, file) + click.echo(f"Logged into {server}") + except Exception as e: + click.echo(e) diff --git a/src/codeflare_sdk/cluster/auth.py b/src/codeflare_sdk/cluster/auth.py index fce410e97..90c1f726a 100644 --- a/src/codeflare_sdk/cluster/auth.py +++ b/src/codeflare_sdk/cluster/auth.py @@ -151,6 +151,9 @@ def load_kube_config(self): def _create_api_client_config( token: str, server: str, skip_tls: bool = False, ca_cert_path: str = None ): + """ + Creates Kubernetes client configuration given necessary parameters + """ configuration = client.Configuration() configuration.api_key_prefix["authorization"] = "Bearer" configuration.host = server From 56a56e3602e2c3c42ea85504efac6e7e1e1dc4ca Mon Sep 17 00:00:00 2001 From: carsonmh Date: Fri, 21 Jul 2023 12:52:42 -0700 Subject: [PATCH 03/10] Change: change options and help for login function --- src/codeflare_sdk/cli/cli_utils.py | 5 ++-- src/codeflare_sdk/cli/commands/login.py | 34 +++++++++++++++++------- src/codeflare_sdk/cli/commands/logout.py | 0 3 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 src/codeflare_sdk/cli/commands/logout.py diff --git a/src/codeflare_sdk/cli/cli_utils.py b/src/codeflare_sdk/cli/cli_utils.py index b6f31474c..ef9bb7d17 100644 --- a/src/codeflare_sdk/cli/cli_utils.py +++ b/src/codeflare_sdk/cli/cli_utils.py @@ -50,7 +50,8 @@ def load_auth(): auth = pickle.load(file) sdk_auth.api_client = auth.create_client() sdk_auth.config_path = auth.k8_config_path + return auth except IOError: - raise "Not logged into Kubernetes cluster" + return None except EOFError: - raise "Not logged into Kubernetes cluster" + return None diff --git a/src/codeflare_sdk/cli/commands/login.py b/src/codeflare_sdk/cli/commands/login.py index 88700daae..ad24e1c80 100644 --- a/src/codeflare_sdk/cli/commands/login.py +++ b/src/codeflare_sdk/cli/commands/login.py @@ -2,24 +2,40 @@ import pickle from codeflare_sdk.cluster.auth import TokenAuthentication -from codeflare_sdk.cli.cli_utils import AuthenticationConfig +from codeflare_sdk.cli.cli_utils import AuthenticationConfig, load_auth import codeflare_sdk.cluster.auth as sdk_auth @click.command() -@click.argument("server") -@click.option("--token", "-t", type=str, required=True) -@click.option("--skip-tls", type=bool) -@click.option("--ca-cert-path", type=str) -def cli(server, token, skip_tls, ca_cert_path): +@click.option("--server", type=str, required=True, help="Cluster API address") +@click.option("--token", "-t", type=str, required=True, help="Authentication token") +@click.option( + "--insecure-skip-tls-verify", + type=bool, + help="If true, server's certificate won't be checked for validity", +) +@click.option( + "--certificate-authority", + type=str, + help="Path to cert file for certificate authority", +) +def cli(server, token, insecure_skip_tls_verify, certificate_authority): """ - Login to your Kubernetes cluster by specifying server and token + Login to your Kubernetes cluster and save login for subsequent use """ try: - auth = TokenAuthentication(token, server, skip_tls, ca_cert_path) + auth = TokenAuthentication( + token, server, insecure_skip_tls_verify, certificate_authority + ) auth.login() + + # Store auth config for later use authConfig = AuthenticationConfig( - token, server, skip_tls, ca_cert_path, sdk_auth.config_path + token, + server, + insecure_skip_tls_verify, + certificate_authority, + sdk_auth.config_path, ) with open("auth", "wb") as file: pickle.dump(authConfig, file) diff --git a/src/codeflare_sdk/cli/commands/logout.py b/src/codeflare_sdk/cli/commands/logout.py new file mode 100644 index 000000000..e69de29bb From 2bbf2bd5f21b0c33d8843c07c4f8703cb65b1f83 Mon Sep 17 00:00:00 2001 From: carsonmh Date: Fri, 21 Jul 2023 13:07:59 -0700 Subject: [PATCH 04/10] Create: logout function --- src/codeflare_sdk/cli/cli_utils.py | 2 ++ src/codeflare_sdk/cli/commands/logout.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/codeflare_sdk/cli/cli_utils.py b/src/codeflare_sdk/cli/cli_utils.py index ef9bb7d17..6f2d99144 100644 --- a/src/codeflare_sdk/cli/cli_utils.py +++ b/src/codeflare_sdk/cli/cli_utils.py @@ -35,6 +35,8 @@ def __init__( token, server, skip_tls, ca_cert_path ) self.k8_config_path = k8_config_path + self.server = server + self.token = token def create_client(self): return client.ApiClient(self.api_client_config) diff --git a/src/codeflare_sdk/cli/commands/logout.py b/src/codeflare_sdk/cli/commands/logout.py index e69de29bb..dc360054f 100644 --- a/src/codeflare_sdk/cli/commands/logout.py +++ b/src/codeflare_sdk/cli/commands/logout.py @@ -0,0 +1,17 @@ +import click +import os + +from codeflare_sdk.cli.cli_utils import load_auth + + +@click.command() +def cli(): + """ + Log out of current Kubernetes cluster + """ + auth = load_auth() + if not auth: + click.echo("Not logged in") + return + os.remove("auth") + click.echo(f"Logged out of '{auth.server}'") From 8f9108e739a79a438faa4be947392a4cf3dc7982 Mon Sep 17 00:00:00 2001 From: carsonmh Date: Fri, 21 Jul 2023 13:27:46 -0700 Subject: [PATCH 05/10] Test: add unit tests for login and logout functions --- src/codeflare_sdk/cli/commands/login.py | 2 +- src/codeflare_sdk/cli/commands/logout.py | 2 +- tests/unit_test.py | 40 ++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/codeflare_sdk/cli/commands/login.py b/src/codeflare_sdk/cli/commands/login.py index ad24e1c80..7b2a45964 100644 --- a/src/codeflare_sdk/cli/commands/login.py +++ b/src/codeflare_sdk/cli/commands/login.py @@ -39,6 +39,6 @@ def cli(server, token, insecure_skip_tls_verify, certificate_authority): ) with open("auth", "wb") as file: pickle.dump(authConfig, file) - click.echo(f"Logged into {server}") + click.echo(f"Logged into '{server}'") except Exception as e: click.echo(e) diff --git a/src/codeflare_sdk/cli/commands/logout.py b/src/codeflare_sdk/cli/commands/logout.py index dc360054f..c73bb0b6d 100644 --- a/src/codeflare_sdk/cli/commands/logout.py +++ b/src/codeflare_sdk/cli/commands/logout.py @@ -14,4 +14,4 @@ def cli(): click.echo("Not logged in") return os.remove("auth") - click.echo(f"Logged out of '{auth.server}'") + click.echo(f"Successfully logged out of '{auth.server}'") diff --git a/tests/unit_test.py b/tests/unit_test.py index 9eddd3cfc..120cd7ef4 100644 --- a/tests/unit_test.py +++ b/tests/unit_test.py @@ -108,6 +108,46 @@ def test_cluster_definition_cli(): ) +def test_login_logout_cli(mocker): + runner = CliRunner() + mocker.patch.object(client, "ApiClient") + k8s_login_command = """ + login + --server=testserver:6443 + --token=testtoken + """ + login_result = runner.invoke(cli, k8s_login_command) + k8s_logout_command = "logout" + logout_result = runner.invoke(cli, k8s_logout_command) + assert login_result.output == "Logged into 'testserver:6443'\n" + assert logout_result.output == "Successfully logged out of 'testserver:6443'\n" + + +def test_login_tls_cli(mocker): + runner = CliRunner() + mocker.patch.object(client, "ApiClient") + k8s_tls_login_command = """ + login + --server=testserver:6443 + --token=testtoken + --insecure-skip-tls-verify=False + """ + k8s_skip_tls_login_command = """ + login + --server=testserver:6443 + --token=testtoken + --insecure-skip-tls-verify=True + """ + tls_result = runner.invoke(cli, k8s_tls_login_command) + skip_tls_result = runner.invoke(cli, k8s_skip_tls_login_command) + assert ( + tls_result.output == skip_tls_result.output == "Logged into 'testserver:6443'\n" + ) + + # Clean up + os.remove("auth") + + # For mocking openshift client results fake_res = openshift.Result("fake") From 081f5036806df72686de5ed642a7a9cacca48aab Mon Sep 17 00:00:00 2001 From: carsonmh Date: Wed, 26 Jul 2023 11:55:18 -0700 Subject: [PATCH 06/10] add: additional error handling and change layout slightly --- src/codeflare_sdk/cli/cli_utils.py | 14 ++++----- src/codeflare_sdk/cli/commands/login.py | 38 +++++++++++------------- src/codeflare_sdk/cli/commands/logout.py | 14 ++++----- tests/unit_test.py | 4 +-- 4 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/codeflare_sdk/cli/cli_utils.py b/src/codeflare_sdk/cli/cli_utils.py index 6f2d99144..df7de83d9 100644 --- a/src/codeflare_sdk/cli/cli_utils.py +++ b/src/codeflare_sdk/cli/cli_utils.py @@ -1,9 +1,10 @@ import ast import click -from kubernetes import client +from kubernetes import client, config import pickle from codeflare_sdk.cluster.auth import _create_api_client_config +from codeflare_sdk.utils.kube_api_helpers import _kube_api_error_handling import codeflare_sdk.cluster.auth as sdk_auth @@ -29,12 +30,10 @@ def __init__( server: str, skip_tls: bool, ca_cert_path: str, - k8_config_path: str, ): self.api_client_config = _create_api_client_config( token, server, skip_tls, ca_cert_path ) - self.k8_config_path = k8_config_path self.server = server self.token = token @@ -51,9 +50,8 @@ def load_auth(): with open("auth", "rb") as file: auth = pickle.load(file) sdk_auth.api_client = auth.create_client() - sdk_auth.config_path = auth.k8_config_path return auth - except IOError: - return None - except EOFError: - return None + except (IOError, EOFError): + click.echo("No authentication found, trying default kubeconfig") + except client.ApiException: + click.echo("Invalid authentication, trying default kubeconfig") diff --git a/src/codeflare_sdk/cli/commands/login.py b/src/codeflare_sdk/cli/commands/login.py index 7b2a45964..4007fdaa1 100644 --- a/src/codeflare_sdk/cli/commands/login.py +++ b/src/codeflare_sdk/cli/commands/login.py @@ -1,13 +1,14 @@ import click import pickle +from kubernetes import client from codeflare_sdk.cluster.auth import TokenAuthentication -from codeflare_sdk.cli.cli_utils import AuthenticationConfig, load_auth +from codeflare_sdk.cli.cli_utils import AuthenticationConfig import codeflare_sdk.cluster.auth as sdk_auth @click.command() -@click.option("--server", type=str, required=True, help="Cluster API address") +@click.option("--server", "-s", type=str, required=True, help="Cluster API address") @click.option("--token", "-t", type=str, required=True, help="Authentication token") @click.option( "--insecure-skip-tls-verify", @@ -23,22 +24,19 @@ def cli(server, token, insecure_skip_tls_verify, certificate_authority): """ Login to your Kubernetes cluster and save login for subsequent use """ - try: - auth = TokenAuthentication( - token, server, insecure_skip_tls_verify, certificate_authority - ) - auth.login() + auth = TokenAuthentication( + token, server, insecure_skip_tls_verify, certificate_authority + ) + auth.login() + if not sdk_auth.api_client: # TokenAuthentication failed + return - # Store auth config for later use - authConfig = AuthenticationConfig( - token, - server, - insecure_skip_tls_verify, - certificate_authority, - sdk_auth.config_path, - ) - with open("auth", "wb") as file: - pickle.dump(authConfig, file) - click.echo(f"Logged into '{server}'") - except Exception as e: - click.echo(e) + authConfig = AuthenticationConfig( + token, + server, + insecure_skip_tls_verify, + certificate_authority, + ) + with open("auth", "wb") as file: + pickle.dump(authConfig, file) + click.echo(f"Logged into '{server}'") diff --git a/src/codeflare_sdk/cli/commands/logout.py b/src/codeflare_sdk/cli/commands/logout.py index c73bb0b6d..5b29748d1 100644 --- a/src/codeflare_sdk/cli/commands/logout.py +++ b/src/codeflare_sdk/cli/commands/logout.py @@ -1,7 +1,6 @@ import click import os - -from codeflare_sdk.cli.cli_utils import load_auth +import pickle @click.command() @@ -9,9 +8,10 @@ def cli(): """ Log out of current Kubernetes cluster """ - auth = load_auth() - if not auth: + try: + with open("auth", "rb") as file: + auth = pickle.load(file) + os.remove("auth") + click.echo(f"Successfully logged out of '{auth.server}'") + except: click.echo("Not logged in") - return - os.remove("auth") - click.echo(f"Successfully logged out of '{auth.server}'") diff --git a/tests/unit_test.py b/tests/unit_test.py index 120cd7ef4..c958bb2df 100644 --- a/tests/unit_test.py +++ b/tests/unit_test.py @@ -144,9 +144,6 @@ def test_login_tls_cli(mocker): tls_result.output == skip_tls_result.output == "Logged into 'testserver:6443'\n" ) - # Clean up - os.remove("auth") - # For mocking openshift client results fake_res = openshift.Result("fake") @@ -2295,3 +2292,4 @@ def test_cleanup(): os.remove("test.yaml") os.remove("raytest2.yaml") os.remove("cli-test-cluster.yaml") + os.remove("auth") From 3ffb53c2bff742d1b296387a050b4d0eaffc33ad Mon Sep 17 00:00:00 2001 From: carsonmh Date: Wed, 26 Jul 2023 12:16:54 -0700 Subject: [PATCH 07/10] test: add unit test for load_auth --- tests/unit_test.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/unit_test.py b/tests/unit_test.py index c958bb2df..a3c0e1841 100644 --- a/tests/unit_test.py +++ b/tests/unit_test.py @@ -65,6 +65,8 @@ export_env, ) from codeflare_sdk.cli.codeflare_cli import cli +from codeflare_sdk.cli.cli_utils import load_auth +import codeflare_sdk.cluster.auth as sdk_auth import openshift from openshift.selector import Selector @@ -145,6 +147,11 @@ def test_login_tls_cli(mocker): ) +def test_load_auth(): + load_auth() + assert sdk_auth.api_client is not None + + # For mocking openshift client results fake_res = openshift.Result("fake") From 6ef0bde6e5dfac5e26016cbe2958a5d6708905f3 Mon Sep 17 00:00:00 2001 From: carsonmh Date: Wed, 26 Jul 2023 14:09:43 -0700 Subject: [PATCH 08/10] change: make tls skip false by default --- src/codeflare_sdk/cli/commands/login.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/codeflare_sdk/cli/commands/login.py b/src/codeflare_sdk/cli/commands/login.py index 4007fdaa1..06d042d82 100644 --- a/src/codeflare_sdk/cli/commands/login.py +++ b/src/codeflare_sdk/cli/commands/login.py @@ -14,6 +14,7 @@ "--insecure-skip-tls-verify", type=bool, help="If true, server's certificate won't be checked for validity", + default=False, ) @click.option( "--certificate-authority", From c91a1583f7252866dcc428972fca0fae939fdda7 Mon Sep 17 00:00:00 2001 From: carsonmh Date: Fri, 28 Jul 2023 12:23:03 -0700 Subject: [PATCH 09/10] add: make authentication go into .codeflare --- src/codeflare_sdk/cli/cli_utils.py | 4 +++- src/codeflare_sdk/cli/codeflare_cli.py | 14 ++++++++++++++ src/codeflare_sdk/cli/commands/login.py | 11 +++++++---- src/codeflare_sdk/cli/commands/logout.py | 8 +++++--- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/codeflare_sdk/cli/cli_utils.py b/src/codeflare_sdk/cli/cli_utils.py index df7de83d9..0c557a8ea 100644 --- a/src/codeflare_sdk/cli/cli_utils.py +++ b/src/codeflare_sdk/cli/cli_utils.py @@ -2,6 +2,7 @@ import click from kubernetes import client, config import pickle +import os from codeflare_sdk.cluster.auth import _create_api_client_config from codeflare_sdk.utils.kube_api_helpers import _kube_api_error_handling @@ -47,7 +48,8 @@ def load_auth(): which can be used by the SDK for authentication """ try: - with open("auth", "rb") as file: + auth_file_path = os.path.expanduser("~/.codeflare/auth") + with open(auth_file_path, "rb") as file: auth = pickle.load(file) sdk_auth.api_client = auth.create_client() return auth diff --git a/src/codeflare_sdk/cli/codeflare_cli.py b/src/codeflare_sdk/cli/codeflare_cli.py index 3083a40d0..f8a5cbab7 100644 --- a/src/codeflare_sdk/cli/codeflare_cli.py +++ b/src/codeflare_sdk/cli/codeflare_cli.py @@ -5,6 +5,11 @@ cmd_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), "commands")) +class CodeflareContext: + def __init__(self, codeflare_path): + self.codeflare_path = codeflare_path + + class CodeflareCLI(click.MultiCommand): def list_commands(self, ctx): rv = [] @@ -26,9 +31,18 @@ def get_command(self, ctx, name): return +def initialize_cli(ctx): + # Make .codeflare folder + codeflare_folder = os.path.expanduser("~/.codeflare") + if not os.path.exists(codeflare_folder): + os.makedirs(codeflare_folder) + ctx.obj = CodeflareContext(codeflare_folder) + + @click.command(cls=CodeflareCLI) @click.pass_context def cli(ctx): + initialize_cli(ctx) # Ran on every command pass diff --git a/src/codeflare_sdk/cli/commands/login.py b/src/codeflare_sdk/cli/commands/login.py index 06d042d82..288607a89 100644 --- a/src/codeflare_sdk/cli/commands/login.py +++ b/src/codeflare_sdk/cli/commands/login.py @@ -1,6 +1,7 @@ import click import pickle from kubernetes import client +import os from codeflare_sdk.cluster.auth import TokenAuthentication from codeflare_sdk.cli.cli_utils import AuthenticationConfig @@ -8,6 +9,7 @@ @click.command() +@click.pass_context @click.option("--server", "-s", type=str, required=True, help="Cluster API address") @click.option("--token", "-t", type=str, required=True, help="Authentication token") @click.option( @@ -21,7 +23,7 @@ type=str, help="Path to cert file for certificate authority", ) -def cli(server, token, insecure_skip_tls_verify, certificate_authority): +def cli(ctx, server, token, insecure_skip_tls_verify, certificate_authority): """ Login to your Kubernetes cluster and save login for subsequent use """ @@ -32,12 +34,13 @@ def cli(server, token, insecure_skip_tls_verify, certificate_authority): if not sdk_auth.api_client: # TokenAuthentication failed return - authConfig = AuthenticationConfig( + auth_config = AuthenticationConfig( token, server, insecure_skip_tls_verify, certificate_authority, ) - with open("auth", "wb") as file: - pickle.dump(authConfig, file) + auth_file_path = ctx.obj.codeflare_path + "/auth" + with open(auth_file_path, "wb") as file: + pickle.dump(auth_config, file) click.echo(f"Logged into '{server}'") diff --git a/src/codeflare_sdk/cli/commands/logout.py b/src/codeflare_sdk/cli/commands/logout.py index 5b29748d1..0001b2331 100644 --- a/src/codeflare_sdk/cli/commands/logout.py +++ b/src/codeflare_sdk/cli/commands/logout.py @@ -4,14 +4,16 @@ @click.command() -def cli(): +@click.pass_context +def cli(ctx): """ Log out of current Kubernetes cluster """ try: - with open("auth", "rb") as file: + auth_file_path = ctx.obj.codeflare_path + "/auth" + with open(auth_file_path, "rb") as file: auth = pickle.load(file) - os.remove("auth") + os.remove(auth_file_path) click.echo(f"Successfully logged out of '{auth.server}'") except: click.echo("Not logged in") From 2a44caf0dd3967a469c471919e072c28cdeb58bc Mon Sep 17 00:00:00 2001 From: carsonmh Date: Fri, 28 Jul 2023 12:39:47 -0700 Subject: [PATCH 10/10] test: add unit tests for checking validity of auth file and split login/logout tests --- tests/unit_test.py | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/tests/unit_test.py b/tests/unit_test.py index a3c0e1841..de202b518 100644 --- a/tests/unit_test.py +++ b/tests/unit_test.py @@ -18,6 +18,7 @@ import os import re from click.testing import CliRunner +import pickle parent = Path(__file__).resolve().parents[1] sys.path.append(str(parent) + "/src") @@ -110,7 +111,7 @@ def test_cluster_definition_cli(): ) -def test_login_logout_cli(mocker): +def test_login_cli(mocker): runner = CliRunner() mocker.patch.object(client, "ApiClient") k8s_login_command = """ @@ -119,10 +120,18 @@ def test_login_logout_cli(mocker): --token=testtoken """ login_result = runner.invoke(cli, k8s_login_command) - k8s_logout_command = "logout" - logout_result = runner.invoke(cli, k8s_logout_command) assert login_result.output == "Logged into 'testserver:6443'\n" - assert logout_result.output == "Successfully logged out of 'testserver:6443'\n" + try: + auth_file_path = os.path.expanduser("~/.codeflare/auth") + with open(auth_file_path, "rb") as file: + auth = pickle.load(file) + except: + assert 0 == 1 + assert auth.server == "testserver:6443" + assert auth.token == "testtoken" + assert auth.api_client_config.api_key["authorization"] == "testtoken" + assert auth.api_client_config.verify_ssl + assert auth.api_client_config.host == "testserver:6443" def test_login_tls_cli(mocker): @@ -147,6 +156,15 @@ def test_login_tls_cli(mocker): ) +def test_logout_cli(mocker): + runner = CliRunner() + mocker.patch.object(client, "ApiClient") + k8s_logout_command = "logout" + logout_result = runner.invoke(cli, k8s_logout_command) + assert logout_result.output == "Successfully logged out of 'testserver:6443'\n" + assert not os.path.exists(os.path.expanduser("~/.codeflare/auth")) + + def test_load_auth(): load_auth() assert sdk_auth.api_client is not None @@ -2299,4 +2317,4 @@ def test_cleanup(): os.remove("test.yaml") os.remove("raytest2.yaml") os.remove("cli-test-cluster.yaml") - os.remove("auth") + os.removedirs(os.path.expanduser("~/.codeflare"))