gcp-monorepo-secret-manager
Version:
A Google Cloud Secret Manager utility for managing environment variables across different environments and services within a monorepo.
113 lines • 4.78 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigManager = void 0;
const fs_1 = __importDefault(require("fs"));
class ConfigManager {
constructor(configPath = ".secrets-config") {
this.configPath = configPath;
this.config = this.loadConfig();
this.validateConfig();
}
loadConfig() {
if (!fs_1.default.existsSync(this.configPath)) {
throw new Error(`Configuration file not found at ${this.configPath}. Please create a .secrets-config file. Run 'msm --init' to generate a template.`);
}
try {
const configContent = fs_1.default.readFileSync(this.configPath, "utf8");
return JSON.parse(configContent);
}
catch (error) {
throw new Error(`Failed to parse configuration file: ${error.message}`);
}
}
validateConfig() {
const { serviceAccountPaths, services, projectIds, deletePolicy } = this.config;
// Validate service account paths
if (!serviceAccountPaths || !serviceAccountPaths.staging || !serviceAccountPaths.production) {
throw new Error("Configuration must include serviceAccountPaths for both staging and production");
}
// Validate project IDs
if (!projectIds || !projectIds.staging || !projectIds.production) {
throw new Error("Configuration must include projectIds for both staging and production");
}
// Services are optional now - they can be added later using --add-service
if (services && !Array.isArray(services)) {
throw new Error("Services must be an array if provided");
}
if (services && services.length > 0) {
services.forEach((service, index) => {
if (!service.name || !service.envPath || !service.targetPath || !service.secretPrefix) {
throw new Error(`Service at index ${index} is missing required fields: name, envPath, targetPath, secretPrefix`);
}
});
}
// Validate delete policy if provided
if (deletePolicy) {
this.validateDeletePolicy(deletePolicy);
}
}
validateDeletePolicy(policy) {
if (policy.maxVersions !== undefined && (policy.maxVersions < 0 || !Number.isInteger(policy.maxVersions))) {
throw new Error("deletePolicy.maxVersions must be a non-negative integer");
}
if (policy.maxAgeDays !== undefined && (policy.maxAgeDays < 0 || !Number.isInteger(policy.maxAgeDays))) {
throw new Error("deletePolicy.maxAgeDays must be a non-negative integer");
}
if (policy.enabled !== undefined && typeof policy.enabled !== 'boolean') {
throw new Error("deletePolicy.enabled must be a boolean");
}
}
getConfig() {
return this.config;
}
getServiceAccountPath(environment) {
return this.config.serviceAccountPaths[environment];
}
getProjectId(environment) {
return this.config.projectIds[environment];
}
getServices() {
return this.config.services || [];
}
getServiceByName(name) {
return this.getServices().find(service => service.name === name);
}
getServiceNames() {
return this.getServices().map(service => service.name);
}
getDeletePolicy() {
// Return default delete policy if none is configured
return this.config.deletePolicy || {
maxVersions: 10,
maxAgeDays: 30,
enabled: true
};
}
static generateTemplate(outputPath = ".secrets-config") {
const template = {
serviceAccountPaths: {
staging: "firebase/freetech-stg/firebase-admin.json",
production: "firebase/freetech-production/firebase-admin.json"
},
projectIds: {
staging: "your-staging-project-id",
production: "your-production-project-id"
},
services: [],
deletePolicy: {
maxVersions: 10,
maxAgeDays: 30,
enabled: true
}
};
fs_1.default.writeFileSync(outputPath, JSON.stringify(template, null, 2));
console.log(`✅ Configuration template created at ${outputPath}`);
console.log("Please update the projectIds and paths according to your project structure.");
console.log("Use 'msm --add-service' to add services to your configuration.");
}
}
exports.ConfigManager = ConfigManager;
//# sourceMappingURL=ConfigManager.js.map