Skip to content

Commit 670833c

Browse files
fix(studio): support standard credential file (#722)
1 parent ac33649 commit 670833c

5 files changed

Lines changed: 108 additions & 9 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ VeADK provides several useful command line tools for faster deployment and optim
205205
policies; target `cn-beijing` (default) or `cn-shanghai` with
206206
`--region`, automatically locate the Identity user pool across Beijing and
207207
Shanghai, and select the VeFaaS project with `--project` (default `default`);
208+
deployment credentials can come from explicit CLI options, the
209+
`VOLCENGINE_ACCESS_KEY` / `VOLCENGINE_SECRET_KEY` environment variables, or
210+
the `[default]` profile in `~/.volc/credentials`;
208211
Shanghai Functions, gateways, and AgentKit resources stay in Shanghai while
209212
VeFaaS Application operations use its Beijing control-plane endpoint; the
210213
selected region is also used for temporary-chat and Skill-creation sessions;

docs/content/docs/framework/frontend.en.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@ veadk studio deploy \
242242
--vefaas-app-name <app-name>
243243
```
244244

245+
Deployment credentials can be supplied explicitly with
246+
`--volcengine-access-key` / `--volcengine-secret-key`, through the current
247+
process's `VOLCENGINE_ACCESS_KEY` / `VOLCENGINE_SECRET_KEY` environment
248+
variables, or through the `[default]` profile in `~/.volc/credentials` when the
249+
other sources are absent.
250+
245251
### Custom Studio branding
246252

247253
Use `--site-title` for a system name of up to six characters and `--site-logo`

docs/content/docs/framework/frontend.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ veadk studio deploy \
204204
--vefaas-app-name <app-name>
205205
```
206206

207+
部署凭据支持通过 `--volcengine-access-key` / `--volcengine-secret-key`
208+
显式传入,也支持当前进程的 `VOLCENGINE_ACCESS_KEY` /
209+
`VOLCENGINE_SECRET_KEY` 环境变量。两者均未提供时,会读取
210+
`~/.volc/credentials` 中的 `[default]` 配置。
211+
207212
### 自定义 Studio 品牌
208213

209214
使用 `--site-title` 设置不超过 6 个字符的系统名称,使用

tests/cli/test_studio_deploy_target.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@
2424
sanitize_for_serialization,
2525
)
2626

27-
from veadk.cli.cli_frontend import _resolve_studio_identity_region, studio
27+
from veadk.cli.cli_frontend import (
28+
_resolve_studio_cloud_credentials,
29+
_resolve_studio_identity_region,
30+
studio,
31+
)
2832
from veadk.config import veadk_environments
2933
from veadk.integrations.ve_identity.identity_client import IdentityClient
3034

@@ -45,6 +49,48 @@ def _skip_serverless_role_setup(monkeypatch: pytest.MonkeyPatch) -> None:
4549
)
4650

4751

