#!/usr/bin/env python3 """上传 .env 文件到 Infisical""" import os import re import requests INFISICAL_URL = "https://infisical.seekkey.eu.org/api" TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoTWV0aG9kIjoiZW1haWwiLCJhdXRoVG9rZW5UeXBlIjoiYWNjZXNzVG9rZW4iLCJ1c2VySWQiOiJkY2NkYzVhYS04OTU0LTQwMmEtOWJkMi00OGM0NmNmZTVkZWQiLCJ0b2tlblZlcnNpb25JZCI6IjE4ZTlhMWEwLThmZTItNGE1MS1hMGQ4LTJiMWVmOTcyNDNiNiIsImFjY2Vzc1ZlcnNpb24iOjEsIm9yZ2FuaXphdGlvbklkIjoiNTI3NjU4ZGQtNWUwZS00NzAzLThiMDktOGNkZmFhZTk2YmIwIiwiaWF0IjoxNzY5ODMyNzI5LCJleHAiOjE3NzA2OTY3Mjl9.OcAUDeioCFNCXx6OjuTjzlgg9AKWPS0EIJr4K87aH1Q" WORKSPACE_ID = "9946b650-e08b-40d9-8e28-a55e3b19ec94" ENVIRONMENT = "dev" def parse_env_file(filepath): """解析 .env 文件,返回 key-value 字典""" secrets = {} with open(filepath, 'r') as f: for line in f: line = line.strip() # 跳过空行和注释 if not line or line.startswith('#') or line.startswith('---'): continue # 匹配 KEY=VALUE 格式 match = re.match(r'^([A-Za-z_][A-Za-z0-9_]*)=(.*)$', line) if match: key = match.group(1) value = match.group(2) secrets[key] = value return secrets def upload_secret(key, value): """使用 Infisical API 上传单个 secret""" headers = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json" } # 获取工作区的加密密钥 url = f"{INFISICAL_URL}/v3/secrets/{key}" params = { "workspaceId": WORKSPACE_ID, "environment": ENVIRONMENT, "type": "shared" } # 先检查 secret 是否存在 response = requests.get(url, headers=headers, params=params) if response.status_code == 200: # 更新现有 secret secret_id = response.json().get('secret', {}).get('id') update_url = f"{INFISICAL_URL}/v3/secrets/{secret_id}" data = { "workspaceId": WORKSPACE_ID, "environment": ENVIRONMENT, "type": "shared", "secretValue": value } response = requests.patch(update_url, headers=headers, json=data) action = "更新" elif response.status_code == 404: # 创建新 secret - 使用批量创建 API create_url = f"{INFISICAL_URL}/v3/secrets/batch/raw" data = { "workspaceId": WORKSPACE_ID, "environment": ENVIRONMENT, "secrets": [{ "secretKey": key, "secretValue": value, "type": "shared" }] } response = requests.post(create_url, headers=headers, json=data) action = "创建" else: print(f"❌ 检查 {key} 失败: {response.status_code}") return False if response.status_code in [200, 201]: print(f"✅ {action}: {key}") return True else: print(f"❌ {action} {key} 失败: {response.status_code} - {response.text[:100]}") return False def main(): env_file = "/home/ben/terraform/.env" secrets = parse_env_file(env_file) print(f"📤 开始上传 {len(secrets)} 个 secrets 到 Infisical...") print(f" 工作区: {WORKSPACE_ID}") print(f" 环境: {ENVIRONMENT}") print() success_count = 0 for key, value in secrets.items(): if upload_secret(key, value): success_count += 1 print() print(f"🎉 完成! 成功上传 {success_count}/{len(secrets)} 个 secrets") if __name__ == "__main__": main()