diff --git a/deploy/dobotai-dingtalk/README.md b/deploy/dobotai-dingtalk/README.md index c13ab7f..9150982 100644 --- a/deploy/dobotai-dingtalk/README.md +++ b/deploy/dobotai-dingtalk/README.md @@ -81,6 +81,8 @@ sudo dobotai-dingtalk-configure | `DINGTALK_CLIENT_ID` | `dingxxxxxxxx` | 钉钉AppKey | | `DINGTALK_CLIENT_SECRET` | `<你的钉钉 AppSecret>` | 钉钉AppSecret | +配置器另含可选的“回答图片外发OSS”整组录入(Endpoint、Region、Bucket、AK、SK、稳定外发基础地址):全部留空即禁用该功能;任一项填写则六项必填、密钥不回显。禁止把OSS凭据写入Git或命令行。 + 保存后脚本自动执行以下RDS门禁: ```text diff --git a/deploy/dobotai-dingtalk/configure_env.py b/deploy/dobotai-dingtalk/configure_env.py index 874d647..1324917 100644 --- a/deploy/dobotai-dingtalk/configure_env.py +++ b/deploy/dobotai-dingtalk/configure_env.py @@ -47,6 +47,36 @@ def prompt_rds(values): print("警告:数据库名不是DobotAI专用库,继续前请确认。") values["DATABASE_URL"] = f"postgres://{quote(user, safe='')}:{quote(password, safe='')}@{host}:{port}/{database}" +OSS_FIELDS = ( + ("DOBOTAI_OUTBOUND_IMAGE_OSS_ENDPOINT", "OSS Endpoint", "私有Bucket的接入地址。", "https://oss-cn-shenzhen.aliyuncs.com", False), + ("DOBOTAI_OUTBOUND_IMAGE_OSS_REGION", "OSS Region", "Bucket所在地域。", "cn-shenzhen", False), + ("DOBOTAI_OUTBOUND_IMAGE_OSS_BUCKET", "OSS Bucket", "外发图片专用私有Bucket。", "dobot-xxx", False), + ("DOBOTAI_OUTBOUND_IMAGE_OSS_ACCESS_KEY_ID", "OSS AccessKey ID", "仅授权该Bucket的AK。", "", False), + ("DOBOTAI_OUTBOUND_IMAGE_OSS_ACCESS_KEY_SECRET", "OSS AccessKey Secret", "仅授权该Bucket的SK。", "", True), + ("DOBOTAI_OUTBOUND_IMAGE_PUBLIC_BASE_URL", "图片稳定外发基础地址", "钉钉可见的稳定HTTPS入口,不含凭据。", "https://host/dingtalk/i", False), +) + +def prompt_oss(values): + """OSS整组录入:全部留空即禁用;任一项填写则六项必填。""" + print("\n回答图片外发OSS(可选,OSS整组录入;直接回车表示整组禁用)") + entered = {} + for key, label, description, example, secret in OSS_FIELDS: + default = values.get(key, "").strip() + suffix = "(已配置,直接回车保留)" if default else "" + print(f"用途:{description} 格式示例:{example}") + reader = getpass.getpass if secret else input + value = reader(f"{label}{suffix}: ").strip() + entered[key] = value or default + if not any(entered.values()): + for key, *_ in OSS_FIELDS: + values.pop(key, None) + return + missing = [label for key, label, *_ in OSS_FIELDS if not entered[key]] + if missing: + raise SystemExit("OSS为整组可选能力,以下项未填写:" + "、".join(missing)) + values.update(entered) + + def parse_env(path): lines = path.read_text(encoding="utf-8").splitlines(); values = {} @@ -72,6 +102,7 @@ def main(): if not path.is_file(): raise SystemExit("DobotAI环境文件不存在,请先执行根目录install-docker.sh。") lines,values=parse_env(path) prompt_rds(values) + prompt_oss(values) for key,label,description,example,secret in FIELDS: suffix="(已配置,直接回车保留)" if values.get(key,"").strip() else "(必填)" print(f"\n{label}\n用途:{description}\n格式示例:{example}") diff --git a/scripts/containerized_deployment_test.go b/scripts/containerized_deployment_test.go index 68c35f4..de54f74 100644 --- a/scripts/containerized_deployment_test.go +++ b/scripts/containerized_deployment_test.go @@ -80,7 +80,7 @@ func TestRDSCredentialConfiguratorPromptsForExternalDatabase(t *testing.T) { t.Fatal(err) } source := string(data) - for _, required := range []string{"DATABASE_URL", "阿里云RDS", "RDS主机地址", "RDS端口", "数据库名", "数据库账号", "数据库密码", "快速问答Agent ID", "智能推理Agent ID", "getpass.getpass", "os.replace", "0o600"} { + for _, required := range []string{"DATABASE_URL", "阿里云RDS", "RDS主机地址", "RDS端口", "数据库名", "数据库账号", "数据库密码", "快速问答Agent ID", "智能推理Agent ID", "getpass.getpass", "os.replace", "0o600", "OSS整组录入", "DOBOTAI_OUTBOUND_IMAGE_OSS_ACCESS_KEY_SECRET"} { if !strings.Contains(source, required) { t.Errorf("RDS configurator missing %q", required) }