@fnndsc/stratus 0.1.0 → 0.2.1

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,136 @@
1
+ /**
2
+ * @file A container's resources as folders: `<container>/<kind>/<name>/…`
3
+ * (docs/stratus.adoc, D4 and D5).
4
+ *
5
+ * Beside its child containers, every container level holds one folder per
6
+ * resource kind (`instances networks loadbalancers volumes buckets dns`),
7
+ * listing the session's region (DNS is global). A resource is a folder of
8
+ * field files: `name id state region created tags info.json` for every kind,
9
+ * plus the kind's own (an instance `shape zone ips`, a volume `size
10
+ * attached`, a load balancer `ip shape`). A network holds `subnets/` and
11
+ * `securitygroups/`; a bucket holds `objects/`, its objects as files (a `/`
12
+ * in an object's name is a folder), and `links`, its pre-authenticated
13
+ * links; a DNS zone holds `records/`, a file per record name whose text is
14
+ * the record set as zone-file lines (the apex is `@`).
15
+ *
16
+ * Duplicate display names wear `~<id6>` (`names.ts`). Every answer is kept
17
+ * for the cache's life. The tree reads only: object bytes are read, never
18
+ * written (D6).
19
+ *
20
+ * @module
21
+ */
22
+ import type { VFSItem } from '@fnndsc/fond';
23
+ import type { CloudDriver, CloudRecord, ResourceKind } from '../cloud/driver.js';
24
+ import type { AnswerCache } from '../cache.js';
25
+ /** The kind folders a container level holds, in listing order. */
26
+ export declare const KIND_FOLDERS: ReadonlyArray<ResourceKind>;
27
+ /**
28
+ * Whether a path segment is a container level's kind folder.
29
+ *
30
+ * @param segment - The segment.
31
+ * @returns True for `instances networks loadbalancers volumes buckets dns`.
32
+ */
33
+ export declare function kindFolder_is(segment: string | undefined): segment is ResourceKind;
34
+ /** The kind folders a network holds. */
35
+ export declare const NETWORK_FOLDERS: ReadonlyArray<ResourceKind>;
36
+ /** The type word a resource of each kind wears in `ls -l` (D5). */
37
+ export declare const RESOURCE_TYPES: Readonly<Record<ResourceKind, string>>;
38
+ /** The largest object `cat` reads through the tree, in bytes. */
39
+ export declare const OBJECT_READ_LIMIT: number;
40
+ /** What a path under a container's kind folders came to. */
41
+ export type ResourceNode = {
42
+ readonly kind: 'listing';
43
+ readonly list: () => Promise<VFSItem[]>;
44
+ } | {
45
+ readonly kind: 'file';
46
+ readonly text: string;
47
+ } | {
48
+ readonly kind: 'bytes';
49
+ readonly size: number;
50
+ readonly read: () => Promise<Buffer>;
51
+ } | {
52
+ readonly kind: 'refused';
53
+ readonly reason: string;
54
+ readonly errno?: 'EPERM' | 'EACCES';
55
+ } | {
56
+ readonly kind: 'missing';
57
+ readonly reason?: string;
58
+ };
59
+ /** How the resource tree is made. */
60
+ export interface ResourceTreeOptions {
61
+ readonly driver: CloudDriver;
62
+ readonly cache: AnswerCache;
63
+ /** The clock for dates the cloud does not give. */
64
+ readonly now: () => string;
65
+ }
66
+ /** The resources of containers, as folders. */
67
+ export declare class ResourceTree {
68
+ private readonly driver;
69
+ private readonly cache;
70
+ private readonly now;
71
+ constructor(options: ResourceTreeOptions);
72
+ private kind_list;
73
+ private counts_get;
74
+ private objects_list;
75
+ private links_list;
76
+ private records_list;
77
+ /**
78
+ * The kind folders of a container level, each counting its resources by
79
+ * one search; a search that fails leaves the counts out, never the folders.
80
+ *
81
+ * @param containerId - The container.
82
+ * @param region - The session's region.
83
+ * @returns One folder item per kind.
84
+ */
85
+ kindFolders_items(containerId: string, region: string): Promise<VFSItem[]>;
86
+ private kindFolder_item;
87
+ /**
88
+ * The node a path names below a container level.
89
+ *
90
+ * @param containerId - The container whose level the path starts at.
91
+ * @param region - The session's region.
92
+ * @param segments - The path's segments from the kind folder on.
93
+ * @param owner - Who rows are shown as owned by.
94
+ * @returns The node.
95
+ */
96
+ node_resolve(containerId: string, region: string, segments: ReadonlyArray<string>, owner: string): Promise<ResourceNode>;
97
+ /** The node inside one resource. */
98
+ private resourceNode_resolve;
99
+ /** The folders a resource of a kind holds beside its fields. */
100
+ private innerFolders_of;
101
+ /** The folder items a resource holds beside its fields, counted. */
102
+ private innerFolder_items;
103
+ /** A network's subnets or security groups. */
104
+ private networkMembers_list;
105
+ /** The node inside a resource's own folder (`subnets/`, `objects/`, `records/`). */
106
+ private innerNode_resolve;
107
+ /** A path inside a bucket's `objects/`: a `/` in an object's name is a folder. */
108
+ private objectNode_resolve;
109
+ /** One level of a bucket's objects: files, and folders for the next `/`. */
110
+ private objectLevel_items;
111
+ /** A path inside a DNS zone's `records/`. */
112
+ private recordNode_resolve;
113
+ /** A kind's resources as rows. */
114
+ private resources_items;
115
+ private file_item;
116
+ /** Every field a resource of a kind has, in the order a listing shows them. */
117
+ private fields_of;
118
+ /** What a volume is attached to: the instance's name when it is in the same container, else its id, else `no`. */
119
+ private attachedName_of;
120
+ }
121
+ /** One record name's set: its file name, its types, its zone-file lines. */
122
+ interface RecordSet {
123
+ readonly name: string;
124
+ readonly types: string[];
125
+ readonly text: string;
126
+ }
127
+ /**
128
+ * A zone's records grouped by name: a file per name, relative to the zone,
129
+ * the apex as `@`, each holding its records as zone-file lines.
130
+ *
131
+ * @param records - The zone's records.
132
+ * @param zone - The zone's name.
133
+ * @returns The sets, sorted by name.
134
+ */
135
+ export declare function recordSets_of(records: ReadonlyArray<CloudRecord>, zone: string): RecordSet[];
136
+ export {};
@@ -0,0 +1,325 @@
1
+ import { UNCOUNTED } from './look.js';
2
+ import { ambiguity_words, segment_resolve, segments_assign } from '../names.js';
3
+ /** The kind folders a container level holds, in listing order. */
4
+ export const KIND_FOLDERS = ['instances', 'networks', 'loadbalancers', 'volumes', 'buckets', 'dns'];
5
+ /**
6
+ * Whether a path segment is a container level's kind folder.
7
+ *
8
+ * @param segment - The segment.
9
+ * @returns True for `instances networks loadbalancers volumes buckets dns`.
10
+ */
11
+ export function kindFolder_is(segment) {
12
+ return KIND_FOLDERS.some((kind) => kind === segment);
13
+ }
14
+ /** The kind folders a network holds. */
15
+ export const NETWORK_FOLDERS = ['subnets', 'securitygroups'];
16
+ /** The type word a resource of each kind wears in `ls -l` (D5). */
17
+ export const RESOURCE_TYPES = {
18
+ instances: 'instance', networks: 'network', subnets: 'subnet', securitygroups: 'securitygroup',
19
+ loadbalancers: 'loadbalancer', volumes: 'volume', buckets: 'bucket', dns: 'dnszone',
20
+ };
21
+ /** The largest object `cat` reads through the tree, in bytes. */
22
+ export const OBJECT_READ_LIMIT = 16 * 1024 * 1024;
23
+ /** The resources of containers, as folders. */
24
+ export class ResourceTree {
25
+ driver;
26
+ cache;
27
+ now;
28
+ constructor(options) {
29
+ this.driver = options.driver;
30
+ this.cache = options.cache;
31
+ this.now = options.now;
32
+ }
33
+ // ---- the cloud, cached ----
34
+ kind_list(kind, containerId, region) {
35
+ const driver = this.driver;
36
+ const asks = {
37
+ instances: () => driver.instances_list(containerId, region),
38
+ networks: () => driver.networks_list(containerId, region),
39
+ subnets: () => driver.subnets_list(containerId, region),
40
+ securitygroups: () => driver.securitygroups_list(containerId, region),
41
+ loadbalancers: () => driver.loadbalancers_list(containerId, region),
42
+ volumes: () => driver.volumes_list(containerId, region),
43
+ buckets: () => driver.buckets_list(containerId, region),
44
+ dns: () => driver.dns_list(containerId, region),
45
+ };
46
+ return this.cache.answer_get(`${kind}/${containerId}/${region}`, asks[kind]);
47
+ }
48
+ counts_get(containerId, region) {
49
+ return this.cache.answer_get(`search/${containerId}/${region}`, () => this.driver.resources_search(containerId, region));
50
+ }
51
+ objects_list(bucket, region) {
52
+ return this.cache.answer_get(`objects/${bucket}/${region}`, () => this.driver.objects_list(bucket, region));
53
+ }
54
+ links_list(bucket, region) {
55
+ return this.cache.answer_get(`links/${bucket}/${region}`, () => this.driver.links_list(bucket, region));
56
+ }
57
+ records_list(zoneId, region) {
58
+ return this.cache.answer_get(`records/${zoneId}`, () => this.driver.records_list(zoneId, region));
59
+ }
60
+ // ---- a container level ----
61
+ /**
62
+ * The kind folders of a container level, each counting its resources by
63
+ * one search; a search that fails leaves the counts out, never the folders.
64
+ *
65
+ * @param containerId - The container.
66
+ * @param region - The session's region.
67
+ * @returns One folder item per kind.
68
+ */
69
+ async kindFolders_items(containerId, region) {
70
+ let counts = {};
71
+ let counted = true;
72
+ try {
73
+ counts = await this.counts_get(containerId, region);
74
+ }
75
+ catch {
76
+ counted = false;
77
+ }
78
+ return KIND_FOLDERS.map((kind) => this.kindFolder_item(kind, counted ? (counts[kind] ?? 0) : null));
79
+ }
80
+ kindFolder_item(name, count) {
81
+ return { name, type: 'kind', size: count ?? 0, owner: 'cloud', date: this.now(), ...(count === null ? { status: UNCOUNTED } : {}) };
82
+ }
83
+ /**
84
+ * The node a path names below a container level.
85
+ *
86
+ * @param containerId - The container whose level the path starts at.
87
+ * @param region - The session's region.
88
+ * @param segments - The path's segments from the kind folder on.
89
+ * @param owner - Who rows are shown as owned by.
90
+ * @returns The node.
91
+ */
92
+ async node_resolve(containerId, region, segments, owner) {
93
+ const [kindName, resourceSegment, ...rest] = segments;
94
+ if (!kindFolder_is(kindName))
95
+ return { kind: 'missing' };
96
+ const kind = kindName;
97
+ const resources = await this.kind_list(kind, containerId, region);
98
+ if (resourceSegment === undefined)
99
+ return { kind: 'listing', list: async () => this.resources_items(kind, resources, owner) };
100
+ const match = segment_resolve(resources, resourceSegment);
101
+ if (match.kind === 'ambiguous')
102
+ return { kind: 'missing', reason: ambiguity_words(resourceSegment, match.segments) };
103
+ if (match.kind === 'none')
104
+ return { kind: 'missing' };
105
+ return this.resourceNode_resolve(kind, match.item, containerId, region, rest, owner);
106
+ }
107
+ /** The node inside one resource. */
108
+ async resourceNode_resolve(kind, resource, containerId, region, segments, owner) {
109
+ const fields = await this.fields_of(kind, resource, containerId, region);
110
+ const folders = this.innerFolders_of(kind);
111
+ if (segments.length === 0) {
112
+ return {
113
+ kind: 'listing',
114
+ list: async () => [
115
+ ...fields.map((field) => this.file_item(field.name, Buffer.byteLength(field.text), owner)),
116
+ ...(await this.innerFolder_items(kind, resource, containerId, region)),
117
+ ],
118
+ };
119
+ }
120
+ const [head, ...rest] = segments;
121
+ if (folders.includes(head))
122
+ return this.innerNode_resolve(kind, head, resource, containerId, region, rest, owner);
123
+ if (rest.length > 0)
124
+ return { kind: 'missing' };
125
+ const field = fields.find((entry) => entry.name === head);
126
+ return field === undefined ? { kind: 'missing' } : { kind: 'file', text: field.text };
127
+ }
128
+ /** The folders a resource of a kind holds beside its fields. */
129
+ innerFolders_of(kind) {
130
+ if (kind === 'networks')
131
+ return [...NETWORK_FOLDERS];
132
+ if (kind === 'buckets')
133
+ return ['objects'];
134
+ if (kind === 'dns')
135
+ return ['records'];
136
+ return [];
137
+ }
138
+ /** The folder items a resource holds beside its fields, counted. */
139
+ async innerFolder_items(kind, resource, containerId, region) {
140
+ if (kind === 'networks') {
141
+ const items = [];
142
+ for (const inner of NETWORK_FOLDERS)
143
+ items.push(this.kindFolder_item(inner, (await this.networkMembers_list(inner, resource.id, containerId, region)).length));
144
+ return items;
145
+ }
146
+ if (kind === 'buckets')
147
+ return [this.kindFolder_item('objects', (await this.objects_list(resource.name, region)).length)];
148
+ if (kind === 'dns')
149
+ return [this.kindFolder_item('records', recordSets_of(await this.records_list(resource.id, region), resource.name).length)];
150
+ return [];
151
+ }
152
+ /** A network's subnets or security groups. */
153
+ async networkMembers_list(inner, networkId, containerId, region) {
154
+ const members = await this.kind_list(inner, containerId, region);
155
+ return members.filter((member) => member.networkId === networkId);
156
+ }
157
+ /** The node inside a resource's own folder (`subnets/`, `objects/`, `records/`). */
158
+ async innerNode_resolve(kind, folder, resource, containerId, region, segments, owner) {
159
+ if (kind === 'networks') {
160
+ const inner = folder === 'subnets' ? 'subnets' : 'securitygroups';
161
+ const members = await this.networkMembers_list(inner, resource.id, containerId, region);
162
+ if (segments.length === 0)
163
+ return { kind: 'listing', list: async () => this.resources_items(inner, members, owner) };
164
+ const match = segment_resolve(members, segments[0]);
165
+ if (match.kind === 'ambiguous')
166
+ return { kind: 'missing', reason: ambiguity_words(segments[0], match.segments) };
167
+ if (match.kind === 'none')
168
+ return { kind: 'missing' };
169
+ return this.resourceNode_resolve(inner, match.item, containerId, region, segments.slice(1), owner);
170
+ }
171
+ if (kind === 'buckets')
172
+ return this.objectNode_resolve(resource.name, region, segments, owner);
173
+ return this.recordNode_resolve(resource, region, segments, owner);
174
+ }
175
+ /** A path inside a bucket's `objects/`: a `/` in an object's name is a folder. */
176
+ async objectNode_resolve(bucket, region, segments, owner) {
177
+ const objects = await this.objects_list(bucket, region);
178
+ const prefix = segments.length === 0 ? '' : `${segments.join('/')}/`;
179
+ const whole = segments.join('/');
180
+ const exact = objects.find((object) => object.name === whole);
181
+ if (exact !== undefined) {
182
+ if (exact.size > OBJECT_READ_LIMIT) {
183
+ return { kind: 'refused', reason: `${exact.size} bytes is past what cat reads through the tree (${OBJECT_READ_LIMIT}); it stays in the bucket` };
184
+ }
185
+ return { kind: 'bytes', size: exact.size, read: () => this.driver.object_read(bucket, exact.name, region) };
186
+ }
187
+ const inside = objects.filter((object) => object.name.startsWith(prefix));
188
+ if (segments.length > 0 && inside.length === 0)
189
+ return { kind: 'missing' };
190
+ return { kind: 'listing', list: async () => this.objectLevel_items(inside, prefix, owner) };
191
+ }
192
+ /** One level of a bucket's objects: files, and folders for the next `/`. */
193
+ objectLevel_items(objects, prefix, owner) {
194
+ const folders = new Map();
195
+ const items = [];
196
+ for (const object of objects) {
197
+ const rest = object.name.slice(prefix.length);
198
+ const slash = rest.indexOf('/');
199
+ if (slash === -1) {
200
+ items.push({ name: rest, type: 'object', size: object.size, owner, date: object.modified !== '' ? object.modified : this.now() });
201
+ }
202
+ else {
203
+ const folder = rest.slice(0, slash);
204
+ folders.set(folder, (folders.get(folder) ?? 0) + 1);
205
+ }
206
+ }
207
+ const folderItems = [...folders.entries()].map(([name, count]) => this.kindFolder_item(name, count));
208
+ return [...folderItems, ...items].sort((a, b) => a.name.localeCompare(b.name));
209
+ }
210
+ /** A path inside a DNS zone's `records/`. */
211
+ async recordNode_resolve(zone, region, segments, owner) {
212
+ const sets = recordSets_of(await this.records_list(zone.id, region), zone.name);
213
+ if (segments.length === 0) {
214
+ return {
215
+ kind: 'listing',
216
+ list: async () => sets.map((set) => ({
217
+ name: set.name, type: 'record', size: Buffer.byteLength(set.text), owner, date: this.now(), title: set.types.join(' '),
218
+ })),
219
+ };
220
+ }
221
+ if (segments.length !== 1)
222
+ return { kind: 'missing' };
223
+ const set = sets.find((entry) => entry.name === segments[0]);
224
+ return set === undefined ? { kind: 'missing' } : { kind: 'file', text: set.text };
225
+ }
226
+ // ---- rows and fields ----
227
+ /** A kind's resources as rows. */
228
+ resources_items(kind, resources, owner) {
229
+ return segments_assign(resources).map((entry) => {
230
+ const resource = entry.item;
231
+ const title = resourceTitle_of(kind, resource);
232
+ return {
233
+ name: entry.segment,
234
+ type: RESOURCE_TYPES[kind],
235
+ size: 0,
236
+ owner,
237
+ date: resource.created !== '' ? resource.created : this.now(),
238
+ status: resource.state,
239
+ ...(title !== '' ? { title } : {}),
240
+ tags: Object.entries(resource.tags).map(([key, value]) => `${key}=${value}`),
241
+ };
242
+ });
243
+ }
244
+ file_item(name, size, owner) {
245
+ return { name, type: 'file', size, owner, date: this.now() };
246
+ }
247
+ /** Every field a resource of a kind has, in the order a listing shows them. */
248
+ async fields_of(kind, resource, containerId, region) {
249
+ const tagLines = Object.entries(resource.tags).map(([key, value]) => `${key}=${value}\n`).join('');
250
+ const fields = [
251
+ { name: 'name', text: `${resource.name}\n` },
252
+ { name: 'id', text: `${resource.id}\n` },
253
+ { name: 'state', text: `${resource.state}\n` },
254
+ { name: 'region', text: `${resource.region}\n` },
255
+ { name: 'created', text: `${resource.created}\n` },
256
+ { name: 'tags', text: tagLines },
257
+ ];
258
+ if (kind === 'instances') {
259
+ const instance = resource;
260
+ fields.push({ name: 'shape', text: `${instance.shape}\n` }, { name: 'zone', text: `${instance.zone}\n` }, { name: 'ips', text: lines_of(instance.ips) });
261
+ }
262
+ else if (kind === 'volumes') {
263
+ const volume = resource;
264
+ fields.push({ name: 'size', text: `${volume.sizeGib} GiB\n` }, { name: 'attached', text: `${await this.attachedName_of(volume, containerId, region)}\n` });
265
+ }
266
+ else if (kind === 'loadbalancers') {
267
+ const balancer = resource;
268
+ fields.push({ name: 'ip', text: lines_of(balancer.ips) }, { name: 'shape', text: `${balancer.shape}\n` });
269
+ }
270
+ else if (kind === 'buckets') {
271
+ fields.push({ name: 'links', text: links_text(await this.links_list(resource.name, region)) });
272
+ }
273
+ fields.push({ name: 'info.json', text: `${JSON.stringify(resource.raw, null, 2)}\n` });
274
+ return fields;
275
+ }
276
+ /** What a volume is attached to: the instance's name when it is in the same container, else its id, else `no`. */
277
+ async attachedName_of(volume, containerId, region) {
278
+ if (volume.attachedTo === null)
279
+ return 'no';
280
+ const instances = await this.kind_list('instances', containerId, region);
281
+ return instances.find((instance) => instance.id === volume.attachedTo)?.name ?? volume.attachedTo;
282
+ }
283
+ }
284
+ /**
285
+ * A zone's records grouped by name: a file per name, relative to the zone,
286
+ * the apex as `@`, each holding its records as zone-file lines.
287
+ *
288
+ * @param records - The zone's records.
289
+ * @param zone - The zone's name.
290
+ * @returns The sets, sorted by name.
291
+ */
292
+ export function recordSets_of(records, zone) {
293
+ const byName = new Map();
294
+ for (const record of records) {
295
+ const domain = record.domain.replace(/\.$/, '');
296
+ const name = domain === zone ? '@' : domain.endsWith(`.${zone}`) ? domain.slice(0, -(zone.length + 1)) : domain;
297
+ byName.set(name, [...(byName.get(name) ?? []), record]);
298
+ }
299
+ return [...byName.entries()]
300
+ .sort(([a], [b]) => a.localeCompare(b))
301
+ .map(([name, set]) => ({
302
+ name,
303
+ types: [...new Set(set.map((record) => record.type))],
304
+ text: set.map((record) => `${record.domain.replace(/\.$/, '')}. ${record.ttl} IN ${record.type} ${record.data}\n`).join(''),
305
+ }));
306
+ }
307
+ /** A list as one value per line. */
308
+ function lines_of(values) {
309
+ return values.map((value) => `${value}\n`).join('');
310
+ }
311
+ /** A bucket's links, one per line: what each opens, its name, what it allows, when it ends. */
312
+ function links_text(links) {
313
+ return links.map((link) => `${link.object ?? '(bucket)'}\t${link.name}\t${link.access}\t${link.expires}\n`).join('');
314
+ }
315
+ /** The short title a resource row carries in a long listing. */
316
+ function resourceTitle_of(kind, resource) {
317
+ if (kind === 'instances')
318
+ return resource.shape;
319
+ if (kind === 'volumes')
320
+ return `${resource.sizeGib} GiB`;
321
+ if (kind === 'loadbalancers')
322
+ return resource.ips.join(' ');
323
+ return '';
324
+ }
325
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/vfs/resources.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,8 @@
4
4
  * A fond provider over the cloud driver. Under the mount: the tenancy by its
