/** * 当配置了 OBS_CREDENTIALS_URL 且未配置 AK/SK 时,从该 URL 拉取 YAML 并解析出 * OBS_ACCESS_KEY、OBS_SECRET_KEY 写入 process.env,供 EnvConfigResolverImpl 使用。 * * Jenkins/CI 用法:在 Job 中配置环境变量即可,不依赖 URL 拉取。 * - 标准名:OBS_ACCESS_KEY、OBS_SECRET_KEY(推荐) * - 别名:OBS_AK、OBS_SK(若 Jenkins 凭证绑定使用此命名) * 只要 AK/SK 任一组合存在则不会请求 OBS_CREDENTIALS_URL。 */ import yaml from 'js-yaml'; const CREDENTIALS_URL_KEY = 'OBS_CREDENTIALS_URL'; const FETCH_TIMEOUT_MS = 15000; function getObsAccessKey(): string | undefined { return process.env.OBS_ACCESS_KEY ?? process.env.OBS_AK; } function getObsSecretKey(): string | undefined { return process.env.OBS_SECRET_KEY ?? process.env.OBS_SK; } /** * 若设置了 OBS_CREDENTIALS_URL 且当前未设置 OBS_ACCESS_KEY 或 OBS_SECRET_KEY, * 则请求该 URL,解析 YAML,并将 OBS_ACCESS_KEY、OBS_SECRET_KEY 写入 process.env。 */ export async function loadObsCredentialsFromUrlIfNeeded(): Promise { const url = process.env.OBS_CREDENTIALS_URL; const hasAccessKey = getObsAccessKey(); const hasSecretKey = getObsSecretKey(); if (!url || (hasAccessKey && hasSecretKey)) { if (hasAccessKey && !process.env.OBS_ACCESS_KEY) process.env.OBS_ACCESS_KEY = getObsAccessKey(); if (hasSecretKey && !process.env.OBS_SECRET_KEY) process.env.OBS_SECRET_KEY = getObsSecretKey(); return; } const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS); let res: Response; try { res = await fetch(url, { signal: controller.signal }); } catch (err: any) { clearTimeout(timeoutId); const msg = err?.name === 'AbortError' ? `拉取 OBS 凭证超时 (${FETCH_TIMEOUT_MS}ms): ${url}。若在 Jenkins/CI 中无法访问该地址,请直接配置环境变量 OBS_ACCESS_KEY 和 OBS_SECRET_KEY。` : `拉取 OBS 凭证失败: ${err?.message ?? err}。若在 Jenkins/CI 中无法访问该地址,请直接配置环境变量 OBS_ACCESS_KEY 和 OBS_SECRET_KEY。`; throw new Error(msg); } clearTimeout(timeoutId); if (!res.ok) { throw new Error(`拉取 OBS 凭证失败 (${res.status}): ${url}`); } const text = await res.text(); const parsed = yaml.load(text) as Record | undefined; if (!parsed || typeof parsed !== 'object') { throw new Error( `OBS 凭证 YAML 解析结果无效,请检查 ${CREDENTIALS_URL_KEY} 返回内容`, ); } const accessKey = parsed.OBS_ACCESS_KEY; const secretKey = parsed.OBS_SECRET_KEY; if (typeof accessKey === 'string') process.env.OBS_ACCESS_KEY = accessKey; if (typeof secretKey === 'string') process.env.OBS_SECRET_KEY = secretKey; if (!process.env.OBS_ACCESS_KEY || !process.env.OBS_SECRET_KEY) { throw new Error( `OBS 凭证 YAML 中未找到 OBS_ACCESS_KEY 或 OBS_SECRET_KEY,请检查 ${CREDENTIALS_URL_KEY} 返回内容`, ); } }