commit 047a2f6339ff4093570bcb97068a4a8e8c1ccc50 Author: GigiaJ Date: Mon Nov 24 00:09:27 2025 -0600 Add pulumi crds generator script diff --git a/generate-crds.js b/generate-crds.js new file mode 100644 index 0000000..201aa1f --- /dev/null +++ b/generate-crds.js @@ -0,0 +1,114 @@ +const fs = require('fs'); +const path = require('path'); +const https = require('https'); +const crypto = require('crypto'); +const { execSync } = require('child_process'); + +const PROJECT_ROOT = process.cwd(); + +const OUTPUT_DIR = path.join(PROJECT_ROOT, 'generated/crds'); +const TEMP_DIR = path.join(PROJECT_ROOT, 'temp_crds'); +const CHECKSUM_FILE = path.join(PROJECT_ROOT, '.crd2pulumi-checksum'); + +const GW_VERSION = process.env.GW_VERSION || 'v1.1.0'; +const GW_URL = `https://github.com/kubernetes-sigs/gateway-api/releases/download/${GW_VERSION}/experimental-install.yaml`; +const GW_FILE = 'gateway-api.yaml'; + +const CM_VERSION = process.env.CM_VERSION || 'v1.15.0'; +const CM_URL = `https://github.com/cert-manager/cert-manager/releases/download/${CM_VERSION}/cert-manager.crds.yaml`; +const CM_FILE = 'cert-manager.yaml'; + +const downloadFile = (url, filename) => { + return new Promise((resolve, reject) => { + const destPath = path.join(TEMP_DIR, filename); + const file = fs.createWriteStream(destPath); + + const request = (uri) => { + https.get(uri, (response) => { + if (response.statusCode === 301 || response.statusCode === 302) { + return request(response.headers.location); + } + if (response.statusCode !== 200) { + reject(new Error(`Failed to download ${uri}: ${response.statusCode}`)); + return; + } + console.log(`Downloading ${filename}...`); + response.pipe(file); + file.on('finish', () => { + file.close(); + resolve(destPath); + }); + }).on('error', (err) => { + fs.unlink(destPath, () => {}); + reject(err); + }); + }; + request(url); + }); +}; + +const computeHash = (filePaths) => { + const hash = crypto.createHash('sha256'); + filePaths.sort().forEach(fp => hash.update(fs.readFileSync(fp))); + return hash.digest('hex'); +}; + +async function main() { + if (fs.existsSync(TEMP_DIR)) fs.rmSync(TEMP_DIR, { recursive: true, force: true }); + fs.mkdirSync(TEMP_DIR); + + try { + const gwPath = await downloadFile(GW_URL, GW_FILE); + const cmPath = await downloadFile(CM_URL, CM_FILE); + const allFiles = [gwPath, cmPath]; + const newHash = computeHash(allFiles); + + let oldHash = null; + if (fs.existsSync(CHECKSUM_FILE)) { + oldHash = fs.readFileSync(CHECKSUM_FILE, 'utf8').trim(); + } + + if (oldHash === newHash && fs.existsSync(OUTPUT_DIR)) { + console.log('CRDs unchanged. Skipping.'); + } else { + console.log('Regenerating CRDs...'); + if (fs.existsSync(OUTPUT_DIR)) fs.rmSync(OUTPUT_DIR, { recursive: true, force: true }); + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + execSync(`crd2pulumi --nodejsPath "${OUTPUT_DIR}" --force "${gwPath}" "${cmPath}"`, { stdio: 'inherit' }); + + const pkgPath = path.join(OUTPUT_DIR, 'package.json'); + if (fs.existsSync(pkgPath)) { + const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); + if (pkg.scripts) delete pkg.scripts; + fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)); + } + + const tsconfig = { + compilerOptions: { + target: "es2020", + module: "commonjs", + moduleResolution: "node", + declaration: true, + skipLibCheck: true, + }, + include: ["**/*.ts"], + exclude: ["node_modules"] + }; + fs.writeFileSync(path.join(OUTPUT_DIR, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2)); + + try { + execSync('npx tsc', { cwd: OUTPUT_DIR, stdio: 'inherit' }); + } catch (e) { console.warn("TSC warnings ignored."); } + + fs.writeFileSync(CHECKSUM_FILE, newHash); + console.log(`Success!`); + } + } catch (error) { + console.error(error); + process.exit(1); + } finally { + if (fs.existsSync(TEMP_DIR)) fs.rmSync(TEMP_DIR, { recursive: true, force: true }); + } +} + +main();