Skip to content
Merged
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
11 changes: 11 additions & 0 deletions python/lightning_sdk/cli/lockdown.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
"""CLI commands that are temporarily unavailable while the API lockdown is on."""

import os

import rich_click as click

from lightning_sdk.cli.utils.unavailable import mark_temporarily_unavailable, mark_unavailable_groups
from lightning_sdk.lightning_cloud import env

# Unset, empty or truthy keeps the commands in UNAVAILABLE_COMMANDS unavailable. A false value such as 0 runs them.
LOCKDOWN_ENV = "LIGHTNING_CLI_DISABLE_UNAVAILABLE_CMDS"

UNAVAILABLE_COMMANDS: tuple[str, ...] = (
"api deploy",
Expand Down Expand Up @@ -119,9 +125,14 @@ def apply_lockdown(root: click.Group) -> None:
Call this after the commands are registered and before anything else takes a reference
to them, such as the legacy forwards in the entrypoint, so those forwards are marked too.

Does nothing when ``LIGHTNING_CLI_DISABLE_UNAVAILABLE_CMDS`` is set to a false value such as ``0``,
so every command runs as usual. The commands stay unavailable by default.

Raises:
KeyError: If a listed path does not name a command under ``root``.
"""
if not env.truthy(os.getenv(LOCKDOWN_ENV) or "1"):
return
for path in UNAVAILABLE_COMMANDS:
*parents, name = path.split()
group: click.Group = root
Expand Down
24 changes: 23 additions & 1 deletion python/tests/cli/test_temporarily_unavailable.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import rich_click as click
from click.testing import CliRunner

from lightning_sdk.cli import lockdown
from lightning_sdk.cli.entrypoint import main_cli
from lightning_sdk.cli.lockdown import UNAVAILABLE_COMMANDS
from lightning_sdk.cli.lockdown import LOCKDOWN_ENV, UNAVAILABLE_COMMANDS, apply_lockdown
from lightning_sdk.cli.utils.unavailable import is_temporarily_unavailable, mark_temporarily_unavailable
from lightning_sdk.exceptions import RECOVERY_URL, TemporarilyUnavailableError
from tests.cli.help import command_text
Expand Down Expand Up @@ -196,3 +197,24 @@ def test_legacy_forwards_to_unavailable_commands_refuse_to_run(args: list[str])

assert result.exit_code == 1
assert _NOTICE in result.output


@pytest.mark.parametrize(
("value", "locked"),
[(None, True), ("", True), ("1", True), ("true", True), ("0", False), ("false", False)],
)
def test_lockdown_env_controls_the_gate(monkeypatch, value: str | None, locked: bool) -> None:
if value is None:
monkeypatch.delenv(LOCKDOWN_ENV, raising=False)
else:
monkeypatch.setenv(LOCKDOWN_ENV, value)
monkeypatch.setattr(lockdown, "UNAVAILABLE_COMMANDS", ("echo-thing",))
root = click.Group("root")
root.add_command(_echo)

apply_lockdown(root)

assert is_temporarily_unavailable(root.commands["echo-thing"]) is locked
if not locked:
result = CliRunner().invoke(root, ["echo-thing", "--name", "a"], catch_exceptions=False)
assert result.output == "hello a\n"
Loading