190 lines
7.3 KiB
JavaScript
190 lines
7.3 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* ═══════════════════════════════════════════════════════════
|
||
* D51-3 · COS 人格体密钥生成器
|
||
* ═══════════════════════════════════════════════════════════
|
||
*
|
||
* 为9个人格体生成腾讯云CAM子用户配置和IAM策略。
|
||
* 每个人格体仅有 /{persona_id}/ 目录的读写权限。
|
||
*
|
||
* 使用方式:
|
||
* node scripts/cos-persona-keys-generator.js
|
||
* node scripts/cos-persona-keys-generator.js --persona zhiqiu
|
||
* node scripts/cos-persona-keys-generator.js --format terraform
|
||
*
|
||
* 签发: 铸渊 · ICE-GL-ZY001
|
||
* 版权: 国作登字-2026-A-00037559
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
// ─── 9个人格体注册表 ───
|
||
const PERSONAS = [
|
||
{ persona_id: 'shushu', name: '舒舒', developer: '肥猫线' },
|
||
{ persona_id: 'qiuqiu', name: '秋秋', developer: '之之线' },
|
||
{ persona_id: 'ounomiya', name: '欧诺弥亚', developer: '小草莓线' },
|
||
{ persona_id: 'jiyao', name: '寂曜', developer: '燕樊线' },
|
||
{ persona_id: 'xiaotanheshu', name: '小坍缩核', developer: '页页线' },
|
||
{ persona_id: 'chenxing', name: '晨星', developer: '桔子线' },
|
||
{ persona_id: 'tangxingyun', name: '糖星云', developer: '花尔线' },
|
||
{ persona_id: 'yaochu', name: '曜初', developer: '时雨线' },
|
||
{ persona_id: 'zhiqiu', name: '知秋', developer: 'Awen线' }
|
||
];
|
||
|
||
// ─── COS 桶配置 ───
|
||
const BUCKET_CONFIG = {
|
||
guangzhou: {
|
||
bucket: 'zy-team-hub-1317346199',
|
||
region: 'ap-guangzhou',
|
||
appId: '1317346199'
|
||
},
|
||
singapore: {
|
||
bucket: 'zy-team-hub-sg-1317346199',
|
||
region: 'ap-singapore',
|
||
appId: '1317346199'
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 为单个人格体生成CAM IAM策略
|
||
*/
|
||
function generateIamPolicy(persona, bucketConfig) {
|
||
return {
|
||
version: '2.0',
|
||
statement: [
|
||
{
|
||
effect: 'allow',
|
||
action: [
|
||
'cos:PutObject',
|
||
'cos:GetObject',
|
||
'cos:HeadObject',
|
||
'cos:DeleteObject',
|
||
'cos:GetBucket'
|
||
],
|
||
resource: [
|
||
`qcs::cos:${bucketConfig.region}:uid/${bucketConfig.appId}:${bucketConfig.bucket}/${persona.persona_id}/*`
|
||
],
|
||
condition: {}
|
||
},
|
||
{
|
||
effect: 'allow',
|
||
action: [
|
||
'cos:GetObject',
|
||
'cos:HeadObject'
|
||
],
|
||
resource: [
|
||
`qcs::cos:${bucketConfig.region}:uid/${bucketConfig.appId}:${bucketConfig.bucket}/zhuyuan/directives/*`,
|
||
`qcs::cos:${bucketConfig.region}:uid/${bucketConfig.appId}:${bucketConfig.bucket}/zhuyuan/architecture/*`
|
||
],
|
||
condition: {}
|
||
}
|
||
]
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 生成子用户配置建议
|
||
*/
|
||
function generateSubUserConfig(persona) {
|
||
return {
|
||
sub_user_name: `zy-persona-${persona.persona_id}`,
|
||
display_name: `${persona.name} · ${persona.developer} · COS专用`,
|
||
console_login: false,
|
||
api_access: true,
|
||
notes: `光湖人格体 ${persona.name}(${persona.persona_id}) 的COS桶访问密钥`,
|
||
secrets_to_configure: {
|
||
[`ZY_COS_${persona.persona_id.toUpperCase()}_SECRET_ID`]: '< 创建子用户后获取 >',
|
||
[`ZY_COS_${persona.persona_id.toUpperCase()}_SECRET_KEY`]: '< 创建子用户后获取 >'
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 生成完整的操作指南
|
||
*/
|
||
function generateOperationGuide() {
|
||
console.log('═══════════════════════════════════════════════════════════');
|
||
console.log('D51-3 · COS 人格体密钥生成器');
|
||
console.log('铸渊 · ICE-GL-ZY001 · 版权: 国作登字-2026-A-00037559');
|
||
console.log('═══════════════════════════════════════════════════════════');
|
||
console.log('');
|
||
console.log('📋 冰朔操作步骤:');
|
||
console.log('');
|
||
console.log('1. 登录腾讯云控制台 → 访问管理(CAM) → 用户 → 用户列表');
|
||
console.log('2. 为每个人格体创建子用户(仅API访问,无控制台登录)');
|
||
console.log('3. 为每个子用户配置下方对应的IAM策略');
|
||
console.log('4. 记录每个子用户的 SecretId / SecretKey');
|
||
console.log('5. 将密钥配置到对应人格体仓库的 GitHub Secrets');
|
||
console.log('');
|
||
console.log('─── 广州桶 ───');
|
||
console.log(`桶名: ${BUCKET_CONFIG.guangzhou.bucket}`);
|
||
console.log(`区域: ${BUCKET_CONFIG.guangzhou.region}`);
|
||
console.log('');
|
||
console.log('─── 新加坡桶 ───');
|
||
console.log(`桶名: ${BUCKET_CONFIG.singapore.bucket}`);
|
||
console.log(`区域: ${BUCKET_CONFIG.singapore.region}`);
|
||
console.log('');
|
||
}
|
||
|
||
// ─── 主逻辑 ───
|
||
const args = process.argv.slice(2);
|
||
const filterPersona = args.includes('--persona') ? args[args.indexOf('--persona') + 1] : null;
|
||
const outputFormat = args.includes('--format') ? args[args.indexOf('--format') + 1] : 'json';
|
||
const outputJson = args.includes('--json');
|
||
|
||
if (!outputJson) {
|
||
generateOperationGuide();
|
||
}
|
||
|
||
const results = [];
|
||
|
||
for (const persona of PERSONAS) {
|
||
if (filterPersona && persona.persona_id !== filterPersona) continue;
|
||
|
||
const config = {
|
||
persona,
|
||
sub_user: generateSubUserConfig(persona),
|
||
iam_policies: {
|
||
guangzhou: generateIamPolicy(persona, BUCKET_CONFIG.guangzhou),
|
||
singapore: generateIamPolicy(persona, BUCKET_CONFIG.singapore)
|
||
}
|
||
};
|
||
|
||
results.push(config);
|
||
|
||
if (!outputJson) {
|
||
console.log(`═══ ${persona.name} (${persona.persona_id}) · ${persona.developer} ═══`);
|
||
console.log('');
|
||
console.log(`子用户名: ${config.sub_user.sub_user_name}`);
|
||
console.log(`显示名: ${config.sub_user.display_name}`);
|
||
console.log('');
|
||
console.log('广州桶 IAM 策略:');
|
||
console.log(JSON.stringify(config.iam_policies.guangzhou, null, 2));
|
||
console.log('');
|
||
console.log('新加坡桶 IAM 策略:');
|
||
console.log(JSON.stringify(config.iam_policies.singapore, null, 2));
|
||
console.log('');
|
||
console.log('GitHub Secrets 配置:');
|
||
for (const [key, val] of Object.entries(config.sub_user.secrets_to_configure)) {
|
||
console.log(` ${key} = ${val}`);
|
||
}
|
||
console.log('');
|
||
console.log('目录结构:');
|
||
console.log(` /${persona.persona_id}/reports/ — 每日汇报`);
|
||
console.log(` /${persona.persona_id}/receipts/ — 铸渊回执`);
|
||
console.log(` /${persona.persona_id}/sync/ — 架构同步`);
|
||
console.log('');
|
||
}
|
||
}
|
||
|
||
if (outputJson) {
|
||
console.log(JSON.stringify(results, null, 2));
|
||
} else {
|
||
console.log('═══════════════════════════════════════════════════════════');
|
||
console.log(`✅ 共 ${results.length} 个人格体密钥配置已生成`);
|
||
console.log('');
|
||
console.log('💡 提示: 使用 --json 参数输出纯JSON格式');
|
||
console.log(' 使用 --persona zhiqiu 仅生成单个人格体');
|
||
console.log('═══════════════════════════════════════════════════════════');
|
||
}
|