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
80 changes: 76 additions & 4 deletions tests/cli/test_studio_deploy_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,35 @@ def test_renderer_localizes_byteplus_purposes_and_summary(capsys) -> None:
assert permissions.IAM_CONFIG_URLS["byteplus"] in output


def test_cli_stops_before_cloud_writes_when_permission_is_missing(
monkeypatch,
@pytest.mark.parametrize(
("provider_args", "expected_prompt", "expected_message"),
[
(
[
"--volcengine-access-key",
"ak",
"--volcengine-secret-key",
"sk",
],
"是否仍要继续部署?",
"缺少 Studio 部署所需的 IAM 权限",
),
(
[
"--provider",
"byteplus",
"--byteplus-access-key",
"ak",
"--byteplus-secret-key",
"sk",
],
"Continue deployment anyway?",
"required IAM Actions are missing",
),
],
)
def test_cli_stops_before_cloud_writes_when_missing_permission_is_declined(
monkeypatch, provider_args, expected_prompt, expected_message
) -> None:
identity_called = False

Expand All @@ -228,6 +255,47 @@ def _identity(**_kwargs):
_identity,
)

result = CliRunner().invoke(
studio,
[
"deploy",
"--vefaas-app-name",
"studio-test",
*provider_args,
],
input="n\n",
)

assert result.exit_code != 0
assert expected_prompt in result.output
assert expected_message in result.output
assert identity_called is False


def test_cli_continues_when_missing_permission_is_accepted(monkeypatch) -> None:
identity_called = False

def _precheck(*, specs, **_kwargs):
return [
permissions.PermissionResult(spec=spec, satisfied=index != 0)
for index, spec in enumerate(specs)
]

def _identity(**_kwargs):
nonlocal identity_called
identity_called = True
raise RuntimeError("identity provisioning reached")

monkeypatch.setattr(
permissions,
"run_studio_deploy_permission_precheck",
_precheck,
)
monkeypatch.setattr(
"veadk.cli.cli_frontend._resolve_or_create_studio_identity_resources",
_identity,
)

result = CliRunner().invoke(
studio,
[
Expand All @@ -239,11 +307,15 @@ def _identity(**_kwargs):
"--volcengine-secret-key",
"sk",
],
input="y\n",
)

assert result.exit_code != 0
assert "缺少 Studio 部署所需的 IAM 权限" in result.output
assert identity_called is False
assert "是否仍要继续部署?" in result.output
assert "已确认忽略缺失的 IAM 权限,继续部署。" in result.output
assert identity_called is True
assert isinstance(result.exception, RuntimeError)
assert str(result.exception) == "identity provisioning reached"


def test_cli_precheck_only_exits_before_cloud_writes(monkeypatch) -> None:
Expand Down
15 changes: 14 additions & 1 deletion veadk/cli/cli_frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -10853,7 +10853,20 @@ def frontend_deploy(
if provider_id == "byteplus"
else "缺少 Studio 部署所需的 IAM 权限,已在创建云资源前终止。"
)
raise click.ClickException(message)
if precheck_only:
raise click.ClickException(message)
prompt = (
"Some required IAM Actions are missing. Continue deployment anyway?"
if provider_id == "byteplus"
else "部分 Studio 部署所需的 IAM 权限未满足,是否仍要继续部署?"
)
if not click.confirm(prompt, default=False):
raise click.ClickException(message)
click.echo(
"Continuing deployment despite missing IAM Actions."
if provider_id == "byteplus"
else "已确认忽略缺失的 IAM 权限,继续部署。"
)
if precheck_only:
click.echo(
"Pre-check only: no cloud resources were created."
Expand Down
Loading