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 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 list(ctx, organization, project, deck, **kwargs): """List all apps.""" cluster_data, deck = get_deck_from_arguments(ctx, organization, project, deck) # get cluster cluster = get_cluster_or_exit(ctx, cluster_data.id) provider_data = cluster.storage.get() # list k8s = KubeAPI(provider_data, deck) pod_table = [] def _ready_ind(c) -> Tuple[bool, str]: # get container count if c is None: container_count = 0 ready_count = 0 else: container_count = len(c) ready_count = sum([val.ready for val in c]) return container_count == ready_count, f"{ready_count}/{container_count}" for pod in k8s.get_pods().items: if pod.status.phase in ["Terminating", "Evicted", "Pending"]: continue all_ready, count = _ready_ind(pod.status.container_statuses) pod_table.append( OrderedDict({ "name": pod.metadata.name, "ready": count, "state": "Ok" if all_ready else "Not Ok", "age": age_from_timestamp( pod.metadata.creation_timestamp.timestamp()), })) console.table( data=pod_table, headers={ "name": "Name", "ready": "Ready", "state": "State", "age": "Age", }, )
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 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 ingress(ctx, organization=None, project=None, deck=None, **kwargs): """ Display ingress configuration for *installed* decks. This command prints a table containing URLs, paths and the associated backends. """ # 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 deck = get_deck(ctx, deck_id=deck_id) # get cluster cluster = get_cluster(ctx=ctx, deck=deck) provider_data = cluster.storage.get() ingress_data = get_ingress_data(deck, provider_data) console.table( ingress_data, headers={ "name": "Name", "url": "URLs" }, ) if not ingress_data: console.warning( f"Are you sure the deck is installed? You may have to run 'unikube deck install {deck['title']}' first." )
def verify(verbose): """ Verifies the installation of dependencies on your local machine. If you need a verbose tabular output, please add the ``--verbose`` flag to the command. """ compare_current_and_latest_versions() report_data = probe_dependencies(silent=verbose) unsuccessful = list(filter(lambda x: not x["success"], report_data)) # show detailed table if verbose: successful = list(filter(lambda x: x["success"], report_data)) console.table( successful + unsuccessful, headers={ "name": "Name", "success": "Ok", "required_version": "Required Version", "installed_version": "Installed Version", "msg": "Message", }, ) if unsuccessful: console.error( f"There {'is' if len(unsuccessful) == 1 else 'are'} {len(unsuccessful)} (of {len(report_data)}) " f"unsuccessfully probed {'dependency' if len(unsuccessful) == 1 else 'dependencies'} on your " f"local machine. Please run 'unikube system install' in order to fix " f"these issues." ) return False console.success("Local dependencies verified.") return True
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 env(ctx, app, init, organization, project, deck, **kwargs): """ Display the environment variables for the given app. This prints the environment variables for all containers. You can print the environment variables for all init containers with the ``-i`` flag. """ cluster_data, deck = get_deck_from_arguments(ctx, organization, project, deck) # get cluster cluster = get_cluster_or_exit(ctx, cluster_data.id) provider_data = cluster.storage.get() # env k8s = KubeAPI(provider_data, deck) app = argument_app(k8s, app) # get the data of the selected pod data = k8s.get_pod(app) if init: containers = data.spec.init_containers else: containers = data.spec.containers if containers: console.info(f"This app runs {len(containers)} container(s).") for idx, container in enumerate(containers): console.info(f"Container {idx + 1}: {container.image}") env_vars = [] def _value_from(s) -> Tuple[str, str]: # return an indicator if this values comes from a secret and the name if s.config_map_key_ref: return "ConfigMap", s.config_map_key_ref elif s.field_ref and s.field_ref.field_path: return "Field", s.field_ref.field_path elif s.resource_field_ref: return "ResourceField", s.resource_field_ref elif s.secret_key_ref and s.secret_key_ref.name: return "Secret", f"Secret: {s.secret_key_ref.name} Key: {s.secret_key_ref.key}" if container.env: for env in container.env: if env.value_from: type, source = _value_from(env.value_from) else: type, source = "Definition", "-" env_vars.append( OrderedDict({ "name": env.name, "value": str(env.value[:50]) + "..." if env.value and len(env.value) > 50 else env.value, "source_type": type, "path": source, })) if container.env_from: for env in container.env_from: if env.config_map_ref: _cm = k8s.get_configmap(env.config_map_ref.name) if _cm.data: for k, v in _cm.data.items(): env_vars.append( OrderedDict({ "name": k, "value": str(v[:50]) + "..." if v and len(v) > 50 else v, "source_type": "ConfigMap", "path": _cm.metadata.name, })) console.table( env_vars, headers={ "name": "Name", "value": "Value", "path": "Path", "source_type": "Source Type", }, ) else: console.info("No container running")
def info(ctx, app, organization, project, deck, **kwargs): """Display the status for the given app name.""" cluster_data, deck = get_deck_from_arguments(ctx, organization, project, deck) # get cluster cluster = get_cluster_or_exit(ctx, cluster_data.id) provider_data = cluster.storage.get() # shell k8s = KubeAPI(provider_data, deck) app = argument_app(k8s, app) # get the data of the selected pod data = k8s.get_pod(app) pod_status = data.status console.info( f"This app runs {len(pod_status.container_statuses)} container(s).") for idx, status in enumerate(pod_status.container_statuses): console.info(f"Container {idx + 1}: {status.image}") print("\nStartup command from workload manifest:") console.table([ ("Command", " ".join(data.spec.containers[idx].command) if data.spec.containers[idx].command else None), ("Args", " ".join(data.spec.containers[idx].args) if data.spec.containers[idx].args else None), ]) print("\nApp status:") console.table([ { "State": "Running", "Value": status.state.running.started_at if status.state.running else None }, { "State": "Terminated", "Value": status.state.terminated.finished_at if status.state.terminated else None, }, { "State": "Waiting", "Value": status.state.waiting.message if status.state.waiting else None }, ]) conditions = [] for condition in pod_status.conditions: conditions.append( OrderedDict({ "type": condition.type, "status": condition.status, "reason": condition.reason, "last_transition_time": condition.last_transition_time, "last_probe_time": condition.last_probe_time, "message": condition.message, })) if conditions: conditions = sorted( conditions, key=lambda x: x.get("last_transition_time").timestamp()) # print a line for padding on the console print() console.info("All conditions for this app:") console.table( conditions, headers={ "type": "Type", "status": "Status", "reason": "Reason", "last_transition_time": "Time", "last_probe_time": "Probe Time", "message": "Message", }, ) else: console.info("No condition to display")
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)
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 install(ctx, organization=None, project=None, deck=None, **kwargs): """ Install a deck. For further information please refer to :ref:` """ # 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 deck = get_deck(ctx, deck_id=deck_id) # cluster cluster = get_cluster(ctx=ctx, deck=deck) # check environment type check_environment_type_local_or_exit(deck=deck) # check for switched app provider_data = cluster.storage.get() telepresence = Telepresence(provider_data) if telepresence.intercept_count(): console.error( "It is not possible to install a deck while having an active switch.", _exit=True) # download manifest general_data = ctx.storage_general.get() manifest = download_manifest( deck=deck, authentication=ctx.auth, access_token=general_data.authentication.access_token) # KubeCtl provider_data = cluster.storage.get() kubectl = KubeCtl(provider_data=provider_data) namespace = deck["environment"][0]["namespace"] kubectl.create_namespace(namespace) with click.progressbar( manifest, label="[INFO] Installing Kubernetes resources to the cluster.", ) as files: for file in files: kubectl.apply_str(namespace, file["content"]) # ingress ingress_data = get_ingress_data(deck, provider_data) if not ingress_data: console.info("No ingress configuration available.", _exit=True) console.table( ingress_data, headers={ "name": "Name", "url": "URLs", "paths": "Paths" }, )