Beispiel #1
0
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.")
Beispiel #2
0
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.")
Beispiel #3
0
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",
        },
    )
Beispiel #4
0
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.")
Beispiel #5
0
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"],
    )
Beispiel #6
0
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."
        )
Beispiel #7
0
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
Beispiel #8
0
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",
        },
    )
Beispiel #9
0
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")
Beispiel #10
0
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")
Beispiel #11
0
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)
Beispiel #12
0
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)
Beispiel #13
0
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"
        },
    )