@celilo/cli 4.1.0 → 5.0.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.
- package/AGENTS.md +2 -2
- package/drizzle/0034_private_routes.sql +41 -0
- package/drizzle/meta/_journal.json +8 -1
- package/package.json +2 -2
- package/src/api/sessions.test.ts +1 -1
- package/src/capabilities/registration.test.ts +11 -11
- package/src/capabilities/secrets.test.ts +18 -18
- package/src/capabilities/validation.test.ts +24 -24
- package/src/cli/cli.test.ts +3 -3
- package/src/cli/commands/module-changeset.test.ts +1 -1
- package/src/cli/commands/module-generate.test.ts +2 -2
- package/src/cli/commands/module-import-aspect.test.ts +2 -2
- package/src/cli/commands/module-update.test.ts +14 -14
- package/src/cli/commands/module-upgrade-gate.test.ts +26 -1
- package/src/cli/commands/module-upgrade.test.ts +3 -3
- package/src/cli/commands/module-upgrade.ts +12 -0
- package/src/cli/commands/module-version.test.ts +1 -1
- package/src/cli/index.ts +22 -2
- package/src/cli/restore-migration-failure.test.ts +1 -1
- package/src/cli/stdout-pipe-flush.test.ts +35 -0
- package/src/db/private-routes.test.ts +159 -0
- package/src/db/schema.ts +49 -0
- package/src/hooks/capability-loader.ts +179 -12
- package/src/hooks/executor.test.ts +13 -13
- package/src/hooks/hook-state-dir.test.ts +2 -2
- package/src/hooks/test-fixtures/store-backed.ts +5 -3
- package/src/manifest/contracts/index.ts +28 -7
- package/src/manifest/contracts/v2.ts +32 -0
- package/src/manifest/icon-schema.test.ts +1 -1
- package/src/manifest/schema.ts +13 -2
- package/src/manifest/template-validator.test.ts +1 -1
- package/src/manifest/validate-privileged.test.ts +1 -1
- package/src/manifest/validate.test.ts +68 -29
- package/src/manifest/validate.ts +14 -1
- package/src/module/import.test.ts +7 -7
- package/src/module/packaging/build.test.ts +1 -1
- package/src/packaging/nfpm-depends.test.ts +42 -0
- package/src/policy/capability-shape-baseline.ts +7 -1
- package/src/policy/fixture-capability-coverage.test.ts +5 -5
- package/src/policy/module-business-baseline.ts +33 -4
- package/src/services/aspect-approvals.test.ts +2 -2
- package/src/services/aspect-reconcile.test.ts +2 -2
- package/src/services/aspect-runner.test.ts +4 -4
- package/src/services/audit/backups.test.ts +1 -1
- package/src/services/audit/capability-abi.test.ts +1 -1
- package/src/services/audit/module-configs.test.ts +1 -1
- package/src/services/build-bus/hook-dispatch-executor.test.ts +3 -3
- package/src/services/bus-interview-park.test.ts +1 -1
- package/src/services/bus-secret-flow.test.ts +1 -1
- package/src/services/capability-table-rows.test.ts +20 -2
- package/src/services/celilo-events.test.ts +80 -6
- package/src/services/celilo-events.ts +115 -12
- package/src/services/celilo-mgmt-hooks.test.ts +6 -3
- package/src/services/cross-module-read.test.ts +2 -2
- package/src/services/deploy-validation.test.ts +6 -6
- package/src/services/dns-provider-backfill.test.ts +2 -2
- package/src/services/dns-registrations.test.ts +1 -1
- package/src/services/fleet-checks.test.ts +2 -2
- package/src/services/health-runner.test.ts +1 -1
- package/src/services/infrastructure-variable-resolver.test.ts +11 -11
- package/src/services/instance-ops.test.ts +2 -2
- package/src/services/module-deploy.dns-repoint.test.ts +1 -1
- package/src/services/module-pause-quiescence.test.ts +1 -1
- package/src/services/module-pause.test.ts +1 -1
- package/src/services/module-subscriptions.test.ts +2 -2
- package/src/services/module-types-generator.test.ts +1 -1
- package/src/services/module-validator/contract-version.test.ts +3 -3
- package/src/services/network-ensure.test.ts +1 -1
- package/src/services/proxmox-reconcile.test.ts +2 -2
- package/src/services/remove-guard.test.ts +1 -1
- package/src/services/update/dep-graph.test.ts +1 -1
- package/src/services/update/orchestrator.test.ts +1 -1
- package/src/variables/capability-self-ref.test.ts +2 -2
- package/src/variables/computed/computed-integration.test.ts +1 -1
- package/src/variables/declarative-derivation.test.ts +19 -19
package/AGENTS.md
CHANGED
|
@@ -30,7 +30,7 @@ web** — they are the source of truth; the hosted copies at
|
|
|
30
30
|
An **app** is a module that provides no capability (it serves content), so set
|
|
31
31
|
`version_source: { kind: changeset }`.
|
|
32
32
|
|
|
33
|
-
1. **`manifest.yml`** — `id` (kebab-case), `celilo_contract: "
|
|
33
|
+
1. **`manifest.yml`** — `id` (kebab-case), `celilo_contract: "2.0"`, `version`,
|
|
34
34
|
the capabilities you `requires:` (e.g. `public_web`, `idp`), `variables`,
|
|
35
35
|
`hooks`, and `version_source`. Keep the schema directive on line 1 so your
|
|
36
36
|
editor validates:
|
|
@@ -60,7 +60,7 @@ celilo module deploy <id> / update / health # deploy + verify on the fleet
|
|
|
60
60
|
|
|
61
61
|
## Conventions / rules
|
|
62
62
|
|
|
63
|
-
- Module `id` is **kebab-case**; pin `celilo_contract: "
|
|
63
|
+
- Module `id` is **kebab-case**; pin `celilo_contract: "2.0"`.
|
|
64
64
|
- **`version_source`** picks how `version` is sourced: `changeset` (apps/content —
|
|
65
65
|
authored via changesets, ordered by `+N`), `pin` (wraps upstream software —
|
|
66
66
|
`version` = the installed upstream version, resolver-checked), `recipe`
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- The internal ingress's declared routes, in core, in their own table.
|
|
2
|
+
--
|
|
3
|
+
-- `caddy-internal` kept the routes its consumers registered in a `routes`
|
|
4
|
+
-- module-config key: the same rows as `web_routes`, stored as one module's
|
|
5
|
+
-- business rather than as declared state core owns. That key is why the two
|
|
6
|
+
-- ingresses could not share plumbing — the private provider had nothing core
|
|
7
|
+
-- could render, converge or audit.
|
|
8
|
+
--
|
|
9
|
+
-- Same columns as `web_routes`, separate table, and the separation is the
|
|
10
|
+
-- point. The PUBLIC provider derives the hostnames it serves from every row of
|
|
11
|
+
-- `web_routes`, so a private route stored there would be picked up and served
|
|
12
|
+
-- publicly, with a public certificate, by the ingress caddy-internal exists to
|
|
13
|
+
-- keep it away from (celilo#846). One table with a flag would make that leak a
|
|
14
|
+
-- missing `WHERE` clause away; two tables make it impossible.
|
|
15
|
+
--
|
|
16
|
+
-- No data migration (design D9 of providers-converge-declared-state). The
|
|
17
|
+
-- table starts empty. When caddy-internal deploys, provider arrival
|
|
18
|
+
-- re-registers its consumers and their hooks write their routes into it inside
|
|
19
|
+
-- that same deploy — observed 2026-09-17, "Re-registered 1 consumer(s) with
|
|
20
|
+
-- 'caddy-internal': wireguard-manager". A one-time backfill would be code that
|
|
21
|
+
-- runs once and is then wrong to keep.
|
|
22
|
+
CREATE TABLE `private_routes` (
|
|
23
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
24
|
+
`slug` text NOT NULL,
|
|
25
|
+
`module_id` text NOT NULL,
|
|
26
|
+
`type` text NOT NULL,
|
|
27
|
+
`path` text NOT NULL,
|
|
28
|
+
`hostname` text NOT NULL,
|
|
29
|
+
`target_host` text,
|
|
30
|
+
`target_port` integer,
|
|
31
|
+
`websocket` integer DEFAULT false NOT NULL,
|
|
32
|
+
`content_hash` text,
|
|
33
|
+
`created_at` integer DEFAULT (unixepoch()) NOT NULL,
|
|
34
|
+
`updated_at` integer DEFAULT (unixepoch()) NOT NULL,
|
|
35
|
+
FOREIGN KEY (`module_id`) REFERENCES `modules`(`id`) ON UPDATE no action ON DELETE cascade
|
|
36
|
+
);
|
|
37
|
+
--> statement-breakpoint
|
|
38
|
+
-- Scoped to hostname as `web_routes` is, and scoped to THIS table: the same
|
|
39
|
+
-- hostname and path may exist on both ingresses, which is a legitimate
|
|
40
|
+
-- split-horizon arrangement and not a collision.
|
|
41
|
+
CREATE UNIQUE INDEX `private_routes_hostname_path_idx` ON `private_routes` (`hostname`,`path`);
|
|
@@ -239,6 +239,13 @@
|
|
|
239
239
|
"when": 1789082481000,
|
|
240
240
|
"tag": "0033_build_bus_hook_runs",
|
|
241
241
|
"breakpoints": true
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"idx": 34,
|
|
245
|
+
"version": "6",
|
|
246
|
+
"when": 1789947740964,
|
|
247
|
+
"tag": "0034_private_routes",
|
|
248
|
+
"breakpoints": true
|
|
242
249
|
}
|
|
243
250
|
]
|
|
244
|
-
}
|
|
251
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@celilo/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Celilo — home lab orchestration CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@aws-sdk/client-s3": "^3.1109.0",
|
|
61
61
|
"@aws-sdk/lib-storage": "^3.1101.0",
|
|
62
|
-
"@celilo/capabilities": "^
|
|
62
|
+
"@celilo/capabilities": "^6.0.0",
|
|
63
63
|
"@celilo/cli-display": "^0.2.0",
|
|
64
64
|
"@celilo/core": "^0.14.0",
|
|
65
65
|
"@celilo/event-bus": "^0.7.0",
|
package/src/api/sessions.test.ts
CHANGED
|
@@ -79,7 +79,7 @@ beforeEach(() => {
|
|
|
79
79
|
name: 'iptables',
|
|
80
80
|
sourcePath: join(dir, 'installed'),
|
|
81
81
|
version: '1.0.2+9',
|
|
82
|
-
manifestData: { celilo_contract: '
|
|
82
|
+
manifestData: { celilo_contract: '2.0', id: 'iptables', name: 'iptables', version: '1.0.2' },
|
|
83
83
|
})
|
|
84
84
|
.run();
|
|
85
85
|
|
|
@@ -17,7 +17,7 @@ describe('Capability Registration', () => {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
const manifest: ModuleManifest = {
|
|
20
|
-
celilo_contract: '
|
|
20
|
+
celilo_contract: '2.0',
|
|
21
21
|
id: 'test-module',
|
|
22
22
|
name: 'Test Module',
|
|
23
23
|
version: '1.0.0',
|
|
@@ -50,7 +50,7 @@ describe('Capability Registration', () => {
|
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
const manifest: ModuleManifest = {
|
|
53
|
-
celilo_contract: '
|
|
53
|
+
celilo_contract: '2.0',
|
|
54
54
|
id: 'test-module',
|
|
55
55
|
name: 'Test Module',
|
|
56
56
|
version: '1.0.0',
|
|
@@ -89,7 +89,7 @@ describe('Capability Registration', () => {
|
|
|
89
89
|
};
|
|
90
90
|
|
|
91
91
|
const manifest: ModuleManifest = {
|
|
92
|
-
celilo_contract: '
|
|
92
|
+
celilo_contract: '2.0',
|
|
93
93
|
id: 'dns-external',
|
|
94
94
|
name: 'DNS External',
|
|
95
95
|
version: '1.0.0',
|
|
@@ -126,7 +126,7 @@ describe('Capability Registration', () => {
|
|
|
126
126
|
};
|
|
127
127
|
|
|
128
128
|
const manifest: ModuleManifest = {
|
|
129
|
-
celilo_contract: '
|
|
129
|
+
celilo_contract: '2.0',
|
|
130
130
|
id: 'test-module',
|
|
131
131
|
name: 'Test Module',
|
|
132
132
|
version: '1.0.0',
|
|
@@ -155,7 +155,7 @@ describe('Capability Registration', () => {
|
|
|
155
155
|
};
|
|
156
156
|
|
|
157
157
|
const manifest: ModuleManifest = {
|
|
158
|
-
celilo_contract: '
|
|
158
|
+
celilo_contract: '2.0',
|
|
159
159
|
id: 'test-module',
|
|
160
160
|
name: 'Test Module',
|
|
161
161
|
version: '1.0.0',
|
|
@@ -185,7 +185,7 @@ describe('Capability Registration', () => {
|
|
|
185
185
|
};
|
|
186
186
|
|
|
187
187
|
const manifest: ModuleManifest = {
|
|
188
|
-
celilo_contract: '
|
|
188
|
+
celilo_contract: '2.0',
|
|
189
189
|
id: 'test-module',
|
|
190
190
|
name: 'Test Module',
|
|
191
191
|
version: '1.0.0',
|
|
@@ -213,7 +213,7 @@ describe('Capability Registration', () => {
|
|
|
213
213
|
};
|
|
214
214
|
|
|
215
215
|
const manifest: ModuleManifest = {
|
|
216
|
-
celilo_contract: '
|
|
216
|
+
celilo_contract: '2.0',
|
|
217
217
|
id: 'test-module',
|
|
218
218
|
name: 'Test Module',
|
|
219
219
|
version: '1.0.0',
|
|
@@ -244,7 +244,7 @@ describe('Capability Registration', () => {
|
|
|
244
244
|
};
|
|
245
245
|
|
|
246
246
|
const manifest: ModuleManifest = {
|
|
247
|
-
celilo_contract: '
|
|
247
|
+
celilo_contract: '2.0',
|
|
248
248
|
id: 'test-module',
|
|
249
249
|
name: 'Test Module',
|
|
250
250
|
version: '1.0.0',
|
|
@@ -280,7 +280,7 @@ describe('Capability Registration', () => {
|
|
|
280
280
|
};
|
|
281
281
|
|
|
282
282
|
const manifest: ModuleManifest = {
|
|
283
|
-
celilo_contract: '
|
|
283
|
+
celilo_contract: '2.0',
|
|
284
284
|
id: 'test-module',
|
|
285
285
|
name: 'Test Module',
|
|
286
286
|
version: '1.0.0',
|
|
@@ -312,7 +312,7 @@ describe('Capability Registration', () => {
|
|
|
312
312
|
};
|
|
313
313
|
|
|
314
314
|
const manifest: ModuleManifest = {
|
|
315
|
-
celilo_contract: '
|
|
315
|
+
celilo_contract: '2.0',
|
|
316
316
|
id: 'test-module',
|
|
317
317
|
name: 'Test Module',
|
|
318
318
|
version: '1.0.0',
|
|
@@ -343,7 +343,7 @@ describe('Capability Registration', () => {
|
|
|
343
343
|
};
|
|
344
344
|
|
|
345
345
|
const manifest: ModuleManifest = {
|
|
346
|
-
celilo_contract: '
|
|
346
|
+
celilo_contract: '2.0',
|
|
347
347
|
id: 'test-module',
|
|
348
348
|
name: 'Test Module',
|
|
349
349
|
version: '1.0.0',
|
|
@@ -11,7 +11,7 @@ describe('Capability Secret Access', () => {
|
|
|
11
11
|
describe('isCapabilityFieldSecret', () => {
|
|
12
12
|
test('should return true when field is marked as secret', () => {
|
|
13
13
|
const providerManifest: ModuleManifest = {
|
|
14
|
-
celilo_contract: '
|
|
14
|
+
celilo_contract: '2.0',
|
|
15
15
|
id: 'dns-external',
|
|
16
16
|
name: 'DNS External',
|
|
17
17
|
version: '1.0.0',
|
|
@@ -56,7 +56,7 @@ describe('Capability Secret Access', () => {
|
|
|
56
56
|
|
|
57
57
|
test('should return true for any secret in the list', () => {
|
|
58
58
|
const providerManifest: ModuleManifest = {
|
|
59
|
-
celilo_contract: '
|
|
59
|
+
celilo_contract: '2.0',
|
|
60
60
|
id: 'provider',
|
|
61
61
|
name: 'Provider',
|
|
62
62
|
version: '1.0.0',
|
|
@@ -98,7 +98,7 @@ describe('Capability Secret Access', () => {
|
|
|
98
98
|
|
|
99
99
|
test('should return false when field is not in secrets list', () => {
|
|
100
100
|
const providerManifest: ModuleManifest = {
|
|
101
|
-
celilo_contract: '
|
|
101
|
+
celilo_contract: '2.0',
|
|
102
102
|
id: 'dns-external',
|
|
103
103
|
name: 'DNS External',
|
|
104
104
|
version: '1.0.0',
|
|
@@ -137,7 +137,7 @@ describe('Capability Secret Access', () => {
|
|
|
137
137
|
|
|
138
138
|
test('should return false when capability has no secrets', () => {
|
|
139
139
|
const providerManifest: ModuleManifest = {
|
|
140
|
-
celilo_contract: '
|
|
140
|
+
celilo_contract: '2.0',
|
|
141
141
|
id: 'provider',
|
|
142
142
|
name: 'Provider',
|
|
143
143
|
version: '1.0.0',
|
|
@@ -183,7 +183,7 @@ describe('Capability Secret Access', () => {
|
|
|
183
183
|
|
|
184
184
|
test('should match exact secret name', () => {
|
|
185
185
|
const providerManifest: ModuleManifest = {
|
|
186
|
-
celilo_contract: '
|
|
186
|
+
celilo_contract: '2.0',
|
|
187
187
|
id: 'provider',
|
|
188
188
|
name: 'Provider',
|
|
189
189
|
version: '1.0.0',
|
|
@@ -227,7 +227,7 @@ describe('Capability Secret Access', () => {
|
|
|
227
227
|
describe('checkCapabilitySecretAccess', () => {
|
|
228
228
|
test('should return true when consumer matches allowlist', () => {
|
|
229
229
|
const providerManifest: ModuleManifest = {
|
|
230
|
-
celilo_contract: '
|
|
230
|
+
celilo_contract: '2.0',
|
|
231
231
|
id: 'dns-external',
|
|
232
232
|
name: 'DNS External',
|
|
233
233
|
version: '1.0.0',
|
|
@@ -253,7 +253,7 @@ describe('Capability Secret Access', () => {
|
|
|
253
253
|
};
|
|
254
254
|
|
|
255
255
|
const consumerManifest: ModuleManifest = {
|
|
256
|
-
celilo_contract: '
|
|
256
|
+
celilo_contract: '2.0',
|
|
257
257
|
id: 'caddy',
|
|
258
258
|
name: 'Caddy',
|
|
259
259
|
version: '1.0.0',
|
|
@@ -298,7 +298,7 @@ describe('Capability Secret Access', () => {
|
|
|
298
298
|
|
|
299
299
|
test('should return false when consumer does not match allowlist', () => {
|
|
300
300
|
const providerManifest: ModuleManifest = {
|
|
301
|
-
celilo_contract: '
|
|
301
|
+
celilo_contract: '2.0',
|
|
302
302
|
id: 'dns-external',
|
|
303
303
|
name: 'DNS External',
|
|
304
304
|
version: '1.0.0',
|
|
@@ -324,7 +324,7 @@ describe('Capability Secret Access', () => {
|
|
|
324
324
|
};
|
|
325
325
|
|
|
326
326
|
const consumerManifest: ModuleManifest = {
|
|
327
|
-
celilo_contract: '
|
|
327
|
+
celilo_contract: '2.0',
|
|
328
328
|
id: 'some-app',
|
|
329
329
|
name: 'Some App',
|
|
330
330
|
version: '1.0.0',
|
|
@@ -367,7 +367,7 @@ describe('Capability Secret Access', () => {
|
|
|
367
367
|
|
|
368
368
|
test('should return true when secret has no readable_by restriction', () => {
|
|
369
369
|
const providerManifest: ModuleManifest = {
|
|
370
|
-
celilo_contract: '
|
|
370
|
+
celilo_contract: '2.0',
|
|
371
371
|
id: 'provider',
|
|
372
372
|
name: 'Provider',
|
|
373
373
|
version: '1.0.0',
|
|
@@ -393,7 +393,7 @@ describe('Capability Secret Access', () => {
|
|
|
393
393
|
};
|
|
394
394
|
|
|
395
395
|
const consumerManifest: ModuleManifest = {
|
|
396
|
-
celilo_contract: '
|
|
396
|
+
celilo_contract: '2.0',
|
|
397
397
|
id: 'consumer',
|
|
398
398
|
name: 'Consumer',
|
|
399
399
|
version: '1.0.0',
|
|
@@ -429,7 +429,7 @@ describe('Capability Secret Access', () => {
|
|
|
429
429
|
|
|
430
430
|
test('should return true when readable_by is empty array', () => {
|
|
431
431
|
const providerManifest: ModuleManifest = {
|
|
432
|
-
celilo_contract: '
|
|
432
|
+
celilo_contract: '2.0',
|
|
433
433
|
id: 'provider',
|
|
434
434
|
name: 'Provider',
|
|
435
435
|
version: '1.0.0',
|
|
@@ -455,7 +455,7 @@ describe('Capability Secret Access', () => {
|
|
|
455
455
|
};
|
|
456
456
|
|
|
457
457
|
const consumerManifest: ModuleManifest = {
|
|
458
|
-
celilo_contract: '
|
|
458
|
+
celilo_contract: '2.0',
|
|
459
459
|
id: 'consumer',
|
|
460
460
|
name: 'Consumer',
|
|
461
461
|
version: '1.0.0',
|
|
@@ -507,7 +507,7 @@ describe('Capability Secret Access', () => {
|
|
|
507
507
|
|
|
508
508
|
test('should return false when consumer not found', () => {
|
|
509
509
|
const providerManifest: ModuleManifest = {
|
|
510
|
-
celilo_contract: '
|
|
510
|
+
celilo_contract: '2.0',
|
|
511
511
|
id: 'provider',
|
|
512
512
|
name: 'Provider',
|
|
513
513
|
version: '1.0.0',
|
|
@@ -558,7 +558,7 @@ describe('Capability Secret Access', () => {
|
|
|
558
558
|
|
|
559
559
|
test('should return false when secret not found in capability', () => {
|
|
560
560
|
const providerManifest: ModuleManifest = {
|
|
561
|
-
celilo_contract: '
|
|
561
|
+
celilo_contract: '2.0',
|
|
562
562
|
id: 'provider',
|
|
563
563
|
name: 'Provider',
|
|
564
564
|
version: '1.0.0',
|
|
@@ -583,7 +583,7 @@ describe('Capability Secret Access', () => {
|
|
|
583
583
|
};
|
|
584
584
|
|
|
585
585
|
const consumerManifest: ModuleManifest = {
|
|
586
|
-
celilo_contract: '
|
|
586
|
+
celilo_contract: '2.0',
|
|
587
587
|
id: 'consumer',
|
|
588
588
|
name: 'Consumer',
|
|
589
589
|
version: '1.0.0',
|
|
@@ -623,7 +623,7 @@ describe('Capability Secret Access', () => {
|
|
|
623
623
|
|
|
624
624
|
test('should return false when capability has no secrets', () => {
|
|
625
625
|
const providerManifest: ModuleManifest = {
|
|
626
|
-
celilo_contract: '
|
|
626
|
+
celilo_contract: '2.0',
|
|
627
627
|
id: 'provider',
|
|
628
628
|
name: 'Provider',
|
|
629
629
|
version: '1.0.0',
|
|
@@ -643,7 +643,7 @@ describe('Capability Secret Access', () => {
|
|
|
643
643
|
};
|
|
644
644
|
|
|
645
645
|
const consumerManifest: ModuleManifest = {
|
|
646
|
-
celilo_contract: '
|
|
646
|
+
celilo_contract: '2.0',
|
|
647
647
|
id: 'consumer',
|
|
648
648
|
name: 'Consumer',
|
|
649
649
|
version: '1.0.0',
|
|
@@ -95,7 +95,7 @@ describe('Capability Access Validation', () => {
|
|
|
95
95
|
describe('getProviderManifest', () => {
|
|
96
96
|
test('should return manifest when capability exists', () => {
|
|
97
97
|
const mockManifest: ModuleManifest = {
|
|
98
|
-
celilo_contract: '
|
|
98
|
+
celilo_contract: '2.0',
|
|
99
99
|
id: 'dns-external',
|
|
100
100
|
name: 'DNS External',
|
|
101
101
|
version: '1.0.0',
|
|
@@ -153,7 +153,7 @@ describe('Capability Access Validation', () => {
|
|
|
153
153
|
|
|
154
154
|
test('should parse JSON manifest correctly', () => {
|
|
155
155
|
const mockManifest: ModuleManifest = {
|
|
156
|
-
celilo_contract: '
|
|
156
|
+
celilo_contract: '2.0',
|
|
157
157
|
id: 'test-module',
|
|
158
158
|
name: 'Test Module',
|
|
159
159
|
version: '1.0.0',
|
|
@@ -190,7 +190,7 @@ describe('Capability Access Validation', () => {
|
|
|
190
190
|
describe('validateCapabilityAccess', () => {
|
|
191
191
|
test('should return success when module does not require capabilities', async () => {
|
|
192
192
|
const manifest: ModuleManifest = {
|
|
193
|
-
celilo_contract: '
|
|
193
|
+
celilo_contract: '2.0',
|
|
194
194
|
id: 'test-module',
|
|
195
195
|
name: 'Test Module',
|
|
196
196
|
version: '1.0.0',
|
|
@@ -209,7 +209,7 @@ describe('Capability Access Validation', () => {
|
|
|
209
209
|
|
|
210
210
|
test('should return success when module requires capabilities array is empty', async () => {
|
|
211
211
|
const manifest: ModuleManifest = {
|
|
212
|
-
celilo_contract: '
|
|
212
|
+
celilo_contract: '2.0',
|
|
213
213
|
id: 'test-module',
|
|
214
214
|
name: 'Test Module',
|
|
215
215
|
version: '1.0.0',
|
|
@@ -236,7 +236,7 @@ describe('Capability Access Validation', () => {
|
|
|
236
236
|
// fails the test after this one: the difference is entirely which
|
|
237
237
|
// capability is asked for.
|
|
238
238
|
const manifest: ModuleManifest = {
|
|
239
|
-
celilo_contract: '
|
|
239
|
+
celilo_contract: '2.0',
|
|
240
240
|
id: 'celilo-web-console',
|
|
241
241
|
name: 'Celilo Web Console',
|
|
242
242
|
version: '1.0.0',
|
|
@@ -261,7 +261,7 @@ describe('Capability Access Validation', () => {
|
|
|
261
261
|
|
|
262
262
|
test('should return error when required capability not found', async () => {
|
|
263
263
|
const manifest: ModuleManifest = {
|
|
264
|
-
celilo_contract: '
|
|
264
|
+
celilo_contract: '2.0',
|
|
265
265
|
id: 'caddy',
|
|
266
266
|
name: 'Caddy',
|
|
267
267
|
version: '1.0.0',
|
|
@@ -292,7 +292,7 @@ describe('Capability Access Validation', () => {
|
|
|
292
292
|
// not demand a providing module for it — otherwise celilo-mgmt
|
|
293
293
|
// can't be imported (regression: openspec/specs/progressive-zone-disclosure/spec.md).
|
|
294
294
|
const manifest: ModuleManifest = {
|
|
295
|
-
celilo_contract: '
|
|
295
|
+
celilo_contract: '2.0',
|
|
296
296
|
id: 'celilo-mgmt',
|
|
297
297
|
name: 'Celilo Management Server',
|
|
298
298
|
version: '1.0.0',
|
|
@@ -318,7 +318,7 @@ describe('Capability Access Validation', () => {
|
|
|
318
318
|
|
|
319
319
|
test('should return success when capability has no secrets', async () => {
|
|
320
320
|
const manifest: ModuleManifest = {
|
|
321
|
-
celilo_contract: '
|
|
321
|
+
celilo_contract: '2.0',
|
|
322
322
|
id: 'consumer',
|
|
323
323
|
name: 'Consumer',
|
|
324
324
|
version: '1.0.0',
|
|
@@ -331,7 +331,7 @@ describe('Capability Access Validation', () => {
|
|
|
331
331
|
};
|
|
332
332
|
|
|
333
333
|
const providerManifest: ModuleManifest = {
|
|
334
|
-
celilo_contract: '
|
|
334
|
+
celilo_contract: '2.0',
|
|
335
335
|
id: 'provider',
|
|
336
336
|
name: 'Provider',
|
|
337
337
|
version: '1.0.0',
|
|
@@ -364,7 +364,7 @@ describe('Capability Access Validation', () => {
|
|
|
364
364
|
|
|
365
365
|
test('should return success when secret has no readable_by restriction', async () => {
|
|
366
366
|
const manifest: ModuleManifest = {
|
|
367
|
-
celilo_contract: '
|
|
367
|
+
celilo_contract: '2.0',
|
|
368
368
|
id: 'consumer',
|
|
369
369
|
name: 'Consumer',
|
|
370
370
|
version: '1.0.0',
|
|
@@ -377,7 +377,7 @@ describe('Capability Access Validation', () => {
|
|
|
377
377
|
};
|
|
378
378
|
|
|
379
379
|
const providerManifest: ModuleManifest = {
|
|
380
|
-
celilo_contract: '
|
|
380
|
+
celilo_contract: '2.0',
|
|
381
381
|
id: 'dns-external',
|
|
382
382
|
name: 'DNS External',
|
|
383
383
|
version: '1.0.0',
|
|
@@ -418,7 +418,7 @@ describe('Capability Access Validation', () => {
|
|
|
418
418
|
|
|
419
419
|
test('should return success when consumer matches allowlist', async () => {
|
|
420
420
|
const manifest: ModuleManifest = {
|
|
421
|
-
celilo_contract: '
|
|
421
|
+
celilo_contract: '2.0',
|
|
422
422
|
id: 'caddy',
|
|
423
423
|
name: 'Caddy',
|
|
424
424
|
version: '1.0.0',
|
|
@@ -439,7 +439,7 @@ describe('Capability Access Validation', () => {
|
|
|
439
439
|
};
|
|
440
440
|
|
|
441
441
|
const providerManifest: ModuleManifest = {
|
|
442
|
-
celilo_contract: '
|
|
442
|
+
celilo_contract: '2.0',
|
|
443
443
|
id: 'dns-external',
|
|
444
444
|
name: 'DNS External',
|
|
445
445
|
version: '1.0.0',
|
|
@@ -480,7 +480,7 @@ describe('Capability Access Validation', () => {
|
|
|
480
480
|
|
|
481
481
|
test('should return error when consumer does not match allowlist', async () => {
|
|
482
482
|
const manifest: ModuleManifest = {
|
|
483
|
-
celilo_contract: '
|
|
483
|
+
celilo_contract: '2.0',
|
|
484
484
|
id: 'some-app',
|
|
485
485
|
name: 'Some App',
|
|
486
486
|
version: '1.0.0',
|
|
@@ -501,7 +501,7 @@ describe('Capability Access Validation', () => {
|
|
|
501
501
|
};
|
|
502
502
|
|
|
503
503
|
const providerManifest: ModuleManifest = {
|
|
504
|
-
celilo_contract: '
|
|
504
|
+
celilo_contract: '2.0',
|
|
505
505
|
id: 'dns-external',
|
|
506
506
|
name: 'DNS External',
|
|
507
507
|
version: '1.0.0',
|
|
@@ -546,7 +546,7 @@ describe('Capability Access Validation', () => {
|
|
|
546
546
|
|
|
547
547
|
test('should return error when consumer provides no capabilities', async () => {
|
|
548
548
|
const manifest: ModuleManifest = {
|
|
549
|
-
celilo_contract: '
|
|
549
|
+
celilo_contract: '2.0',
|
|
550
550
|
id: 'consumer',
|
|
551
551
|
name: 'Consumer',
|
|
552
552
|
version: '1.0.0',
|
|
@@ -559,7 +559,7 @@ describe('Capability Access Validation', () => {
|
|
|
559
559
|
};
|
|
560
560
|
|
|
561
561
|
const providerManifest: ModuleManifest = {
|
|
562
|
-
celilo_contract: '
|
|
562
|
+
celilo_contract: '2.0',
|
|
563
563
|
id: 'dns-external',
|
|
564
564
|
name: 'DNS External',
|
|
565
565
|
version: '1.0.0',
|
|
@@ -601,7 +601,7 @@ describe('Capability Access Validation', () => {
|
|
|
601
601
|
|
|
602
602
|
test('should validate all required capabilities', async () => {
|
|
603
603
|
const manifest: ModuleManifest = {
|
|
604
|
-
celilo_contract: '
|
|
604
|
+
celilo_contract: '2.0',
|
|
605
605
|
id: 'complex-app',
|
|
606
606
|
name: 'Complex App',
|
|
607
607
|
version: '1.0.0',
|
|
@@ -697,7 +697,7 @@ describe('Capability Access Validation', () => {
|
|
|
697
697
|
// dependency graph that six core services read.
|
|
698
698
|
describe('celilo#854 — secret access is gated on reference, not on declaration', () => {
|
|
699
699
|
const knotManifest: ModuleManifest = {
|
|
700
|
-
celilo_contract: '
|
|
700
|
+
celilo_contract: '2.0',
|
|
701
701
|
id: 'knot-unbound-internal',
|
|
702
702
|
name: 'Knot + Unbound',
|
|
703
703
|
version: '1.0.0',
|
|
@@ -730,7 +730,7 @@ describe('Capability Access Validation', () => {
|
|
|
730
730
|
|
|
731
731
|
test('a consumer that requires the capability but never names the secret imports', async () => {
|
|
732
732
|
const manifest: ModuleManifest = {
|
|
733
|
-
celilo_contract: '
|
|
733
|
+
celilo_contract: '2.0',
|
|
734
734
|
id: 'caddy-internal',
|
|
735
735
|
name: 'Caddy (fleet-only ingress)',
|
|
736
736
|
version: '1.0.0',
|
|
@@ -752,7 +752,7 @@ describe('Capability Access Validation', () => {
|
|
|
752
752
|
|
|
753
753
|
test('a consumer that DOES name the restricted secret is still refused', async () => {
|
|
754
754
|
const manifest: ModuleManifest = {
|
|
755
|
-
celilo_contract: '
|
|
755
|
+
celilo_contract: '2.0',
|
|
756
756
|
id: 'nosy-app',
|
|
757
757
|
name: 'Nosy App',
|
|
758
758
|
version: '1.0.0',
|
|
@@ -817,7 +817,7 @@ describe('Capability Access Validation', () => {
|
|
|
817
817
|
test('naming one secret enforces that secret allow-list and no other', async () => {
|
|
818
818
|
function consumer(deriveFrom: string): ModuleManifest {
|
|
819
819
|
return {
|
|
820
|
-
celilo_contract: '
|
|
820
|
+
celilo_contract: '2.0',
|
|
821
821
|
id: 'caddy-internal',
|
|
822
822
|
name: 'Caddy (fleet-only ingress)',
|
|
823
823
|
version: '1.0.0',
|
|
@@ -871,7 +871,7 @@ describe('Capability Access Validation', () => {
|
|
|
871
871
|
*/
|
|
872
872
|
test('a secret named only in a template is refused at import', async () => {
|
|
873
873
|
const manifest: ModuleManifest = {
|
|
874
|
-
celilo_contract: '
|
|
874
|
+
celilo_contract: '2.0',
|
|
875
875
|
id: 'nosy-app',
|
|
876
876
|
name: 'Nosy App',
|
|
877
877
|
version: '1.0.0',
|
|
@@ -890,7 +890,7 @@ describe('Capability Access Validation', () => {
|
|
|
890
890
|
|
|
891
891
|
test('a non-secret template reference is still not a secret reference', async () => {
|
|
892
892
|
const manifest: ModuleManifest = {
|
|
893
|
-
celilo_contract: '
|
|
893
|
+
celilo_contract: '2.0',
|
|
894
894
|
id: 'caddy-internal',
|
|
895
895
|
name: 'Caddy (fleet-only ingress)',
|
|
896
896
|
version: '1.0.0',
|
package/src/cli/cli.test.ts
CHANGED
|
@@ -100,7 +100,7 @@ describe('CLI Integration', () => {
|
|
|
100
100
|
await writeFile(
|
|
101
101
|
join(TEST_MODULE_DIR, 'manifest.yml'),
|
|
102
102
|
`
|
|
103
|
-
celilo_contract: "
|
|
103
|
+
celilo_contract: "2.0"
|
|
104
104
|
id: test-module
|
|
105
105
|
name: Test Module
|
|
106
106
|
version: 1.0.0
|
|
@@ -255,7 +255,7 @@ description: Test module for CLI
|
|
|
255
255
|
const db = getDb();
|
|
256
256
|
// Insert test module with variable declarations
|
|
257
257
|
const manifestData = JSON.stringify({
|
|
258
|
-
celilo_contract: '
|
|
258
|
+
celilo_contract: '2.0',
|
|
259
259
|
id: 'test-module',
|
|
260
260
|
name: 'Test Module',
|
|
261
261
|
version: '1.0.0',
|
|
@@ -440,7 +440,7 @@ description: Test module for CLI
|
|
|
440
440
|
const db = getDb();
|
|
441
441
|
// Insert test module with secrets manifest
|
|
442
442
|
const manifestData = JSON.stringify({
|
|
443
|
-
celilo_contract: '
|
|
443
|
+
celilo_contract: '2.0',
|
|
444
444
|
id: 'test-module',
|
|
445
445
|
name: 'Test Module',
|
|
446
446
|
version: '1.0.0',
|
|
@@ -10,7 +10,7 @@ beforeEach(async () => {
|
|
|
10
10
|
dir = await mkdtemp(join(tmpdir(), 'celilo-cs-'));
|
|
11
11
|
await writeFile(
|
|
12
12
|
join(dir, 'manifest.yml'),
|
|
13
|
-
'celilo_contract: "
|
|
13
|
+
'celilo_contract: "2.0"\nid: lunacycle\nversion: 1.0.0\n',
|
|
14
14
|
);
|
|
15
15
|
});
|
|
16
16
|
afterEach(async () => {
|
|
@@ -9,7 +9,7 @@ const DECLARED = join('ansible', 'roles', 'fixture', 'files', 'binary');
|
|
|
9
9
|
|
|
10
10
|
function manifestWithArtifacts(artifacts: string[]): ModuleManifest {
|
|
11
11
|
return {
|
|
12
|
-
celilo_contract: '
|
|
12
|
+
celilo_contract: '2.0',
|
|
13
13
|
id: 'fixture',
|
|
14
14
|
name: 'Fixture',
|
|
15
15
|
version: '1.0.0',
|
|
@@ -42,7 +42,7 @@ describe('missingBuildOutputs', () => {
|
|
|
42
42
|
test('reports nothing for a module with no build block', () => {
|
|
43
43
|
expect(
|
|
44
44
|
missingBuildOutputs(payload, {
|
|
45
|
-
celilo_contract: '
|
|
45
|
+
celilo_contract: '2.0',
|
|
46
46
|
id: 'fixture',
|
|
47
47
|
name: 'Fixture',
|
|
48
48
|
version: '1.0.0',
|
|
@@ -32,7 +32,7 @@ function insertAspectModule(id: string, version: string): void {
|
|
|
32
32
|
id,
|
|
33
33
|
name: id,
|
|
34
34
|
version,
|
|
35
|
-
celilo_contract: '
|
|
35
|
+
celilo_contract: '2.0',
|
|
36
36
|
base_module_aspect: aspect,
|
|
37
37
|
},
|
|
38
38
|
sourcePath: `/tmp/${id}`,
|
|
@@ -102,7 +102,7 @@ describe('handleAspectApprovalAfterImport (non-interactive)', () => {
|
|
|
102
102
|
id: 'caddy',
|
|
103
103
|
name: 'caddy',
|
|
104
104
|
version: '1.0.0',
|
|
105
|
-
manifestData: { id: 'caddy', name: 'caddy', version: '1.0.0', celilo_contract: '
|
|
105
|
+
manifestData: { id: 'caddy', name: 'caddy', version: '1.0.0', celilo_contract: '2.0' },
|
|
106
106
|
sourcePath: '/tmp/caddy',
|
|
107
107
|
})
|
|
108
108
|
.run();
|