5
5
  * display name; inside it, its containers (compartments) nesting as the cloud
6
6
  * nests them, `regions/` with each region's zones, limits, shapes and prices,
7
- * and `domains/`. A container lists its children and `info.json`; a fact
7
+ * and `domains/`. Every container level, the tenancy's included, also holds
8
+ * the resource kind folders for the session's region (`resources.ts`). A container lists its children and `info.json`; a fact
8
9
  * (a limit, a shape, a price) is a folder of field files, as `/proc` does it:
9
10
  * a field is a file when a shell line wants it, and `info.json` holds the
10
11
  * whole record.
@@ -20,6 +21,7 @@
20
21
  import { type CpOptions, type Result, type VFSItem, type VFSProvider, type VfsOutcome } from '@fnndsc/fond';
21
22
  import type { CloudDriver } from '../cloud/driver.js';
22
23
  import { AnswerCache } from '../cache.js';
24
+ import { DomainTree } from './domains.js';
23
25
  /** The folders a tenancy level reserves beside its containers. */
24
26
  export declare const TENANCY_RESERVED: ReadonlyArray<string>;
25
27
  /** The folders a container level reserves beside its children. */
@@ -33,6 +35,10 @@ export interface TenancyProviderOptions {
33
35
  readonly cache?: AnswerCache;
34
36
  /** The clock for item dates the cloud does not give. */
35
37
  readonly now?: () => string;
38
+ /** The session's region, whose resources the kind folders list; the credential's home region when absent or null. */
39
+ readonly region?: () => string | null;
40
+ /** The domains the daemon was given; `domains/` lists empty without them. */
41
+ readonly domains?: DomainTree;
36
42
  }
37
43
  /** The tenancy as a tree under `/net/<cloud>`. */
38
44
  export declare class TenancyProvider implements VFSProvider {
@@ -40,7 +46,14 @@ export declare class TenancyProvider implements VFSProvider {
40
46
  private readonly driver;
41
47
  private readonly cache;
42
48
  private readonly now;
49
+ private readonly region;
50
+ private readonly resources;
51
+ private readonly domains;
43
52
  constructor(options: TenancyProviderOptions);
53
+ /** The region the kind folders list. */
54
+ private region_of;
55
+ /** A path below a container's kind folder, resolved by the resource tree. */
56
+ private resourceNode_resolve;
44
57
  /** Forgets every kept answer: the next listing asks the cloud. */
45
58
  cache_clear(): void;
46
59
  private identity_get;
@@ -81,7 +94,7 @@ export declare class TenancyProvider implements VFSProvider {
81
94
  private folder_item;
82
95
  private file_item;
83
96
  private container_item;
84
- /** What a container level lists: its children, the reserved folders, `info.json`. */
97
+ /** What a container level lists: its children, its kind folders, the reserved folders, `info.json`. */
85
98
  private containerLevel_list;
86
99
  /** What a node lists. */
87
100
  private node_list;