def get_deck(ctx, deck_id: str): # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($id: UUID) { deck(id: $id) { id title environment { id type valuesPath namespace } project { id title organization { title } } } } """, query_variables={"id": deck_id}, ) deck = data["deck"] except Exception as e: console.debug(e) console.exit_generic_error() return deck
def compare_current_and_latest_versions(): try: current_version = None try: path = Path(__file__).parent / "../VERSION" with path.open("r") as f: current_version = f.read() except (FileNotFoundError, PermissionError): console.debug("Could not read current version.") if not current_version: dist = pkg_resources.working_set.by_key.get("unikube") if dist: current_version = dist.version release = requests.get("https://api.github.com/repos/unikubehq/cli/releases/latest") if release.status_code == 403: console.info("Versions cannot be compared, as API rate limit was exceeded") return None latest_release_version = release.json()["tag_name"].replace("-", ".") if current_version != latest_release_version: console.info( f"You are using unikube version {current_version}; however, version {latest_release_version} is " f"available." ) return current_version except pkg_resources.DistributionNotFound as e: console.warning(f"Version of the package could not be found: {e}") except Exception: import traceback console.info(f"Versions cannot be compared, because of error {traceback.format_exc()}")
def organization_list(ctx) -> Union[None, str]: # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query(""" query { allOrganizations { results { id title } } } """) organization_list = data["allOrganizations"]["results"] except Exception as e: console.debug(e) console.exit_generic_error() selection = console.list( message="Please select an organization", choices=[organization["title"] for organization in organization_list], identifiers=[organization["id"] for organization in organization_list], message_no_choices="No organizations available!", ) if selection is None: return None # get identifier if available organization_argument = get_identifier_or_pass(selection) organization_id = convert_organization_argument_to_uuid( ctx.auth, argument_value=organization_argument) return organization_id
def info(ctx, project=None, organization=None, **kwargs): """ Displays the id, title and optional description of the selected project. """ _ = ctx.auth.refresh() # context organization_id, project_id, _ = ctx.context.get_context_ids_from_arguments( organization_argument=organization, project_argument=project) # argument if not project_id: project_id = console.project_list(ctx, organization_id=organization_id) if not project_id: return None # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($id: UUID!) { project(id: $id) { id title description specRepository specRepositoryBranch organization { title } } } """, query_variables={"id": project_id}, ) project_selected = data["project"] except Exception as e: console.debug(e) console.exit_generic_error() # console if project_selected: project_selected["organization"] = project_selected.pop( "organization").get("title", "-") project_selected["repository"] = project_selected.pop("specRepository") project_selected["repository branch"] = project_selected.pop( "specRepositoryBranch") console.table( data={ "key": [k for k in project_selected.keys()], "value": [v for v in project_selected.values()], }, headers=["Key", "Value"], ) else: console.error("Project does not exist.")
def environment_type_from_string(environment_type: str): try: environment_type = EnvironmentType(environment_type) except Exception as e: console.debug(e) environment_type = None return environment_type
def __request( self, url, data, message_exception, message_200, message_400, message_500, headers=None, ) -> dict: # request try: req = requests.post( url, data, headers=headers, timeout=self.timeout, ) except Exception as e: console.debug(e) return { "success": False, "message": message_exception, "response": None, } # return if req.status_code == 200: success = True message = message_200 elif req.status_code in [400, 401, 404]: success = False message = message_400 elif req.status_code in [500, 501, 502, 503]: success = False message = message_500 else: success = False message = "" # get json response try: response = req.json() except Exception: response = None return { "success": success, "message": message, "response": response, }
def uninstall(self, deployment, namespace=None, silent=False): arguments = ["uninstall", "--agent", deployment] arguments.append(deployment) if namespace: arguments += ["-n", namespace] console.debug(arguments) process = self._execute(arguments) if not silent and process.returncode and process.returncode != 0: console.error( "There was an error with uninstalling the traffic agent, please find details above", _exit=False)
def get_deck_from_arguments(ctx, organization_id: str, project_id: str, deck_id: str): # context organization_id, project_id, deck_id = ctx.context.get_context_ids_from_arguments( organization_argument=organization_id, project_argument=project_id, deck_argument=deck_id) # argument if not deck_id: deck_id = console.deck_list(ctx, organization_id=organization_id, project_id=project_id) if not deck_id: exit(1) # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($id: UUID) { deck(id: $id) { id title environment { namespace } project { id } } } """, query_variables={"id": deck_id}, ) deck = data["deck"] project_id = deck["project"]["id"] except Exception as e: console.debug(e) console.exit_generic_error() # cluster data cluster_list = ctx.cluster_manager.get_cluster_list(ready=True) if project_id not in [cluster.id for cluster in cluster_list]: console.info( f"The project cluster for '{project_id}' is not up or does not exist yet.", _exit=True) cluster_data = ctx.cluster_manager.get(id=project_id) if not cluster_data: console.error("The cluster could not be found.", _exit=True) return cluster_data, deck
def prune(ctx, **kwargs): """ Remove unused clusters. """ # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query(""" query { allProjects { results { id } } } """) projects = data["allProjects"]["results"] except Exception as e: console.debug(e) console.exit_generic_error() # cluster cluster_list = ctx.cluster_manager.get_cluster_list() # select clusters to prune prune_clusters = [] for cluster_data in cluster_list: if cluster_data.id not in [project["id"] for project in projects]: prune_clusters.append(cluster_data) for cluster_data in prune_clusters: console.info( f"It seems like the project for cluster '{cluster_data.name}' has been deleted." ) # confirm question confirmed = console.confirm( question="Do want to remove the cluster? [N/y]: ") if not confirmed: console.info("No action taken.") continue # delete try: cluster = ctx.cluster_manager.select(cluster_data=cluster_data) success = cluster.delete() if success: console.success("The project was deleted successfully.") ctx.cluster_manager.delete(cluster.id) except Exception as e: console.debug(e) console.error("The cluster could not be deleted.")
def project_list(ctx, organization_id: str = None, filter: List[str] = None, excludes: List[str] = None) -> Union[None, str]: # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($organization_id: UUID) { allProjects(organizationId: $organization_id) { results { title id organization { id title } } } } """, query_variables={ "organization_id": organization_id, }, ) project_list = data["allProjects"]["results"] except Exception as e: console.debug(e) console.exit_generic_error() selection = console.list( message="Please select a project", choices=[project["title"] for project in project_list], identifiers=[project["id"] for project in project_list], filter=filter, excludes=excludes, help_texts=[ project["organization"]["title"] for project in project_list ], message_no_choices="No projects available!", ) if selection is None: return None # get identifier if available project_argument = get_identifier_or_pass(selection) project_id = convert_project_argument_to_uuid( ctx.auth, argument_value=project_argument, organization_id=organization_id) return project_id
def leave(self, deployment, namespace=None, silent=False): arguments = ["leave", "--no-report"] if namespace: arguments.append(f"{deployment}-{namespace}") else: arguments.append(deployment) console.debug(arguments) process = self._execute(arguments) if not silent and process.returncode and process.returncode != 0: console.error( "There was an error with leaving the deployment, please find details above", _exit=False)
def deck_list(ctx, organization_id: str = None, project_id: str = None) -> Union[None, str]: # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($organization_id: UUID, $project_id: UUID) { allDecks(organizationId: $organization_id, projectId: $project_id) { results { title id project { id title organization { id } } } } } """, query_variables={ "organization_id": organization_id, "project_id": project_id, }, ) deck_list = data["allDecks"]["results"] except Exception as e: console.debug(e) console.exit_generic_error() selection = console.list( message="Please select a deck", choices=[deck["title"] for deck in deck_list], identifiers=[deck["id"] for deck in deck_list], help_texts=[deck["project"]["title"] for deck in deck_list], message_no_choices="No decks available!", ) if selection is None: return None # get identifier if available deck_argument = get_identifier_or_pass(selection) deck_id = convert_deck_argument_to_uuid(ctx.auth, argument_value=deck_argument, organization_id=organization_id, project_id=project_id) return deck_id
def info(ctx, organization=None, project=None, deck=None, **kwargs): """ Display further information of the selected deck. """ # context organization_id, project_id, deck_id = ctx.context.get_context_ids_from_arguments( organization_argument=organization, project_argument=project, deck_argument=deck) # argument if not deck_id: deck_id = console.deck_list(ctx, organization_id=organization_id, project_id=project_id) if not deck_id: return None # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($id: UUID) { deck(id: $id) { id title description namespace type } } """, query_variables={"id": deck_id}, ) deck_selected = data["deck"] except Exception as e: console.debug(e) console.exit_generic_error() # console if deck_selected: console.table( data={ "key": [k for k in deck_selected.keys()], "value": [v for v in deck_selected.values()], }, headers=["Key", "Value"], ) else: console.error("Deck does not exist.")
def _decode_requesting_party_token(self, requesting_party_token: str) -> dict: # decode try: token = jwt.decode( requesting_party_token, algorithms=["RS256"], audience=settings.TOKEN_AUDIENCE, options={"verify_signature": False}, ) except Exception as e: console.debug(e) raise Exception("Requesting Party Token (RPT) could not be decoded.") return token
def swap(self, deployment, image_name, command=None, namespace=None, envs=None, mounts=None, port=None): arguments = ["intercept", "--no-report", deployment] if namespace: arguments = arguments + ["--namespace", namespace] arguments = arguments + [ "--port", f"{port}:{port}", "--docker-run", "--" ] if platform.system() != "Darwin": arguments.append("--network=host") arguments += [ f"--dns-search={namespace}", "--rm", ] if mounts: for mount in mounts: arguments = arguments + ["-v", f"{mount[0]}:{mount[1]}"] if envs: for env in envs: arguments = arguments + ["--env", f"{env[0]}={env[1]}"] # this name to be retrieved for "app shell" command arguments = arguments + ["--name", image_name.replace(":", "")] arguments.append(image_name) if command: arguments = arguments + ["sh", "-c"] + [f"{' '.join(command)}"] console.debug(arguments) try: process = self._execute_intercept(arguments) if process.returncode and (process.returncode != 0 and not process.returncode != 137): console.error( "There was an error with switching the deployment, please find details above", _exit=False) except KeyboardInterrupt: pass console.info( "Stopping the switch operation. It takes a few seconds to reset the cluster." ) self.leave(deployment, namespace, silent=True) self.uninstall(deployment, namespace, silent=True)
def verify_or_refresh(self) -> bool: # verify response = self.verify() if response["success"]: return True # refresh response = self.refresh() if response["success"]: return True # exception messsage console.debug(response["message"]) return False
def intercept_count(self) -> Union[int, None]: arguments = ["status"] process = self._execute(arguments) status = process.stdout.readlines() # parse intercept count try: intercept_line = status[15] match = re.findall("[ ]{1,}Intercepts[ ]{1,}:(.*)[ ]{1,}total", intercept_line) intercept_count = int(match[0]) except Exception as e: console.debug(e) intercept_count = None return intercept_count
def list(ctx, organization, **kwargs): """ Display a table of all available project names alongside with the ids. """ _ = ctx.auth.refresh() # context organization_id, _, _ = ctx.context.get_context_ids_from_arguments( organization_argument=organization) # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($organization_id: UUID) { allProjects(organizationId: $organization_id) { results { title id description } } } """, query_variables={"organization_id": organization_id}, ) project_list = data["allProjects"]["results"] except Exception as e: console.debug(e) console.exit_generic_error() # console if len(project_list) < 1: console.info( "No projects available. Please go to https://app.unikube.io and create a project.", _exit=True) console.table( data={ "id": [p["id"] for p in project_list], "title": [p["title"] for p in project_list], "description": [p["description"] for p in project_list], }, headers=["id", "name", "description"], )
def info(ctx, organization, **kwargs): """ Display further information of the selected organization. """ _ = ctx.auth.refresh() # context organization_id, _, _ = ctx.context.get_context_ids_from_arguments(organization_argument=organization) # argument if not organization_id: organization_id = console.organization_list(ctx) if not organization_id: return None # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($id: UUID!) { organization(id: $id) { id title description } } """, query_variables={"id": organization_id}, ) organization_selected = data["organization"] except Exception as e: console.debug(e) console.exit_generic_error() # console if organization_selected: console.table( data={ "key": [k for k in organization_selected.keys()], "value": [v for v in organization_selected.values()], }, headers=["Key", "Value"], ) else: console.error("Organization does not exist.")
def do_POST(self): POST = self.get_post_data() if POST["state"] != state: raise Exception(f"Invalid state: {POST['state']}") response = ctx.auth._get_requesting_party_token( POST["access_token"]) login_file = open( os.path.join(os.path.dirname(os.path.realpath(__file__)), "login.html")) text = login_file.read() login_file.close() # select response if not response["success"]: console.error("Login failed!") text = ( "Login failed! Could not retrieve requesting party token. " "Please try again or contact your System administrator") else: try: token = ctx.auth.token_from_response(response) except Exception as e: console.debug(e) console.debug(response) console.error("Login failed!") text = "Login failed! Your token does not match." else: ctx.auth.general_data.authentication = AuthenticationData( email=token["email"], access_token=response["response"]["access_token"], refresh_token=response["response"]["refresh_token"], requesting_party_token=True, ) ctx.auth.local_storage_general.set(ctx.auth.general_data) if given_name := token.get("given_name", ""): greeting = f"Hello {given_name}!" else: greeting = "Hello!"
def password_flow(ctx, email, password): response = ctx.auth.login( email, password, ) if response["success"]: try: token = ctx.auth.token_from_response(response) except Exception as e: console.debug(e) console.debug(response) console.error("Login failed. Your token does not match.") return False if token["given_name"]: console.success(f'Login successful. Hello {token["given_name"]}!') else: console.success("Login successful.") else: console.error("Login failed. Please check email and password.") return True
def get(self) -> ContextData: context = ContextData() for context_object in self.context_order: # get context variables from current context try: context_current = context_object.get(current_context=context) except Exception as e: console.debug(e) context_current = ContextData() # update context context_dict = context.dict() for key, value in context_current.dict().items(): if context_dict[key] is None: context_dict[key] = value context = ContextData(**context_dict) # check if all context variables have already been set if None not in context.dict().values(): break return context
def list(ctx, **kwargs): """ List all your organizations. """ _ = ctx.auth.refresh() context = ctx.context.get() # keycloak try: keycloak_permissions = KeycloakPermissions(authentication=ctx.auth) permission_list = keycloak_permissions.get_permissions_by_scope("organization:*") except Exception as e: console.debug(e) console.exit_generic_error() # append "(active)" if context.organization_id: for permission in permission_list: if permission.rsid == context.organization_id: permission.rsid += " (active)" # console organization_list = [ { "id": permission.rsid, "name": permission.rsname.replace("organization ", ""), } for permission in permission_list ] console.table( data=organization_list, headers={ "id": "id", "name": "name", }, )
def organization_id_2_display_name(ctx, id: str = None) -> str: if not id: return "-" try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($id: UUID!) { organization(id: $id) { title } } """, query_variables={ "id": id, }, ) title = data["organization"]["title"] except Exception as e: console.debug(e) title = "-" return f"{title} ({id})"
def select( self, cluster_data: K8sProviderData, cluster_provider_type: K8sProviderType = settings. UNIKUBE_DEFAULT_PROVIDER_TYPE, ) -> Union[AbstractK8sProvider, None]: # create config config = { "id": cluster_data.id, } if cluster_data.name: config["name"] = cluster_data.name # get selected kubernetes cluster from factory try: kubernetes_cluster = kubernetes_cluster_factory.get( cluster_provider_type, **config, ) return kubernetes_cluster except Exception as e: console.debug(e) return None
def list(ctx, organization=None, project=None, **kwargs): """ List all decks. """ # context organization_id, project_id, _ = ctx.context.get_context_ids_from_arguments( organization_argument=organization, project_argument=project) # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($organization_id: UUID, $project_id: UUID) { allDecks(organizationId: $organization_id, projectId: $project_id) { results { id title project { title organization { title } } } } } """, query_variables={ "organization_id": organization_id, "project_id": project_id, }, ) deck_list = data["allDecks"]["results"] except Exception as e: console.debug(e) console.exit_generic_error() if not deck_list: console.warning( "No decks available. Please go to https://app.unikube.io and create a project.", _exit=True) # format list to table table_data = [] for deck in deck_list: data = {} if not organization_id: data["organization"] = deck["project"]["organization"]["title"] if not project_id: data["project"] = deck["project"]["title"] data["id"] = deck["id"] data["title"] = deck["title"] table_data.append(data) # console console.table(data=table_data)
def switch(ctx, app, organization, project, deck, deployment, unikubefile: str = None, no_build: bool = False, **kwargs): """ Switch a running deployment with a local Docker container. """ cluster_data, deck = get_deck_from_arguments(ctx, organization, project, deck) # get cluster cluster = get_cluster_or_exit(ctx, cluster_data.id) # unikube file input try: unikube_file = unikube_file_selector.get(path_unikube_file=unikubefile) unikube_file_app = unikube_file.get_app(name=app) except Exception as e: console.debug(e) console.error("Invalid 'app' argument.", _exit=True) # 2: Get a deployment # 2.1.a Check the deployment identifier if not deployment and unikube_file_app: # 1.1.b check the unikubefile deployment = unikube_file_app.get_deployment() if not deployment: console.error( "Please specify the 'deployment' key of your app in your unikube.yaml.", _exit=True) else: console.error( "Please specify the deployment either using the '--deployment' option or in the unikube.yaml. " "Run 'unikube app switch' in a directory containing the unikube.yaml file.", _exit=True, ) # 2.2 Fetch available "deployment:", deployments # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($id: UUID) { deck(id: $id) { deployments(level: "local") { id title description ports isSwitchable } environment { id type valuesPath namespace } } } """, query_variables={ "id": deck["id"], }, ) except Exception as e: console.debug(e) console.exit_generic_error() target_deployment = None for _deployment in data["deck"]["deployments"]: if _deployment["title"] == deployment: target_deployment = _deployment # 2.3 Check and select deployment data if target_deployment is None: console.error( f"The deployment '{deployment}' you specified could not be found.", _exit=True, ) ports = target_deployment["ports"].split(",") deployment = target_deployment["title"] namespace = deck["environment"][0]["namespace"] console.info("Please wait while unikube prepares the switch.") with click_spinner.spinner(beep=False, disable=False, force=False, stream=sys.stdout): # check telepresence provider_data = cluster.storage.get() telepresence = Telepresence(provider_data) available_deployments = telepresence.list(namespace, flat=True) if deployment not in available_deployments: console.error( "The given deployment cannot be switched. " f"You may have to run 'unikube deck install {deck}' first.", _exit=True, ) is_swapped = telepresence.is_swapped(deployment, namespace) k8s = KubeAPI(provider_data, deck) # service account token, service cert service_account_tokens = k8s.get_serviceaccount_tokens(deployment) # 3: Build an new Docker image # 3.1 Grab the docker file context, dockerfile, target = unikube_file_app.get_docker_build() if not target: target = "" console.debug(f"{context}, {dockerfile}, {target}") # 3.2 Set an image name image_name = settings.TELEPRESENCE_DOCKER_IMAGE_FORMAT.format( project=cluster_data.name.replace(" ", "").lower(), deck=deck["title"], name=deployment) docker = Docker() if is_swapped: console.warning( "It seems this app is already switched in another process. ") if click.confirm("Do you want to kill it and switch here?"): telepresence.leave(deployment, namespace, silent=True) if docker.check_running(image_name): docker.kill(name=image_name) else: sys.exit(0) # 3.3 Build image if not docker.image_exists(image_name) or not no_build: if no_build: console.warning( f"Ignoring --no-build since the required image '{image_name}' does not exist" ) console.info( f"Building a Docker image for {dockerfile} with context {context}") with click_spinner.spinner(beep=False, disable=False, force=False, stream=sys.stdout): status, msg = docker.build(image_name, context, dockerfile, target) if not status: console.debug(msg) console.error("Failed to build Docker image.", _exit=True) console.info(f"Docker image successfully built: {image_name}") # 4. Start the Telepresence session # 4.1 Set the right intercept port port = unikube_file_app.get_port() if port is None: port = str(ports[0]) if len(ports) > 1: console.warning( f"No port specified although there are multiple ports available: {ports}. " f"Defaulting to port {port} which might not be correct.") if port not in ports: console.error( f"The specified port {port} is not in the rage of available options: {ports}", _exit=True) if not _is_local_port_free(port): console.error( f"The local port {port} is busy. Please stop the application running on " f"this port and try again.", _exit=True, ) # 4.2 See if there are volume mounts mounts = unikube_file_app.get_mounts() console.debug(f"Volumes requested: {mounts}") # mount service tokens if service_account_tokens: tmp_sa_token = tempfile.NamedTemporaryFile(delete=True) tmp_sa_cert = tempfile.NamedTemporaryFile(delete=True) tmp_sa_token.write(service_account_tokens[0].encode()) tmp_sa_cert.write(service_account_tokens[1].encode()) tmp_sa_token.flush() tmp_sa_cert.flush() mounts.append((tmp_sa_token.name, settings.SERVICE_TOKEN_FILENAME)) mounts.append((tmp_sa_cert.name, settings.SERVICE_CERT_FILENAME)) else: tmp_sa_token = None tmp_sa_cert = None # 4.3 See if there special env variables envs = unikube_file_app.get_environment() console.debug(f"Envs requested: {envs}") # 4.4 See if there is a run command to be executed command = unikube_file_app.get_command(port=port) console.debug(f"Run command: {command}") console.info( "Starting your container, this may take a while to become effective") telepresence.swap(deployment, image_name, command, namespace, envs, mounts, port) if docker.check_running(image_name): docker.kill(name=image_name) if tmp_sa_token: tmp_sa_token.close() tmp_sa_cert.close()
def up(ctx, project=None, organization=None, ingress=None, provider=None, workers=None, **kwargs): """ This command starts or resumes a Kubernetes cluster for the specified project. As it is a selection command, the project can be specified and/or filtered in several ways: * as a positional argument, id or project title can be specified, or from a set context * as an interactive selection from available projects * via ``-o`` or ``--organization`` option, specifying an organisation to which a project belongs """ _ = ctx.auth.refresh() if not Docker().daemon_active(): console.error( "Docker is not running. Please start Docker before starting a project.", _exit=True) # context organization_id, project_id, _ = ctx.context.get_context_ids_from_arguments( organization_argument=organization, project_argument=project) # cluster information cluster_list = ctx.cluster_manager.get_cluster_list(ready=True) cluster_id_list = [item.id for item in cluster_list] # argument if not project_id: project_id = console.project_list(ctx, organization_id=organization_id, excludes=cluster_id_list) if not project_id: return None if project_id in cluster_id_list: console.info( f"Project '{project_id_2_display_name(ctx=ctx, id=project_id)}' is already up.", _exit=True) # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query($id: UUID) { project(id: $id) { title id organization { id } clusterSettings { id port } organization { title } } } """, query_variables={ "id": project_id, }, ) project_selected = data["project"] except Exception as e: console.debug(e) console.exit_generic_error() if not project_selected: console.info( f"The project '{project_id_2_display_name(ctx=ctx, id=project_id)}' could not be found.", _exit=True) try: cluster_provider_type = K8sProviderType[provider] except KeyError: console.error( f"The provider '{provider}' is not supported. Please use " f"one of: {','.join(opt.name for opt in K8sProviderType)}", _exit=True, ) check_running_cluster(ctx, cluster_provider_type, project_selected) # get project id if ingress is None: ingress = project_selected["clusterSettings"]["port"] if not_available_ports := check_ports([ingress]): console.error( "Following ports are currently busy, however needed to spin up the cluster: {}" .format(", ".join([str(port) for port in not_available_ports])), _exit=True, )
def ps(ctx, **kwargs): """ Displays the current process state. """ # cluster cluster_list = ctx.cluster_manager.get_cluster_list(ready=True) cluster_id_list = [cluster.id for cluster in cluster_list] # GraphQL try: graph_ql = GraphQL(authentication=ctx.auth) data = graph_ql.query( """ query { allProjects { results { title id description } } } """, ) project_list = data["allProjects"]["results"] except Exception as e: console.debug(e) console.exit_generic_error() cluster_data = [] for project in project_list: if project["id"] in cluster_id_list: cluster_data.append(project) console.info("Project:") console.table( data={ "id": [cluster["id"] for cluster in cluster_data], "title": [cluster["title"] for cluster in cluster_data], "description": [cluster["description"] for cluster in cluster_data], }, headers=["cluster: id", "name", "description"], ) console.echo("") # switch intercept_count = 0 if cluster_data: cluster = get_cluster_or_exit(ctx, cluster_data[0]["id"]) provider_data = cluster.storage.get() telepresence = Telepresence(provider_data) intercept_count = telepresence.intercept_count() if intercept_count == 0 or not intercept_count: console.info("No app switched!") else: console.info(f"Apps switched: #{intercept_count}") console.echo("") # context local_storage_user = get_local_storage_user() user_data = local_storage_user.get() show_context(ctx=ctx, context=user_data.context)