Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions playbooks/tasks/configure_operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,7 @@
--name "{{ operator.name }}" \
--version "{{ operator.version }}" \
--namespace "{{ operator.namespace }}" \
{% for csv in (operator.csvNames | default([operator.name])) %}--csv-name "{{ csv }}" {% endfor %}\
--no-dry-run
{% for csv in (operator.csvNames | default([operator.name])) %}--csv-name "{{ csv }}" {% endfor %}
register: operator_update_result

- name: Print the output
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ preview = true
"src/tests/fixtures.py" = [
"ANN401", # anymarkup.parse returns Any; no tighter type available
]
"src/enclave/utils.py" = [
"ANN401", # HelpGroup mirrors click.Group's *args/**kwargs interface
]

[tool.ruff.lint.isort]
combine-as-imports = true
Expand Down
11 changes: 8 additions & 3 deletions src/enclave/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@

from enclave.reconcile.cli import cli as reconcile_cli
from enclave.tools.cli import cli as tools_cli
from enclave.utils import LOG_LEVELS, configure_logging
from enclave.utils import LOG_LEVELS, HelpGroup, configure_logging


@click.group()
@click.group(cls=HelpGroup)
@click.option(
"--log-level",
"-l",
default="INFO",
type=click.Choice(LOG_LEVELS, case_sensitive=False),
help="Set the logging level.",
)
def cli(log_level: str) -> None:
"""Enclave CLI."""
"""Management CLI for Red Hat Sovereign Enclave (RHSE).

Provides subcommands for reconciling cluster state and running
operational tools against the management cluster.
"""
configure_logging(log_level)


Expand Down
46 changes: 37 additions & 9 deletions src/enclave/reconcile/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
reconcile as cluster_upgrade_reconcile,
)
from enclave.reconcile.operator_versions import reconcile as operator_versions_reconcile
from enclave.utils import LOG_LEVELS, configure_logging
from enclave.utils import LOG_LEVELS, HelpGroup, configure_logging


def defaults_path(filename: str) -> Path:
Expand All @@ -22,36 +22,49 @@ def defaults_path(filename: str) -> Path:
return path


@click.group()
@click.group(cls=HelpGroup)
@click.option(
"--log-level",
"-l",
default="INFO",
type=click.Choice(LOG_LEVELS, case_sensitive=False),
help="Set the logging level.",
)
def cli(log_level: str) -> None:
"""Reconcile CLI."""
"""Reconcile management cluster state against desired configuration.

Commands compare the current cluster state with expected values
and apply changes to bring them in sync.
"""
# Configure logging only if not already configured by the parent enclave CLI
configure_logging(log_level)


