@fnndsc/stratus 0.1.0 → 0.2.0

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.
Files changed (134) hide show
  1. package/README.md +6 -1
  2. package/dist/args.d.ts +20 -6
  3. package/dist/args.js +45 -2
  4. package/dist/args.js.map +1 -1
  5. package/dist/backend.d.ts +35 -4
  6. package/dist/backend.js +77 -12
  7. package/dist/backend.js.map +1 -1
  8. package/dist/cloud/builder.d.ts +172 -0
  9. package/dist/cloud/builder.js +41 -0
  10. package/dist/cloud/builder.js.map +1 -0
  11. package/dist/cloud/driver.d.ts +149 -0
  12. package/dist/cloud/fake/builder.d.ts +147 -0
  13. package/dist/cloud/fake/builder.js +213 -0
  14. package/dist/cloud/fake/builder.js.map +1 -0
  15. package/dist/cloud/fake/driver.d.ts +73 -1
  16. package/dist/cloud/fake/driver.js +122 -0
  17. package/dist/cloud/fake/driver.js.map +1 -1
  18. package/dist/cloud/oci/api.d.ts +3 -2
  19. package/dist/cloud/oci/api.js +2 -0
  20. package/dist/cloud/oci/api.js.map +1 -1
  21. package/dist/cloud/oci/buildApi.d.ts +61 -0
  22. package/dist/cloud/oci/buildApi.js +132 -0
  23. package/dist/cloud/oci/buildApi.js.map +1 -0
  24. package/dist/cloud/oci/builder.d.ts +172 -0
  25. package/dist/cloud/oci/builder.js +370 -0
  26. package/dist/cloud/oci/builder.js.map +1 -0
  27. package/dist/cloud/oci/driver.d.ts +23 -2
  28. package/dist/cloud/oci/driver.js +107 -1
  29. package/dist/cloud/oci/driver.js.map +1 -1
  30. package/dist/cloud/oci/planRead.d.ts +38 -0
  31. package/dist/cloud/oci/planRead.js +67 -0
  32. package/dist/cloud/oci/planRead.js.map +1 -0
  33. package/dist/cloud/oci/prices.d.ts +22 -1
  34. package/dist/cloud/oci/prices.js +35 -0
  35. package/dist/cloud/oci/prices.js.map +1 -1
  36. package/dist/cloud/oci/resourceApi.d.ts +114 -0
  37. package/dist/cloud/oci/resourceApi.js +261 -0
  38. package/dist/cloud/oci/resourceApi.js.map +1 -0
  39. package/dist/cloud/oci/resourceMap.d.ts +44 -0
  40. package/dist/cloud/oci/resourceMap.js +70 -0
  41. package/dist/cloud/oci/resourceMap.js.map +1 -0
  42. package/dist/cloud/oci/rmApi.d.ts +74 -0
  43. package/dist/cloud/oci/rmApi.js +141 -0
  44. package/dist/cloud/oci/rmApi.js.map +1 -0
  45. package/dist/cloud/oci/stackVars.d.ts +49 -0
  46. package/dist/cloud/oci/stackVars.js +70 -0
  47. package/dist/cloud/oci/stackVars.js.map +1 -0
  48. package/dist/cluster/fakeKube.d.ts +43 -0
  49. package/dist/cluster/fakeKube.js +86 -0
  50. package/dist/cluster/fakeKube.js.map +1 -0
  51. package/dist/cluster/kube.d.ts +40 -0
  52. package/dist/cluster/kube.js +46 -0
  53. package/dist/cluster/kube.js.map +1 -0
  54. package/dist/cluster/kubeHttp.d.ts +16 -0
  55. package/dist/cluster/kubeHttp.js +86 -0
  56. package/dist/cluster/kubeHttp.js.map +1 -0
  57. package/dist/commands/build.d.ts +90 -0
  58. package/dist/commands/build.js +358 -0
  59. package/dist/commands/build.js.map +1 -0
  60. package/dist/commands/capacity.d.ts +37 -0
  61. package/dist/commands/capacity.js +93 -0
  62. package/dist/commands/capacity.js.map +1 -0
  63. package/dist/commands/domain.d.ts +45 -0
  64. package/dist/commands/domain.js +150 -0
  65. package/dist/commands/domain.js.map +1 -0
  66. package/dist/commands/spend.d.ts +22 -0
  67. package/dist/commands/spend.js +65 -0
  68. package/dist/commands/spend.js.map +1 -0
  69. package/dist/commands/teardown.d.ts +10 -0
  70. package/dist/commands/teardown.js +72 -0
  71. package/dist/commands/teardown.js.map +1 -0
  72. package/dist/commands/verify.d.ts +28 -0
  73. package/dist/commands/verify.js +98 -0
  74. package/dist/commands/verify.js.map +1 -0
  75. package/dist/domain/adopt.d.ts +60 -0
  76. package/dist/domain/adopt.js +143 -0
  77. package/dist/domain/adopt.js.map +1 -0
  78. package/dist/domain/sizing.d.ts +55 -0
  79. package/dist/domain/sizing.js +66 -0
  80. package/dist/domain/sizing.js.map +1 -0
  81. package/dist/domain/spec.d.ts +101 -0
  82. package/dist/domain/spec.js +191 -0
  83. package/dist/domain/spec.js.map +1 -0
  84. package/dist/domain/spend.d.ts +84 -0
  85. package/dist/domain/spend.js +109 -0
  86. package/dist/domain/spend.js.map +1 -0
  87. package/dist/domain/state.d.ts +149 -0
  88. package/dist/domain/state.js +182 -0
  89. package/dist/domain/state.js.map +1 -0
  90. package/dist/domain/steps.d.ts +82 -0
  91. package/dist/domain/steps.js +311 -0
  92. package/dist/domain/steps.js.map +1 -0
  93. package/dist/domain/teardown.d.ts +38 -0
  94. package/dist/domain/teardown.js +48 -0
  95. package/dist/domain/teardown.js.map +1 -0
  96. package/dist/domain/verify.d.ts +68 -0
  97. package/dist/domain/verify.js +216 -0
  98. package/dist/domain/verify.js.map +1 -0
  99. package/dist/domain/view.d.ts +24 -0
  100. package/dist/domain/view.js +38 -0
  101. package/dist/domain/view.js.map +1 -0
  102. package/dist/domains/harborOci.d.ts +75 -0
  103. package/dist/domains/harborOci.js +165 -0
  104. package/dist/domains/harborOci.js.map +1 -0
  105. package/dist/index.d.ts +7 -0
  106. package/dist/index.js +6 -0
  107. package/dist/index.js.map +1 -1
  108. package/dist/installer/assisted.d.ts +97 -0
  109. package/dist/installer/assisted.js +171 -0
  110. package/dist/installer/assisted.js.map +1 -0
  111. package/dist/installer/installer.d.ts +86 -0
  112. package/dist/installer/installer.js +15 -0
  113. package/dist/installer/installer.js.map +1 -0
  114. package/dist/prompt.d.ts +33 -0
  115. package/dist/prompt.js +46 -0
  116. package/dist/prompt.js.map +1 -0
  117. package/dist/session.d.ts +2 -0
  118. package/dist/session.js +4 -0
  119. package/dist/session.js.map +1 -1
  120. package/dist/stratus.js +75 -3
  121. package/dist/stratus.js.map +1 -1
  122. package/dist/vfs/domains.d.ts +39 -0
  123. package/dist/vfs/domains.js +128 -0
  124. package/dist/vfs/domains.js.map +1 -0
  125. package/dist/vfs/look.d.ts +10 -0
  126. package/dist/vfs/look.js +43 -8
  127. package/dist/vfs/look.js.map +1 -1
  128. package/dist/vfs/resources.d.ts +136 -0
  129. package/dist/vfs/resources.js +325 -0
  130. package/dist/vfs/resources.js.map +1 -0
  131. package/dist/vfs/tenancy.d.ts +15 -2
  132. package/dist/vfs/tenancy.js +53 -17
  133. package/dist/vfs/tenancy.js.map +1 -1
  134. package/package.json +13 -6
