@meshxdata/fops 0.1.45 → 0.1.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -18
- package/package.json +1 -1
- package/src/commands/lifecycle.js +81 -5
- package/src/commands/setup.js +45 -4
- package/src/plugins/bundled/fops-plugin-azure/index.js +29 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-core.js +1185 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-flux.js +1180 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-ingress.js +393 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-naming.js +104 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-network.js +296 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-postgres.js +768 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-reconcilers.js +538 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-secrets.js +849 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-stacks.js +643 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-state.js +145 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-storage.js +496 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks-terraform.js +1032 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-aks.js +155 -4245
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-keyvault.js +186 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/azure-results.js +5 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/commands/infra-cmds.js +758 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/commands/registry-cmds.js +250 -0
- package/src/plugins/bundled/fops-plugin-azure/lib/commands/test-cmds.js +2 -1
- package/src/plugins/bundled/fops-plugin-foundation/lib/apply.js +3 -2
- package/src/plugins/bundled/fops-plugin-foundation/lib/helpers.js +21 -0
- package/src/plugins/bundled/fops-plugin-foundation/lib/tools-read.js +3 -5
- package/src/ui/tui/App.js +13 -13
- package/src/web/dist/assets/index-NXC8Hvnp.css +1 -0
- package/src/web/dist/assets/index-QH1N4ejK.js +112 -0
- package/src/web/dist/index.html +2 -2
- package/src/web/server.js +4 -4
- package/src/web/dist/assets/index-BphVaAUd.css +0 -1
- package/src/web/dist/assets/index-CSckLzuG.js +0 -129
|
@@ -1253,6 +1253,192 @@ export async function keyvaultSetup(opts = {}) {
|
|
|
1253
1253
|
console.log(chalk.bold.green(`\n Setup complete! Run: fops azure keyvault sync\n`));
|
|
1254
1254
|
}
|
|
1255
1255
|
|
|
1256
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1257
|
+
// Network configuration (VNet integration, service endpoints)
|
|
1258
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
1259
|
+
|
|
1260
|
+
export async function networkShow(opts = {}) {
|
|
1261
|
+
const execa = await lazyExeca();
|
|
1262
|
+
const sub = opts.profile;
|
|
1263
|
+
await ensureAzCli(execa);
|
|
1264
|
+
await ensureAzAuth(execa, { subscription: sub });
|
|
1265
|
+
|
|
1266
|
+
const vault = await resolveVault(execa, opts.vault, sub);
|
|
1267
|
+
|
|
1268
|
+
const { stdout } = await execa("az", [
|
|
1269
|
+
"keyvault", "show", "--name", vault, "--output", "json", ...subArgs(sub),
|
|
1270
|
+
], { timeout: 30000 });
|
|
1271
|
+
|
|
1272
|
+
const v = JSON.parse(stdout);
|
|
1273
|
+
const props = v.properties || {};
|
|
1274
|
+
const networkRules = props.networkAcls || {};
|
|
1275
|
+
|
|
1276
|
+
banner(`Network Config — "${vault}"`);
|
|
1277
|
+
kvLine("Public Access", props.publicNetworkAccess === "Disabled" ? OK("disabled") : WARN("enabled"));
|
|
1278
|
+
kvLine("Default Action", networkRules.defaultAction === "Deny" ? OK("Deny") : WARN(networkRules.defaultAction || "Allow"));
|
|
1279
|
+
kvLine("Bypass", DIM(networkRules.bypass || "AzureServices"));
|
|
1280
|
+
|
|
1281
|
+
const ipRules = networkRules.ipRules || [];
|
|
1282
|
+
const vnetRules = networkRules.virtualNetworkRules || [];
|
|
1283
|
+
|
|
1284
|
+
console.log("");
|
|
1285
|
+
if (ipRules.length > 0) {
|
|
1286
|
+
console.log(ACCENT(" IP Rules"));
|
|
1287
|
+
for (const r of ipRules) {
|
|
1288
|
+
console.log(` ${DIM("•")} ${r.value}`);
|
|
1289
|
+
}
|
|
1290
|
+
} else {
|
|
1291
|
+
kvLine("IP Rules", DIM("none"));
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
if (vnetRules.length > 0) {
|
|
1295
|
+
console.log(ACCENT(" VNet Rules"));
|
|
1296
|
+
for (const r of vnetRules) {
|
|
1297
|
+
const subnetId = r.id || "";
|
|
1298
|
+
const parts = subnetId.split("/");
|
|
1299
|
+
const vnet = parts[parts.indexOf("virtualNetworks") + 1] || "";
|
|
1300
|
+
const subnet = parts[parts.indexOf("subnets") + 1] || "";
|
|
1301
|
+
console.log(` ${DIM("•")} ${vnet}/${subnet}`);
|
|
1302
|
+
}
|
|
1303
|
+
} else {
|
|
1304
|
+
kvLine("VNet Rules", DIM("none"));
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
console.log("");
|
|
1308
|
+
hint("Add VNet: fops azure keyvault network add-vnet --vault <name> --vnet <vnet> --subnet <subnet>");
|
|
1309
|
+
hint("Private: fops azure keyvault network private --vault <name>\n");
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
export async function networkAddVnet(opts = {}) {
|
|
1313
|
+
const execa = await lazyExeca();
|
|
1314
|
+
const sub = opts.profile;
|
|
1315
|
+
await ensureAzCli(execa);
|
|
1316
|
+
await ensureAzAuth(execa, { subscription: sub });
|
|
1317
|
+
|
|
1318
|
+
const vault = await resolveVault(execa, opts.vault, sub);
|
|
1319
|
+
|
|
1320
|
+
if (!opts.vnet || !opts.subnet) {
|
|
1321
|
+
console.error(chalk.red("\n --vnet and --subnet are required.\n"));
|
|
1322
|
+
process.exit(1);
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
const rg = opts.resourceGroup || opts.vnetResourceGroup;
|
|
1326
|
+
|
|
1327
|
+
// 1. Add service endpoint to subnet if not present
|
|
1328
|
+
hint(`Adding Microsoft.KeyVault service endpoint to ${opts.vnet}/${opts.subnet}...`);
|
|
1329
|
+
|
|
1330
|
+
const subnetArgs = [
|
|
1331
|
+
"network", "vnet", "subnet", "update",
|
|
1332
|
+
"--vnet-name", opts.vnet,
|
|
1333
|
+
"-n", opts.subnet,
|
|
1334
|
+
"--service-endpoints", "Microsoft.KeyVault",
|
|
1335
|
+
"--output", "none",
|
|
1336
|
+
...subArgs(sub),
|
|
1337
|
+
];
|
|
1338
|
+
if (rg) subnetArgs.push("-g", rg);
|
|
1339
|
+
|
|
1340
|
+
const { exitCode: seCode, stderr: seErr } = await execa("az", subnetArgs, { timeout: 120000, reject: false });
|
|
1341
|
+
if (seCode !== 0) {
|
|
1342
|
+
console.log(WARN(` ⚠ Service endpoint: ${(seErr || "").split("\n")[0]}`));
|
|
1343
|
+
} else {
|
|
1344
|
+
console.log(OK(" ✓ Service endpoint added"));
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
// 2. Get subnet resource ID
|
|
1348
|
+
const subnetShowArgs = [
|
|
1349
|
+
"network", "vnet", "subnet", "show",
|
|
1350
|
+
"--vnet-name", opts.vnet,
|
|
1351
|
+
"-n", opts.subnet,
|
|
1352
|
+
"--query", "id", "-o", "tsv",
|
|
1353
|
+
...subArgs(sub),
|
|
1354
|
+
];
|
|
1355
|
+
if (rg) subnetShowArgs.push("-g", rg);
|
|
1356
|
+
|
|
1357
|
+
const { stdout: subnetId, exitCode: sidCode, stderr: sidErr } = await execa("az", subnetShowArgs, { timeout: 30000, reject: false });
|
|
1358
|
+
if (sidCode !== 0 || !subnetId?.trim()) {
|
|
1359
|
+
console.error(chalk.red(`\n ✗ Could not find subnet: ${(sidErr || "").split("\n")[0]}\n`));
|
|
1360
|
+
process.exit(1);
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
// 3. Add VNet rule to Key Vault
|
|
1364
|
+
hint(`Adding VNet rule to Key Vault "${vault}"...`);
|
|
1365
|
+
|
|
1366
|
+
const { exitCode, stderr } = await execa("az", [
|
|
1367
|
+
"keyvault", "network-rule", "add",
|
|
1368
|
+
"--name", vault,
|
|
1369
|
+
"--subnet", subnetId.trim(),
|
|
1370
|
+
"--output", "none",
|
|
1371
|
+
...subArgs(sub),
|
|
1372
|
+
], { timeout: 60000, reject: false });
|
|
1373
|
+
|
|
1374
|
+
if (exitCode !== 0) {
|
|
1375
|
+
console.error(chalk.red(`\n ✗ ${(stderr || "").split("\n")[0]}\n`));
|
|
1376
|
+
process.exit(1);
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
console.log(OK(` ✓ VNet rule added: ${opts.vnet}/${opts.subnet}`));
|
|
1380
|
+
hint(`\nSet to private: fops azure keyvault network private --vault ${vault}\n`);
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
export async function networkPrivate(opts = {}) {
|
|
1384
|
+
const execa = await lazyExeca();
|
|
1385
|
+
const sub = opts.profile;
|
|
1386
|
+
await ensureAzCli(execa);
|
|
1387
|
+
await ensureAzAuth(execa, { subscription: sub });
|
|
1388
|
+
|
|
1389
|
+
const vault = await resolveVault(execa, opts.vault, sub);
|
|
1390
|
+
|
|
1391
|
+
hint(`Setting "${vault}" to private (deny public access)...`);
|
|
1392
|
+
|
|
1393
|
+
const { exitCode, stderr } = await execa("az", [
|
|
1394
|
+
"keyvault", "update",
|
|
1395
|
+
"--name", vault,
|
|
1396
|
+
"--default-action", "Deny",
|
|
1397
|
+
"--bypass", "AzureServices",
|
|
1398
|
+
"--output", "none",
|
|
1399
|
+
...subArgs(sub),
|
|
1400
|
+
], { timeout: 60000, reject: false });
|
|
1401
|
+
|
|
1402
|
+
if (exitCode !== 0) {
|
|
1403
|
+
console.error(chalk.red(`\n ✗ ${(stderr || "").split("\n")[0]}\n`));
|
|
1404
|
+
process.exit(1);
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
console.log(OK(` ✓ Key Vault "${vault}" is now private`));
|
|
1408
|
+
console.log(DIM(" Default action: Deny"));
|
|
1409
|
+
console.log(DIM(" Bypass: AzureServices"));
|
|
1410
|
+
hint("\nAccess limited to allowed VNets/IPs and Azure services.\n");
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
export async function networkPublic(opts = {}) {
|
|
1414
|
+
const execa = await lazyExeca();
|
|
1415
|
+
const sub = opts.profile;
|
|
1416
|
+
await ensureAzCli(execa);
|
|
1417
|
+
await ensureAzAuth(execa, { subscription: sub });
|
|
1418
|
+
|
|
1419
|
+
const vault = await resolveVault(execa, opts.vault, sub);
|
|
1420
|
+
|
|
1421
|
+
const { resolveCliSrc } = await import("./azure-helpers.js");
|
|
1422
|
+
const { confirm } = await import(resolveCliSrc("ui/confirm.js"));
|
|
1423
|
+
const yes = await confirm(` Make Key Vault "${vault}" publicly accessible?`);
|
|
1424
|
+
if (!yes) { console.log(DIM("\n Cancelled.\n")); return; }
|
|
1425
|
+
|
|
1426
|
+
const { exitCode, stderr } = await execa("az", [
|
|
1427
|
+
"keyvault", "update",
|
|
1428
|
+
"--name", vault,
|
|
1429
|
+
"--default-action", "Allow",
|
|
1430
|
+
"--output", "none",
|
|
1431
|
+
...subArgs(sub),
|
|
1432
|
+
], { timeout: 60000, reject: false });
|
|
1433
|
+
|
|
1434
|
+
if (exitCode !== 0) {
|
|
1435
|
+
console.error(chalk.red(`\n ✗ ${(stderr || "").split("\n")[0]}\n`));
|
|
1436
|
+
process.exit(1);
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
console.log(WARN(` ⚠ Key Vault "${vault}" is now public`));
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1256
1442
|
// ── Config helpers ──────────────────────────────────────────────────────────
|
|
1257
1443
|
|
|
1258
1444
|
function readFopsConfig() {
|
|
@@ -421,6 +421,11 @@ export async function resultsShow(opts = {}) {
|
|
|
421
421
|
process.exit(1);
|
|
422
422
|
}
|
|
423
423
|
|
|
424
|
+
if (opts.json) {
|
|
425
|
+
console.log(JSON.stringify(result, null, 2));
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
|
|
424
429
|
banner(`Test Result: ${target}`);
|
|
425
430
|
kvLine("Passed", result.passed ? OK("yes") : ERR("no"));
|
|
426
431
|
kvLine("Exit code", String(result.exitCode ?? "–"));
|