@cli.command()
@click.option("--name", help="Operator package name")
@click.option("--version", help="Operator version")
@click.option("--namespace", help="Operator namespace")
@click.option("--name", "-n", help="Operator package name")
@click.option("--version", "-v", help="Operator version")
@click.option("--namespace", "-N", help="Operator namespace")
@click.option(
"--csv-name",
"-c",
"csv_names",
multiple=True,
help="CSV name(s); defaults to operator name if omitted",
)
@click.option(
"--use-defaults",
"-u",
is_flag=True,
default=False,
help="Load all operators from defaults/operators.yaml (mutually exclusive with --name, --version, --namespace, --csv-name)",
)
@click.option("--dry-run/--no-dry-run", default=False)
@click.option(
"--dry-run",
"-d",
is_flag=True,
default=False,
help="Print what would be done without applying any changes.",
)
def operator_versions(
name: str,
version: str,
Expand All @@ -60,6 +73,7 @@ def operator_versions(
use_defaults: bool,
dry_run: bool,
) -> None:
"""Reconcile operator CSV versions on the management cluster."""
if use_defaults and any([name, version, namespace, csv_names]):
raise click.UsageError(
"--use-defaults is mutually exclusive with --name, --version, --namespace, --csv-name"
Expand Down Expand Up @@ -100,23 +114,32 @@ def operator_versions(

@cli.command()
@click.option(
"--version", "version", default=None, help="OpenShift version to upgrade to"
"--version", "-v", "version", default=None, help="OpenShift version to upgrade to"
)
@click.option(
"--use-defaults",
"-u",
is_flag=True,
default=False,
help="Load the default version from defaults/platforms.yaml (mutually exclusive with --version)",
)
@click.option("--dry-run/--no-dry-run", default=False)
@click.option(
"--dry-run",
"-d",
is_flag=True,
default=False,
help="Print what would be done without applying any changes.",
)
@click.option(
"--timeout-minutes",
"-t",
default=180,
type=click.IntRange(min=1),
help="Timeout for waiting operations in minutes (default: 180 = 3 hours)",
)
@click.option(
"--sleep-interval",
"-s",
default=60,
type=click.IntRange(min=1),
help="Sleep interval between polling attempts in seconds (default: 60)",
Expand All @@ -128,6 +151,11 @@ def mgmt_cluster_version(
timeout_minutes: int,
sleep_interval: int,
) -> None:
"""Reconcile the management cluster's OpenShift version.

Triggers an upgrade if the cluster is not already at the target
version, then waits for the rollout to complete.
"""
if use_defaults and version:
raise click.UsageError("--use-defaults is mutually exclusive with --version")

Expand Down
11 changes: 7 additions & 4 deletions src/enclave/tools/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@

from enclave.tools.node_image_digests import main as collect_node_image_digests_main
from enclave.tools.quay_registry_ca import main as quay_registry_ca_main
from enclave.utils import HelpGroup


@click.group()
@click.group(cls=HelpGroup)
def cli() -> None:
"""Enclave tools CLI."""
"""Utility tools for enclave operations."""


@cli.command("resolve-quay-registry-ca")
@click.option("--hostname", required=True, help="Quay registry route hostname.")
@click.option("--hostname", "-H", required=True, help="Quay registry route hostname.")
@click.option(
"--oc",
default="oc",
Expand All @@ -26,7 +27,7 @@ def resolve_quay_registry_ca(hostname: str, oc: str) -> None:


@cli.command("collect-node-image-digests")
@click.option("--node", required=True, help="Node name.")
@click.option("--node", "-n", required=True, help="Node name.")
@click.option(
"--oc",
default="oc",
Expand All @@ -35,11 +36,13 @@ def resolve_quay_registry_ca(hostname: str, oc: str) -> None:
)
@click.option(
"--exclude-contains",
"-e",
default=None,
help="JSON array of substrings; matching digest refs are skipped.",
)
@click.option(
"--raw-output-file",
"-r",
default=None,
help="File path for raw oc debug/crictl output when no digest refs are collected.",
)
Expand Down
20 changes: 20 additions & 0 deletions src/enclave/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,30 @@
import subprocess
import sys
import time
from typing import Any

import click

logger = logging.getLogger(__name__)

LOG_LEVELS = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
_HELP_CONTEXT = {"help_option_names": ["-h", "--help"]}


class HelpGroup(click.Group):
"""click.Group that propagates -h/--help to every subcommand automatically."""

def __init__(self, *args: Any, **kwargs: Any) -> None:
kwargs.setdefault("context_settings", _HELP_CONTEXT)
super().__init__(*args, **kwargs)

def command(self, *args: Any, **kwargs: Any) -> Any:
kwargs.setdefault("context_settings", _HELP_CONTEXT)
return super().command(*args, **kwargs)

def group(self, *args: Any, **kwargs: Any) -> Any:
kwargs.setdefault("context_settings", _HELP_CONTEXT)
return super().group(*args, **kwargs)


def configure_logging(log_level: str) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
def test_cli_help() -> None:
result = CliRunner().invoke(cli, ["--help"])
assert result.exit_code == 0
assert "Reconcile CLI" in result.output
assert "Reconcile management cluster state" in result.output
assert "resolve-quay-registry-ca" not in result.output
assert "collect-node-image-digests" not in result.output

Expand Down
2 changes: 1 addition & 1 deletion src/tests/test_tools_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
def test_tools_cli_help() -> None:
result = CliRunner().invoke(cli, ["--help"])
assert result.exit_code == 0
assert "Enclave tools CLI" in result.output
assert "Utility tools for enclave operations" in result.output


def test_resolve_quay_registry_ca_help() -> None:
Expand Down
Loading