@@ -0,0 +1,37 @@
1
+ import { type CapacityRow, type CommandEnvelope } from '@fnndsc/menu';
2
+ import type { CommandHelp } from '@fnndsc/brasa/core';
3
+ import type { CloudDriver } from '../cloud/driver.js';
4
+ import type { DomainTree } from '../vfs/domains.js';
5
+ /** What `capacity` reads from the session. */
6
+ export interface CapacityCommandContext {
7
+ readonly domains: DomainTree;
8
+ readonly driver: CloudDriver;
9
+ /** The session's region, or null when not connected. */
10
+ readonly region: () => string | null;
11
+ }
12
+ /**
13
+ * The shape family a spec names (`family: E5`), or null.
14
+ *
15
+ * @param spec - The spec's text.
16
+ * @returns The family.
17
+ */
18
+ export declare function specFamily_of(spec: string | null): string | null;
19
+ /**
20
+ * The capacity rows for families in a region.
21
+ *
22
+ * @param driver - The cloud.
23
+ * @param region - The region.
24
+ * @param families - The families.
25
+ * @returns One row per limit and zone, family by family.
26
+ */
27
+ export declare function capacityRows_read(driver: CloudDriver, region: string, families: ReadonlyArray<string>): Promise<CapacityRow[]>;
28
+ /**
29
+ * Runs `capacity`.
30
+ *
31
+ * @param context - The session.
32
+ * @param args - Families, or none for the domains' own.
33
+ * @returns The envelope, with the `stratus.capacity` model.
34
+ */
35
+ export declare function capacity_run(context: CapacityCommandContext, args: ReadonlyArray<string>): Promise<CommandEnvelope>;
36
+ /** `capacity`'s help. */
37
+ export declare const CAPACITY_HELP: CommandHelp;
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @file `capacity`: how much of each limit a shape family draws on is free,
3
+ * per zone, in the session's region (docs/stratus.adoc, D7).
4
+ *
5
+ * The families are the ones named, else the ones the daemon's domains'
6
+ * specs name (`family:`). For each, the region's shapes of that family say
7
+ * which limits they draw on; each limit is read at every zone it is kept in,
8
+ * with what is used and left when the cloud says. The answer carries the
9
+ * `stratus.capacity` model the CAPACITY tile draws.
10
+ *
11
+ * @module
12
+ */
13
+ import chalk from 'chalk';
14
+ import { envelope_error, envelope_ok, STRATUS_CAPACITY_MODEL_KIND } from '@fnndsc/menu';
15
+ /**
16
+ * The shape family a spec names (`family: E5`), or null.
17
+ *
18
+ * @param spec - The spec's text.
19
+ * @returns The family.
20
+ */
21
+ export function specFamily_of(spec) {
22
+ const match = spec?.match(/^family:\s*([A-Za-z0-9.]+)/m) ?? null;
23
+ return match?.[1] ?? null;
24
+ }
25
+ /**
26
+ * The capacity rows for families in a region.
27
+ *
28
+ * @param driver - The cloud.
29
+ * @param region - The region.
30
+ * @param families - The families.
31
+ * @returns One row per limit and zone, family by family.
32
+ */
33
+ export async function capacityRows_read(driver, region, families) {
34
+ const shapes = await driver.shapes_list(region);
35
+ const rows = [];
36
+ for (const family of families) {
37
+ const ofFamily = shapes.filter((shape) => shape.family.toLowerCase() === family.toLowerCase());
38
+ const quotas = new Map();
39
+ for (const shape of ofFamily)
40
+ for (const name of shape.quotaNames)
41
+ quotas.set(name, shape.limitService);
42
+ const byService = new Map();
43
+ for (const [name, service] of quotas) {
44
+ if (!byService.has(service))
45
+ byService.set(service, await driver.limits_list(region, service));
46
+ const limits = (byService.get(service) ?? []).filter((limit) => limit.name === name);
47
+ for (const limit of limits) {
48
+ const availability = await driver.limitAvailability_get(region, limit.service, limit.name, limit.zone);
49
+ rows.push({ family, limit: limit.name, zone: limit.zone ?? null, value: limit.value, used: availability?.used ?? null, available: availability?.available ?? null });
50
+ }
51
+ }
52
+ }
53
+ return rows;
54
+ }
55
+ /** One row as a line. */
56
+ function row_line(row, limitWidth, zoneWidth) {
57
+ const free = row.available === null ? chalk.gray(`${row.value} permitted, use not reported`) : `${row.available} of ${row.value} free`;
58
+ return `${row.family.padEnd(4)} ${row.limit.padEnd(limitWidth)} ${(row.zone ?? 'region').padEnd(zoneWidth)} ${free}`;
59
+ }
60
+ /**
61
+ * Runs `capacity`.
62
+ *
63
+ * @param context - The session.
64
+ * @param args - Families, or none for the domains' own.
65
+ * @returns The envelope, with the `stratus.capacity` model.
66
+ */
67
+ export async function capacity_run(context, args) {
68
+ const region = context.region();
69
+ if (region === null)
70
+ return envelope_error('', undefined, 'capacity: not connected\n');
71
+ const families = args.length > 0
72
+ ? [...args]
73
+ : [...new Set(context.domains.domains_read().map((domain) => specFamily_of(domain.spec)).filter((family) => family !== null))];
74
+ if (families.length === 0)
75
+ return envelope_error('', undefined, 'capacity: name a shape family (capacity E5); no domain\'s spec names one\n');
76
+ const rows = await capacityRows_read(context.driver, region, families);
77
+ const model = { region, rows };
78
+ if (rows.length === 0)
79
+ return envelope_ok(`capacity in ${region}: no limits for ${families.join(', ')}\n`, { kind: STRATUS_CAPACITY_MODEL_KIND, data: model });
80
+ const limitWidth = Math.max(...rows.map((row) => row.limit.length));
81
+ const zoneWidth = Math.max(...rows.map((row) => (row.zone ?? 'region').length));
82
+ const text = [`capacity in ${region}`, ...rows.map((row) => row_line(row, limitWidth, zoneWidth))].join('\n');
83
+ return envelope_ok(`${text}\n`, { kind: STRATUS_CAPACITY_MODEL_KIND, data: model });
84
+ }
85
+ /** `capacity`'s help. */
86
+ export const CAPACITY_HELP = {
87
+ usage: 'capacity [<family>…]',
88
+ summary: 'What the region has free for a shape family, per zone',
89
+ category: 'Resources',
90
+ description: 'For each shape family named (or, with none, each family a domain\'s spec names), the limits its shapes draw on in the session\'s region, at every zone they are kept in: what is permitted and, when the cloud says, how much is free. The same facts are under regions/<region>/limits.',
91
+ examples: ['capacity', 'capacity E5 A1'],
92
+ };
93
+ //# sourceMappingURL=capacity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capacity.js","sourceRoot":"","sources":["../../src/commands/capacity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { type CommandEnvelope, type DomainSummary } from '@fnndsc/menu';
2
+ import type { CommandGroup, CommandHelp } from '@fnndsc/brasa/core';
3
+ import type { CloudDriver } from '../cloud/driver.js';
4
+ import type { HarborDomain } from '../domains/harborOci.js';
5
+ import type { DomainTree } from '../vfs/domains.js';
6
+ import { type BuildCommandContext } from './build.js';
7
+ /** What `domain` reads from the session. */
8
+ export interface DomainCommandContext {
9
+ readonly domains: DomainTree;
10
+ readonly driver: CloudDriver;
11
+ /** The session's region, or null when not connected. */
12
+ readonly region: () => string | null;
13
+ /** The folder the domains stand in (`/net/oci/<tenancy>/domains`). */
14
+ readonly domainsPath: () => string;
15
+ /** What the build verbs run over; absent, `new`, `plan` and `build` refuse. */
16
+ readonly build?: BuildCommandContext;
17
+ }
18
+ /**
19
+ * One domain's status: its lines, and its summary for the model.
20
+ *
21
+ * @param context - The session.
22
+ * @param domain - The domain.
23
+ * @returns The lines and the summary.
24
+ */
25
+ export declare function domainStatus_read(context: DomainCommandContext, domain: HarborDomain): Promise<{
26
+ lines: string[];
27
+ summary: DomainSummary;
28
+ }>;
29
+ /**
30
+ * Runs `domain`.
31
+ *
32
+ * @param context - The session.
33
+ * @param args - The words after `domain`.
34
+ * @returns The envelope.
35
+ */
36
+ export declare function domain_run(context: DomainCommandContext, args: ReadonlyArray<string>): Promise<CommandEnvelope>;
37
+ /** `domain`'s help. */
38
+ export declare const DOMAIN_HELP: CommandHelp;
39
+ /**
40
+ * The stratus backend's commands: `domain` and `capacity`.
41
+ *
42
+ * @param context - The session.
43
+ * @returns The group to register as the backend's.
44
+ */
45
+ export declare function stratusCommands_make(context: DomainCommandContext): CommandGroup;
@@ -0,0 +1,150 @@
1
+ /**
2
+ * @file `domain`: where each Trusted Domain's build stands (docs/stratus.adoc, D7).
3
+ *
4
+ * `domain status [<name>]` prints, per domain, its cluster, its checkout,
5
+ * each step with its state and the evidence for it, and how many live
6
+ * resources its compartment holds in the session's region. A bare `domain`
7
+ * is `domain status` for every domain. `new`, `plan`, `build` and `adopt`
8
+ * are in `build.ts`, `verify` in `verify.ts`; any other verb is refused by name.
9
+ *
10
+ * @module
11
+ */
12
+ import chalk from 'chalk';
13
+ import { envelope_error, envelope_ok, STRATUS_DOMAINS_MODEL_KIND } from '@fnndsc/menu';
14
+ import { stateTone_paint } from '../vfs/look.js';
15
+ import { lastDone_of } from '../domains/harborOci.js';
16
+ import { capacity_run, CAPACITY_HELP } from './capacity.js';
17
+ import { spend_line, spend_read } from '../domain/spend.js';
18
+ import { spend_run, SPEND_HELP } from './spend.js';
19
+ import { domainAdopt_run, domainBuild_run, domainNew_run, domainPlan_run } from './build.js';
20
+ import { domainVerify_run, verifyReach_default } from './verify.js';
21
+ import { domainTeardown_run } from './teardown.js';
22
+ /** The order the counted kinds are said in. */
23
+ const COUNT_ORDER = ['instances', 'networks', 'subnets', 'securitygroups', 'loadbalancers', 'volumes', 'buckets', 'dns'];
24
+ /**
25
+ * A compartment's live resources, and the line that says them or why they
26
+ * could not be counted.
27
+ *
28
+ * @param context - The session.
29
+ * @param compartmentId - The compartment, from the domain's settings.
30
+ * @returns The counts (null when not counted) and the line.
31
+ */
32
+ async function compartment_count(context, compartmentId) {
33
+ const region = context.region();
34
+ if (compartmentId === undefined)
35
+ return { counts: null, line: 'compartment not in the domain\'s settings' };
36
+ if (region === null)
37
+ return { counts: null, line: 'compartment not counted: not connected' };
38
+ try {
39
+ const counts = await context.driver.resources_search(compartmentId, region);
40
+ const said = COUNT_ORDER.filter((kind) => (counts[kind] ?? 0) > 0).map((kind) => `${counts[kind]} ${kind}`);
41
+ return { counts, line: `compartment ${said.length > 0 ? said.join(', ') : 'nothing live'} (${region})` };
42
+ }
43
+ catch (error) {
44
+ return { counts: null, line: `compartment not counted: ${error instanceof Error ? error.message : String(error)}` };
45
+ }
46
+ }
47
+ /**
48
+ * What a domain costs, and the line that says it or why it is not priced.
49
+ *
50
+ * @param context - The session.
51
+ * @param domain - The domain.
52
+ * @returns The spend (null when not priced) and the line.
53
+ */
54
+ async function domainCost_read(context, domain) {
55
+ const compartmentId = domain.settings['OCI_COMPARTMENT_OCID'];
56
+ const region = domain.settings['OCI_REGION'] ?? context.region();
57
+ if (compartmentId === undefined || region === null)
58
+ return { spend: null, line: 'cost not priced: no compartment known' };
59
+ try {
60
+ const spend = await spend_read(context.driver, compartmentId, region, new Date());
61
+ return { spend, line: `cost ${spend_line(spend)}` };
62
+ }
63
+ catch (error) {
64
+ return { spend: null, line: `cost not priced: ${error instanceof Error ? error.message : String(error)}` };
65
+ }
66
+ }
67
+ /**
68
+ * One domain's status: its lines, and its summary for the model.
69
+ *
70
+ * @param context - The session.
71
+ * @param domain - The domain.
72
+ * @returns The lines and the summary.
73
+ */
74
+ export async function domainStatus_read(context, domain) {
75
+ const width = Math.max(...domain.steps.map((step) => step.folder.length));
76
+ const [compartment, cost] = await Promise.all([compartment_count(context, domain.settings['OCI_COMPARTMENT_OCID']), domainCost_read(context, domain)]);
77
+ const lines = [
78
+ `${chalk.bold(domain.name)} ${domain.cluster ?? '(no cluster name in its settings)'}`,
79
+ `${domain.origin !== 'built' ? 'checkout ' : domain.state?.adopted !== undefined ? 'adopted ' : domain.state?.gone !== undefined ? 'torn down ' : 'built here '} ${domain.root}`,
80
+ ...domain.steps.map((step) => ` ${step.folder.padEnd(width)} ${stateTone_paint(step.state, step.state.padEnd(8))} ${chalk.gray(step.evidence)}`),
81
+ compartment.line,
82
+ cost.line,
83
+ ];
84
+ const summary = {
85
+ name: domain.name,
86
+ path: `${context.domainsPath()}/${domain.name}`,
87
+ cluster: domain.cluster,
88
+ lastDone: lastDone_of(domain)?.folder ?? null,
89
+ steps: domain.steps.map((step) => ({ folder: step.folder, state: step.state })),
90
+ resources: compartment.counts === null ? null : { ...compartment.counts },
91
+ cost: cost.spend === null ? null : { hourly: cost.spend.hourly, soFar: cost.spend.soFar, currency: cost.spend.currency },
92
+ };
93
+ return { lines, summary };
94
+ }
95
+ /**
96
+ * Runs `domain`.
97
+ *
98
+ * @param context - The session.
99
+ * @param args - The words after `domain`.
100
+ * @returns The envelope.
101
+ */
102
+ export async function domain_run(context, args) {
103
+ const [verb = 'status', ...rest] = args;
104
+ const builds = { new: domainNew_run, plan: domainPlan_run, build: domainBuild_run, adopt: domainAdopt_run, teardown: domainTeardown_run, verify: (build, words) => domainVerify_run(build, build.verifyReach ?? verifyReach_default(), words) };
105
+ const build = builds[verb];
106
+ if (build !== undefined)
107
+ return context.build === undefined ? envelope_error('', undefined, `domain: ${verb}: this session builds no domains\n`) : build(context.build, rest);
108
+ if (verb !== 'status')
109
+ return envelope_error('', undefined, `domain: ${verb}: not a verb this session has yet (domain status, new, plan, build, adopt, verify, teardown)\n`);
110
+ const all = context.domains.domains_read();
111
+ if (all.length === 0)
112
+ return envelope_ok('no domains: domain new <name> makes one; stratus --domain <name>=<harbor-oci checkout> reads one\n', { kind: STRATUS_DOMAINS_MODEL_KIND, data: { domains: [] } });
113
+ const chosen = rest.length === 0 ? all : all.filter((domain) => rest.includes(domain.name));
114
+ const missing = rest.filter((name) => !all.some((domain) => domain.name === name));
115
+ if (missing.length > 0)
116
+ return envelope_error('', undefined, `domain: ${missing.join(', ')}: no such domain (${all.map((domain) => domain.name).join(', ')})\n`);
117
+ const blocks = [];
118
+ const model = { domains: [] };
119
+ for (const domain of chosen) {
120
+ const read = await domainStatus_read(context, domain);
121
+ blocks.push(read.lines.join('\n'));
122
+ model.domains.push(read.summary);
123
+ }
124
+ return envelope_ok(`${blocks.join('\n\n')}\n`, { kind: STRATUS_DOMAINS_MODEL_KIND, data: model });
125
+ }
126
+ /** `domain`'s help. */
127
+ export const DOMAIN_HELP = {
128
+ usage: 'domain [status [<name>…]] | domain new <name> [options] | domain plan [<name>] | domain build [<name>] [--through <step>] | domain adopt <name> --from <checkout> | domain verify [<name>]',
129
+ summary: 'Make, plan, build, and see where each Trusted Domain stands',
130
+ category: 'Resources',
131
+ description: 'domain status prints each domain: those this daemon builds, and those read from a harbor-oci checkout (stratus --domain <name>=<checkout>), with its cluster, each build step with its state and the evidence for it, and its compartment\'s live resources in the session\'s region. A bare domain is domain status for every domain. domain new writes a domain\'s spec and nothing else (--family E5, --plane 3x8/24, --workers 2x8/32 as count x vCPU / GiB, --data, --database, --queue in GiB, --base-domain zone). domain plan reads only: whether the spec fits each availability domain, what it costs an hour, where the steps stand; the infrastructure plan needs the tasks tier. domain build runs the steps from the first not done as a task (/proc/steps/<name>-build) and follows it; before the first step that bills it asks, with the plan\'s counts and the cost. Ctrl-C stops following, not the build: wait <name>-build follows it again, kill <name>-build asks it to stop. domain adopt keeps a domain harbor-oci built and, with the tasks tier, takes its stack and state into the cloud\'s Resource Manager; an adopted domain is planned against, never built on. domain verify runs ten checks against the cluster through its kubeconfig, which stays on the host: nine read, and the block-volume probe, which makes a claim and a pod, runs only with the tasks tier. The domain\'s files are under ~ (domains/<name>/); its credentials stay on the host.',
132
+ examples: ['domain', 'domain new trial --workers 2x8/32 --data 100', 'domain plan trial', 'domain build trial --through infra-plan', 'domain build trial', 'domain adopt harbor --from ~/src/harbor-oci', 'domain verify harbor', 'cat ~/harbor/steps/05-infra-apply/evidence'],
133
+ };
134
+ /**
135
+ * The stratus backend's commands: `domain` and `capacity`.
136
+ *
137
+ * @param context - The session.
138
+ * @returns The group to register as the backend's.
139
+ */
140
+ export function stratusCommands_make(context) {
141
+ return {
142
+ envelope: {
143
+ domain: (args) => domain_run(context, args),
144
+ capacity: (args) => capacity_run(context, args),
145
+ spend: (args) => spend_run(context, args),
146
+ },
147
+ help: { domain: DOMAIN_HELP, capacity: CAPACITY_HELP, spend: SPEND_HELP },
148
+ };
149
+ }
150
+ //# sourceMappingURL=domain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain.js","sourceRoot":"","sources":["../../src/commands/domain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type CommandEnvelope } from '@fnndsc/menu';
2
+ import type { CommandHelp } from '@fnndsc/brasa/core';
3
+ import { type Spend } from '../domain/spend.js';
4
+ import type { DomainCommandContext } from './domain.js';
5
+ /** `spend`'s help. */
6
+ export declare const SPEND_HELP: CommandHelp;
7
+ /**
8
+ * One domain's spend as lines.
9
+ *
10
+ * @param name - The domain.
11
+ * @param spend - Its spend.
12
+ * @returns The lines.
13
+ */
14
+ export declare function spend_lines(name: string, spend: Spend): string[];
15
+ /**
16
+ * Runs `spend`.
17
+ *
18
+ * @param context - The session.
19
+ * @param args - The domains' names.
20
+ * @returns The envelope.
21
+ */
22
+ export declare function spend_run(context: DomainCommandContext, args: ReadonlyArray<string>): Promise<CommandEnvelope>;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @file `spend [<name>…]`: what each domain costs, resource by resource, at
3
+ * list price: an hour, and since each resource was made (docs/stratus.adoc,
4
+ * D7; `harbor-oci`'s `burn`).
5
+ *
6
+ * @module
7
+ */
8
+ import chalk from 'chalk';
9
+ import { envelope_error, envelope_ok } from '@fnndsc/menu';
10
+ import { money_words, spend_line, spend_read } from '../domain/spend.js';
11
+ /** `spend`'s help. */
12
+ export const SPEND_HELP = {
13
+ usage: 'spend [<name>…]',
14
+ summary: 'What each Trusted Domain costs, an hour and so far',
15
+ category: 'Resources',
16
+ description: 'Prices every live resource in each domain\'s compartment at list price: machines by vCPU and memory while they run, volumes by size and performance, load balancers by the hour and their minimum bandwidth. Prints each with its rate an hour and what it has come to since it was made, then the domain\'s total. An estimate, not the bill: discounts, free tiers and traffic are not in it. Bare, every domain.',
17
+ examples: ['spend', 'spend harbor'],
18
+ };
19
+ /**
20
+ * One domain's spend as lines.
21
+ *
22
+ * @param name - The domain.
23
+ * @param spend - Its spend.
24
+ * @returns The lines.
25
+ */
26
+ export function spend_lines(name, spend) {
27
+ const nameWidth = Math.max(4, ...spend.items.map((item) => item.name.length));
28
+ const rate = (amount, unit = '') => (amount === null ? 'not priced' : `${money_words(amount, spend.currency)}${unit}`);
29
+ return [
30
+ chalk.bold(name),
31
+ ...spend.items.map((item) => ` ${item.kind.padEnd(15)} ${item.name.padEnd(nameWidth)} ${rate(item.hourly, '/h').padStart(10)} ${rate(item.soFar, ' so far').padStart(17)} ${chalk.gray(item.detail)}`),
32
+ ` ${chalk.yellow(spend_line(spend))}`,
33
+ ];
34
+ }
35
+ /**
36
+ * Runs `spend`.
37
+ *
38
+ * @param context - The session.
39
+ * @param args - The domains' names.
40
+ * @returns The envelope.
41
+ */
42
+ export async function spend_run(context, args) {
43
+ const flag = args.find((word) => word.startsWith('-'));
44
+ if (flag !== undefined)
45
+ return envelope_error('', undefined, `spend: ${flag}: unknown option\n`);
46
+ const all = context.domains.domains_read();
47
+ const missing = args.filter((name) => !all.some((domain) => domain.name === name));
48
+ if (missing.length > 0)
49
+ return envelope_error('', undefined, `spend: ${missing.join(', ')}: no such domain\n`);
50
+ const chosen = args.length === 0 ? all : all.filter((domain) => args.includes(domain.name));
51
+ if (chosen.length === 0)
52
+ return envelope_ok('no domains\n');
53
+ const blocks = [];
54
+ for (const domain of chosen) {
55
+ const compartmentId = domain.settings['OCI_COMPARTMENT_OCID'];
56
+ const region = domain.settings['OCI_REGION'] ?? context.region();
57
+ if (compartmentId === undefined || region === null) {
58
+ blocks.push(`${chalk.bold(domain.name)}\n ${chalk.gray('not priced: no compartment known')}`);
59
+ continue;
60
+ }
61
+ blocks.push(spend_lines(domain.name, await spend_read(context.driver, compartmentId, region, new Date())).join('\n'));
62
+ }
63
+ return envelope_ok(`${blocks.join('\n\n')}\n${chalk.gray('List prices: an estimate, not the bill.')}\n`);
64
+ }
65
+ //# sourceMappingURL=spend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spend.js","sourceRoot":"","sources":["../../src/commands/spend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { type CommandEnvelope } from '@fnndsc/menu';
2
+ import { type BuildCommandContext } from './build.js';
3
+ /**
4
+ * `domain teardown <name>`.
5
+ *
6
+ * @param context - The session.
7
+ * @param args - The words after `teardown`.
8
+ * @returns The envelope.
9
+ */
10
+ export declare function domainTeardown_run(context: BuildCommandContext, args: ReadonlyArray<string>): Promise<CommandEnvelope>;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @file `domain teardown <name>`: removes what a domain built here, after
3
+ * showing what goes and asking for the domain's name (docs/stratus.adoc, D6).
4
+ *
5
+ * @module
6
+ */
7
+ import { readFileSync } from 'node:fs';
8
+ import chalk from 'chalk';
9
+ import { envelope_error, envelope_ok } from '@fnndsc/menu';
10
+ import { repl_question, sink_dataLine, surface_get } from '@fnndsc/brasa/core';
11
+ import { clusterVolumes_read, teardownRun_make } from '../domain/teardown.js';
12
+ import { job_runFollowed } from './build.js';
13
+ import { verifyReach_default } from './verify.js';
14
+ /**
15
+ * `domain teardown <name>`.
16
+ *
17
+ * @param context - The session.
18
+ * @param args - The words after `teardown`.
19
+ * @returns The envelope.
20
+ */
21
+ export async function domainTeardown_run(context, args) {
22
+ if (args.length !== 1 || args[0].startsWith('-'))
23
+ return envelope_error('', undefined, 'domain teardown: usage: domain teardown <name>\n');
24
+ const name = args[0];
25
+ const domain = context.domains.domain_read(name);
26
+ const record = context.store.record_read(name);
27
+ if (domain === null)
28
+ return envelope_error('', undefined, `domain teardown: ${name}: no such domain\n`);
29
+ if (domain.origin !== 'built' || record === null)
30
+ return envelope_error('', undefined, `domain teardown: ${name}: Operation not permitted: read from a harbor-oci checkout, not built here\n`);
31
+ if (record.adopted !== undefined)
32
+ return envelope_error('', undefined, `domain teardown: ${name}: Operation not permitted: adopted, not built here\n`);
33
+ if (record.gone !== undefined)
34
+ return envelope_ok(`${name}: already torn down (${record.gone.slice(0, 16)})\n`);
35
+ const builder = context.builder;
36
+ if (builder === null || builder.teardown_run === undefined)
37
+ return envelope_error('', undefined, 'domain teardown: this cloud cannot tear a domain down yet\n');
38
+ if (surface_get().capabilities.tasks !== true)
39
+ return envelope_error('', undefined, `domain teardown: ${name}: Operation not permitted: tearing down needs the tasks tier\n`);
40
+ // The cluster names its own volumes; read before the destroy takes it away.
41
+ let volumeIds = [];
42
+ const kubeconfig = domain.secrets.find((secret) => secret.name === 'kubeconfig');
43
+ if (kubeconfig !== undefined) {
44
+ try {
45
+ volumeIds = await clusterVolumes_read((context.verifyReach ?? verifyReach_default()).kube_make(readFileSync(kubeconfig.hostPath, 'utf-8')));
46
+ }
47
+ catch (error) {
48
+ return envelope_error('', undefined, `domain teardown: ${name}: cannot read the cluster's volumes (${error instanceof Error ? error.message : String(error)}): refusing, they would be left billing\n`);
49
+ }
50
+ }
51
+ const stackRef = record.ids['stackRef'];
52
+ const inStack = stackRef !== undefined && builder.stackResources_count !== undefined ? await builder.stackResources_count({ region: record.region, stackRef }) : null;
53
+ const lines = [
54
+ `${chalk.bold(name)} ${name}.${record.baseDomain} teardown`,
55
+ ` ${chalk.red('−')} ${stackRef === undefined ? 'no stack: nothing was applied' : `the stack's ${inStack ?? '?'} resources, by a destroy job`}`,
56
+ ` ${chalk.red('−')} the DNS records api, api-int and *.apps`,
57
+ ...(record.ids['isoObject'] !== undefined ? [` ${chalk.red('−')} the image ${record.ids['isoObject']} and its link`] : []),
58
+ ` ${chalk.red('−')} ${volumeIds.length} volume${volumeIds.length === 1 ? '' : 's'} the cluster made for its claims${kubeconfig === undefined ? ' (no cluster to ask)' : ''}`,
59
+ ...(record.ids['clusterId'] !== undefined ? [` ${chalk.red('−')} the installer's cluster and infra-env`] : []),
60
+ chalk.gray(' Nothing else in the compartment is touched.'),
61
+ ];
62
+ for (const line of lines)
63
+ sink_dataLine(line);
64
+ const answer = (await repl_question(`Destroy what ${name} built? Its data goes with it; billing stops. Type the domain's name to go on:`)).trim();
65
+ if (answer !== name)
66
+ return envelope_ok(`${chalk.gray(`not torn down: '${answer}' is not ${name}`)}\n`);
67
+ const ran = await job_runFollowed(`${name}-teardown`, `teardown ${name}`, teardownRun_make(context.store, builder, context.deps?.installer ?? null, name, volumeIds));
68
+ if ('error' in ran)
69
+ return envelope_error('', undefined, `domain teardown: ${ran.error}\n`);
70
+ return envelope_ok(`${name}: torn down\n`);
71
+ }
72
+ //# sourceMappingURL=teardown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teardown.js","sourceRoot":"","sources":["../../src/commands/teardown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type CommandEnvelope } from '@fnndsc/menu';
2
+ import { type KubeApi } from '../cluster/kube.js';
3
+ import type { BuildCommandContext } from './build.js';
4
+ /** The resolver `verify` asks, as `harbor-oci` did: one outside the tenancy. */
5
+ export declare const PUBLIC_RESOLVER: string;
6
+ /** What `verify` reaches the cluster and the world with; a test hands in its own. */
7
+ export interface VerifyReach {
8
+ readonly kube_make: (kubeconfig: string) => KubeApi;
9
+ readonly resolve: (name: string) => Promise<string[]>;
10
+ readonly https_status: (url: string, ca: string | null) => Promise<number>;
11
+ readonly probeTimeoutMs: number;
12
+ readonly pollMs: number;
13
+ }
14
+ /**
15
+ * The reach over the network: the Kubernetes API, a public resolver, HTTPS.
16
+ *
17
+ * @returns The reach.
18
+ */
19
+ export declare function verifyReach_default(): VerifyReach;
20
+ /**
21
+ * `domain verify [<name>]`.
22
+ *
23
+ * @param context - The session.
24
+ * @param reach - How the checks reach the cluster.
25
+ * @param args - The words after `verify`.
26
+ * @returns The envelope: failed when a check failed.
27
+ */
28
+ export declare function domainVerify_run(context: BuildCommandContext, reach: VerifyReach, args: ReadonlyArray<string>): Promise<CommandEnvelope>;