52+
def test_studio_credentials_prefer_inline_environment(
53+
monkeypatch: pytest.MonkeyPatch,
54+
tmp_path: Path,
55+
) -> None:
56+
credentials_path = tmp_path / "credentials"
57+
credentials_path.write_text(
58+
"[default]\naccess_key_id=file-ak\nsecret_access_key=file-sk\n",
59+
encoding="utf-8",
60+
)
61+
monkeypatch.setenv("VOLCENGINE_ACCESS_KEY", "env-ak")
62+
monkeypatch.setenv("VOLCENGINE_SECRET_KEY", "env-sk")
63+
64+
credentials = _resolve_studio_cloud_credentials(
65+
None,
66+
None,
67+
credentials_path,
68+
)
69+
70+
assert credentials == ("env-ak", "env-sk")
71+
72+
73+
def test_studio_credentials_fall_back_to_volc_default_profile(
74+
monkeypatch: pytest.MonkeyPatch,
75+
tmp_path: Path,
76+
) -> None:
77+
credentials_path = tmp_path / "credentials"
78+
credentials_path.write_text(
79+
"[default]\naccess_key_id=file-ak\nsecret_access_key=file-sk\n",
80+
encoding="utf-8",
81+
)
82+
monkeypatch.delenv("VOLCENGINE_ACCESS_KEY", raising=False)
83+
monkeypatch.delenv("VOLCENGINE_SECRET_KEY", raising=False)
84+
85+
credentials = _resolve_studio_cloud_credentials(
86+
None,
87+
None,
88+
credentials_path,
89+
)
90+
91+
assert credentials == ("file-ak", "file-sk")
92+
93+
4894
@pytest.mark.parametrize(
4995
("stage", "expected_prefix"),
5096
[

veadk/cli/cli_frontend.py

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3501,6 +3501,48 @@ def _resolve_studio_identity_region(
35013501
)
35023502

35033503

3504+
def _resolve_studio_cloud_credentials(
3505+
access_key: str | None,
3506+
secret_key: str | None,
3507+
credentials_path: Path | None = None,
3508+
) -> tuple[str, str]:
3509+
"""Resolve Studio deploy credentials from CLI, environment, or ~/.volc."""
3510+
import configparser
3511+
3512+
resolved_access_key = access_key or os.getenv("VOLCENGINE_ACCESS_KEY", "")
3513+
resolved_secret_key = secret_key or os.getenv("VOLCENGINE_SECRET_KEY", "")
3514+
if resolved_access_key and resolved_secret_key:
3515+
return resolved_access_key, resolved_secret_key
3516+
3517+
path = credentials_path or Path.home() / ".volc" / "credentials"
3518+
if path.is_file():
3519+
parser = configparser.ConfigParser(interpolation=None)
3520+
try:
3521+
with path.open(encoding="utf-8") as credentials_file:
3522+
parser.read_file(credentials_file)
3523+
except (OSError, UnicodeError, configparser.Error) as error:
3524+
raise click.ClickException(
3525+
f"Failed to read Volcengine credentials file '{path}': {error}"
3526+
) from error
3527+
default_profile = parser["default"] if parser.has_section("default") else {}
3528+
resolved_access_key = (
3529+
resolved_access_key or str(default_profile.get("access_key_id", "")).strip()
3530+
)
3531+
resolved_secret_key = (
3532+
resolved_secret_key
3533+
or str(default_profile.get("secret_access_key", "")).strip()
3534+
)
3535+
3536+
if resolved_access_key and resolved_secret_key:
3537+
return resolved_access_key, resolved_secret_key
3538+
raise click.ClickException(
3539+
"Volcengine credentials required: pass --volcengine-access-key/"
3540+
"--volcengine-secret-key, set VOLCENGINE_ACCESS_KEY/"
3541+
"VOLCENGINE_SECRET_KEY, or configure the [default] profile in "
3542+
"~/.volc/credentials."
3543+
)
3544+
3545+
35043546
@studio.command("deploy")
35053547
@click.option(
35063548
"--user-pool-id",
@@ -3640,21 +3682,18 @@ def frontend_deploy(
36403682
import tempfile
36413683
import shutil
36423684

3643-
from veadk.config import getenv, veadk_environments
3685+
from veadk.config import veadk_environments
36443686

36453687
try:
36463688
branding_title = normalize_site_title(site_title)
36473689
branding_logo = resolve_site_logo(site_logo)
36483690
except ValueError as error:
36493691
raise click.ClickException(str(error)) from error
36503692

3651-
ak = volcengine_access_key or getenv("VOLCENGINE_ACCESS_KEY")
3652-
sk = volcengine_secret_key or getenv("VOLCENGINE_SECRET_KEY")
3653-
if not ak or not sk:
3654-
raise click.ClickException(
3655-
"Volcengine credentials required: set VOLCENGINE_ACCESS_KEY/SECRET_KEY "
3656-
"or pass --volcengine-access-key/--volcengine-secret-key."
3657-
)
3693+
ak, sk = _resolve_studio_cloud_credentials(
3694+
volcengine_access_key,
3695+
volcengine_secret_key,
3696+
)
36583697

36593698
identity_region = _resolve_studio_identity_region(
36603699
access_key=ak,

0 commit comments

Comments
 (0)