diff --git a/src/codeflare_sdk/cluster/auth.py b/src/codeflare_sdk/cluster/auth.py new file mode 100644 index 000000000..8d985eceb --- /dev/null +++ b/src/codeflare_sdk/cluster/auth.py @@ -0,0 +1,111 @@ +# Copyright 2022 IBM, Red Hat +# +# 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. + +""" +The auth sub-module contains the definitions for the Authentication objects, which represent +the methods by which a user can authenticate to their cluster(s). The abstract class, `Authentication`, +contains two required methods `login()` and `logout()`. Users can use one of the existing concrete classes to +authenticate to their cluster or add their own custom concrete classes here. +""" + +import abc +import openshift as oc + + +class Authentication(metaclass=abc.ABCMeta): + """ + An abstract class that defines the necessary methods for authenticating to a remote environment. + Specifically, this class defines the need for a `login()` and a `logout()` function. + """ + + def login(self): + """ + Method for logging in to a remote cluster. + """ + pass + + def logout(self): + """ + Method for logging out of the remote cluster. + """ + pass + + +class TokenAuthentication(Authentication): + """ + `TokenAuthentication` is a subclass of `Authentication`. It can be used to authenticate to an OpenShift + cluster when the user has an API token and the API server address. + """ + + def __init__( + self, + token: str = None, + server: str = None, + ): + """ + Initialize a TokenAuthentication object that requires a value for `token`, the API Token + and `server`, the API server address for authenticating to an OpenShift cluster. + """ + + self.token = token + self.server = server + + def login(self): + """ + This function is used to login to an OpenShift cluster using the user's API token and API server address. + """ + token = self.token + server = self.server + response = oc.invoke("login", [f"--token={token}", f"--server={server}:6443"]) + return response.out() + + def logout(self): + """ + This function is used to logout of an OpenShift cluster. + """ + response = oc.invoke("logout") + return response.out() + + +class PasswordUserAuthentication(Authentication): + """ + `PasswordUserAuthentication` is a subclass of `Authentication`. It can be used to authenticate to an OpenShift + cluster when the user has a username and password. + """ + + def __init__( + self, + username: str = None, + password: str = None, + ): + """ + Initialize a PasswordUserAuthentication object that requires a value for `username` + and `password` for authenticating to an OpenShift cluster. + """ + self.username = username + self.password = password + + def login(self): + """ + This function is used to login to an OpenShift cluster using the user's `username` and `password`. + """ + response = oc.login(self.username, self.password) + return response.out() + + def logout(self): + """ + This function is used to logout of an OpenShift cluster. + """ + response = oc.invoke("logout") + return response.out() diff --git a/src/codeflare_sdk/cluster/cluster.py b/src/codeflare_sdk/cluster/cluster.py index acf2f4dd0..2eb8b5f10 100644 --- a/src/codeflare_sdk/cluster/cluster.py +++ b/src/codeflare_sdk/cluster/cluster.py @@ -94,6 +94,7 @@ def up(self): Applies the AppWrapper yaml, pushing the resource request onto the MCAD queue. """ + self.config.auth.login() namespace = self.config.namespace with oc.project(namespace): oc.invoke("apply", ["-f", self.app_wrapper_yaml]) @@ -106,6 +107,7 @@ def down(self): namespace = self.config.namespace with oc.project(namespace): oc.invoke("delete", ["AppWrapper", self.app_wrapper_name]) + self.config.auth.logout() def status(self, print_to_console: bool = True): """ diff --git a/src/codeflare_sdk/cluster/config.py b/src/codeflare_sdk/cluster/config.py index 6377ee72c..2456ea8d5 100644 --- a/src/codeflare_sdk/cluster/config.py +++ b/src/codeflare_sdk/cluster/config.py @@ -19,6 +19,7 @@ """ from dataclasses import dataclass, field +from .auth import Authentication import pathlib dir = pathlib.Path(__file__).parent.parent.resolve() @@ -46,3 +47,4 @@ class ClusterConfiguration: instascale: bool = False envs: dict = field(default_factory=dict) image: str = "ghcr.io/ibm-ai-foundation/base:ray1.13.0-py38-gpu-pytorch1.12.0cu116-20220826-202124" + auth: Authentication = Authentication()