@serve.zone/interfaces 31.9.0 ā 32.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/.smartconfig.json +1 -0
- package/changelog.md +467 -0
- package/dist_ts/00_commitinfo_data.js +3 -3
- package/dist_ts/appstore/types.d.ts +4 -6
- package/dist_ts/appstore/types.js +5 -5
- package/dist_ts/data/backup.d.ts +3 -26
- package/dist_ts/data/cluster.d.ts +36 -11
- package/dist_ts/data/cluster.js +33 -22
- package/dist_ts/data/clusteringress.d.ts +8 -0
- package/dist_ts/data/clusteringress.js +13 -8
- package/dist_ts/data/clusternode.d.ts +121 -74
- package/dist_ts/data/clusternode.js +109 -132
- package/dist_ts/data/coremail.d.ts +3 -7
- package/dist_ts/data/coremail.js +2 -2
- package/dist_ts/data/coremail.runtime.d.ts +0 -1
- package/dist_ts/data/coremail.runtime.js +5 -22
- package/dist_ts/data/deploymentadoption.d.ts +0 -2
- package/dist_ts/data/deploymentadoption.js +40 -6
- package/dist_ts/data/deploymentoperation.js +16 -3
- package/dist_ts/data/deploymentpreflight.d.ts +0 -2
- package/dist_ts/data/deploymentpreflight.js +1 -1
- package/dist_ts/data/immutableimage.d.ts +38 -21
- package/dist_ts/data/immutableimage.js +45 -5
- package/dist_ts/data/index.d.ts +1 -1
- package/dist_ts/data/isolatedrestore.d.ts +139 -21
- package/dist_ts/data/isolatedrestore.golden.d.ts +0 -1
- package/dist_ts/data/isolatedrestore.golden.js +6 -9
- package/dist_ts/data/isolatedrestore.js +176 -40
- package/dist_ts/data/mail.d.ts +1 -1
- package/dist_ts/data/networkaddressplan.d.ts +8 -8
- package/dist_ts/data/networkaddressplan.js +4 -4
- package/dist_ts/data/networkauthority.d.ts +20 -22
- package/dist_ts/data/networkauthority.js +26 -28
- package/dist_ts/data/networkcredential.d.ts +10 -10
- package/dist_ts/data/networkcredential.js +16 -16
- package/dist_ts/data/networkdelivery.d.ts +18 -18
- package/dist_ts/data/networkdelivery.js +16 -16
- package/dist_ts/data/networklease.d.ts +18 -7
- package/dist_ts/data/networklease.js +29 -7
- package/dist_ts/data/networknode.d.ts +2 -2
- package/dist_ts/data/networkprojection.d.ts +59 -60
- package/dist_ts/data/networkprojection.js +53 -57
- package/dist_ts/data/networkprotection.d.ts +27 -28
- package/dist_ts/data/networkprotection.js +36 -36
- package/dist_ts/data/networkrouter.d.ts +11 -11
- package/dist_ts/data/networkrouter.js +1 -1
- package/dist_ts/data/networksigning.d.ts +16 -18
- package/dist_ts/data/networksigning.js +20 -21
- package/dist_ts/data/nodecredential.d.ts +4 -6
- package/dist_ts/data/nodeenrollment.d.ts +35 -40
- package/dist_ts/data/nodeenrollment.js +57 -72
- package/dist_ts/data/privatenetwork.d.ts +21 -24
- package/dist_ts/data/privatenetwork.js +39 -54
- package/dist_ts/data/runtimeassignment.d.ts +50 -34
- package/dist_ts/data/runtimeassignment.js +79 -45
- package/dist_ts/data/runtimeconfig.d.ts +21 -22
- package/dist_ts/data/runtimeconfig.js +24 -24
- package/dist_ts/data/runtimesession.d.ts +100 -62
- package/dist_ts/data/runtimesession.js +98 -79
- package/dist_ts/data/runtimeterminalreceipt.d.ts +28 -29
- package/dist_ts/data/runtimeterminalreceipt.js +42 -42
- package/dist_ts/data/secret.d.ts +18 -25
- package/dist_ts/data/secret.js +12 -52
- package/dist_ts/data/servicecredential.d.ts +14 -16
- package/dist_ts/data/servicecredential.js +17 -28
- package/dist_ts/data/serviceruntime.d.ts +7 -7
- package/dist_ts/data/serviceruntime.js +4 -4
- package/dist_ts/data/sparknodereport.d.ts +27 -14
- package/dist_ts/data/sparknodereport.js +35 -28
- package/dist_ts/data/webpush.d.ts +0 -1
- package/dist_ts/index.d.ts +2 -1
- package/dist_ts/index.js +3 -2
- package/dist_ts/platform/objectstorageretention.d.ts +21 -24
- package/dist_ts/platform/objectstorageretention.js +6 -18
- package/dist_ts/platform/storage.d.ts +1 -3
- package/dist_ts/platform/storagemigration.d.ts +0 -7
- package/dist_ts/platform/storagemigration.golden.d.ts +0 -1
- package/dist_ts/platform/storagemigration.golden.js +8 -12
- package/dist_ts/platform/storagemigration.js +6 -51
- package/dist_ts/platform/types.d.ts +2 -2
- package/dist_ts/private/canonicaljson.d.ts +9 -1
- package/dist_ts/private/canonicaljson.js +14 -2
- package/dist_ts/private/dataproperties.d.ts +62 -0
- package/dist_ts/private/dataproperties.js +117 -0
- package/dist_ts/private/networkcontract.d.ts +10 -10
- package/dist_ts/private/networkcontract.js +1 -1
- package/dist_ts/private/releaseversion.d.ts +37 -0
- package/dist_ts/private/releaseversion.js +48 -0
- package/dist_ts/private/runtimepolicy.d.ts +2 -2
- package/dist_ts/private/runtimepolicy.js +1 -1
- package/dist_ts/private/tokenlist.d.ts +9 -0
- package/dist_ts/private/tokenlist.js +23 -0
- package/dist_ts/protocol.d.ts +137 -0
- package/dist_ts/protocol.js +255 -0
- package/dist_ts/requests/admin.d.ts +8 -8
- package/dist_ts/requests/backup.d.ts +102 -112
- package/dist_ts/requests/cluster.d.ts +10 -10
- package/dist_ts/requests/clusteringress.d.ts +9 -0
- package/dist_ts/requests/clusteringress.js +1 -1
- package/dist_ts/requests/config.d.ts +3 -3
- package/dist_ts/requests/corestore.d.ts +0 -3
- package/dist_ts/requests/corestore.js +5 -9
- package/dist_ts/requests/network.d.ts +30 -30
- package/dist_ts/requests/node.d.ts +15 -28
- package/dist_ts/requests/pallet.d.ts +13 -13
- package/dist_ts/requests/runtimesession.d.ts +53 -41
- package/dist_ts/requests/secret.d.ts +4 -5
- package/dist_ts/requests/secret.js +1 -5
- package/dist_ts/runtime.corestore.d.ts +56 -74
- package/dist_ts/runtime.corestore.databaseexportpackage.d.ts +30 -36
- package/dist_ts/runtime.corestore.databaseexportpackage.golden.d.ts +11 -12
- package/dist_ts/runtime.corestore.databaseexportpackage.golden.js +54 -71
- package/dist_ts/runtime.corestore.databaseexportpackage.js +9 -25
- package/dist_ts/runtime.corestore.js +35 -135
- package/dist_ts/runtime.corestore.relay.js +2 -7
- package/dist_ts/runtime.d.ts +38 -48
- package/dist_ts/runtime.js +20 -77
- package/dist_ts/runtime.networkprojection.d.ts +4 -4
- package/dist_ts/runtime.networkprojection.js +18 -18
- package/dist_ts/runtime.workloadinit.d.ts +23 -24
- package/dist_ts/runtime.workloadinit.js +6 -13
- package/package.json +2 -2
- package/readme.md +421 -270
- package/ts/00_commitinfo_data.ts +3 -3
- package/ts/appstore/types.ts +4 -6
- package/ts/data/backup.ts +3 -38
- package/ts/data/cluster.ts +51 -34
- package/ts/data/clusteringress.ts +12 -12
- package/ts/data/clusternode.ts +204 -232
- package/ts/data/coremail.runtime.ts +4 -21
- package/ts/data/coremail.ts +3 -7
- package/ts/data/deploymentadoption.ts +46 -4
- package/ts/data/deploymentoperation.ts +16 -1
- package/ts/data/deploymentpreflight.ts +0 -2
- package/ts/data/immutableimage.ts +71 -24
- package/ts/data/index.ts +1 -1
- package/ts/data/isolatedrestore.golden.ts +5 -9
- package/ts/data/isolatedrestore.ts +339 -54
- package/ts/data/mail.ts +1 -1
- package/ts/data/networkaddressplan.ts +13 -13
- package/ts/data/networkauthority.ts +42 -46
- package/ts/data/networkcredential.ts +24 -24
- package/ts/data/networkdelivery.ts +27 -27
- package/ts/data/networklease.ts +40 -13
- package/ts/data/networknode.ts +2 -2
- package/ts/data/networkprojection.ts +119 -124
- package/ts/data/networkprotection.ts +54 -55
- package/ts/data/networkrouter.ts +14 -14
- package/ts/data/networksigning.ts +29 -32
- package/ts/data/nodecredential.ts +4 -6
- package/ts/data/nodeenrollment.ts +96 -114
- package/ts/data/privatenetwork.ts +58 -74
- package/ts/data/runtimeassignment.ts +143 -94
- package/ts/data/runtimeconfig.ts +45 -46
- package/ts/data/runtimesession.ts +185 -138
- package/ts/data/runtimeterminalreceipt.ts +72 -73
- package/ts/data/secret.ts +28 -76
- package/ts/data/servicecredential.ts +33 -43
- package/ts/data/serviceruntime.ts +11 -11
- package/ts/data/sparknodereport.ts +48 -36
- package/ts/data/webpush.ts +0 -1
- package/ts/index.ts +2 -0
- package/ts/platform/objectstorageretention.ts +36 -55
- package/ts/platform/storage.ts +1 -3
- package/ts/platform/storagemigration.golden.ts +7 -11
- package/ts/platform/storagemigration.ts +5 -55
- package/ts/platform/types.ts +2 -2
- package/ts/private/canonicaljson.ts +13 -1
- package/ts/private/dataproperties.ts +139 -0
- package/ts/private/networkcontract.ts +9 -9
- package/ts/private/releaseversion.ts +70 -0
- package/ts/private/runtimepolicy.ts +2 -2
- package/ts/private/tokenlist.ts +30 -0
- package/ts/protocol.ts +364 -0
- package/ts/requests/admin.ts +11 -11
- package/ts/requests/backup.ts +112 -117
- package/ts/requests/cluster.ts +13 -13
- package/ts/requests/clusteringress.ts +9 -0
- package/ts/requests/config.ts +3 -3
- package/ts/requests/corestore.ts +4 -16
- package/ts/requests/network.ts +40 -40
- package/ts/requests/node.ts +21 -38
- package/ts/requests/pallet.ts +17 -17
- package/ts/requests/runtimesession.ts +63 -51
- package/ts/requests/secret.ts +5 -10
- package/ts/runtime.corestore.databaseexportpackage.golden.ts +77 -95
- package/ts/runtime.corestore.databaseexportpackage.ts +51 -73
- package/ts/runtime.corestore.relay.ts +1 -10
- package/ts/runtime.corestore.ts +118 -268
- package/ts/runtime.networkprojection.ts +30 -30
- package/ts/runtime.ts +83 -158
- package/ts/runtime.workloadinit.ts +36 -48
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.d.ts +0 -902
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.golden.d.ts +0 -35
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.golden.js +0 -315
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.js +0 -3315
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.d.ts +0 -291
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.d.ts +0 -30
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.js +0 -408
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.js +0 -1126
- package/ts/runtime.cloudlylegacydeploymentsettlement.golden.ts +0 -421
- package/ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.ts +0 -510
- package/ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.ts +0 -2470
- package/ts/runtime.cloudlylegacydeploymentsettlement.ts +0 -6630
|
@@ -346,7 +346,7 @@ export const normalizeCoreMailCredentialVerifier = (
|
|
|
346
346
|
/^\$argon2id\$v=19\$m=65536,t=3,p=1\$([A-Za-z0-9+/]+)\$([A-Za-z0-9+/]+)$/,
|
|
347
347
|
);
|
|
348
348
|
if (!match) {
|
|
349
|
-
return fail(`${pathArg}.verificationHash must use the canonical argon2id
|
|
349
|
+
return fail(`${pathArg}.verificationHash must use the canonical argon2id PHC form`);
|
|
350
350
|
}
|
|
351
351
|
const [, saltBase64, digestBase64] = match;
|
|
352
352
|
decodeCanonicalBase64(
|
|
@@ -1585,7 +1585,6 @@ const normalizeBinding = (
|
|
|
1585
1585
|
record,
|
|
1586
1586
|
pathArg,
|
|
1587
1587
|
[
|
|
1588
|
-
'schemaVersion',
|
|
1589
1588
|
'bindingId',
|
|
1590
1589
|
'serviceId',
|
|
1591
1590
|
'tenantId',
|
|
@@ -1599,9 +1598,6 @@ const normalizeBinding = (
|
|
|
1599
1598
|
],
|
|
1600
1599
|
['defaultSender'],
|
|
1601
1600
|
);
|
|
1602
|
-
if (record.schemaVersion !== 2) {
|
|
1603
|
-
fail(`${pathArg}.schemaVersion must be 2`);
|
|
1604
|
-
}
|
|
1605
1601
|
const state = record.state === 'active'
|
|
1606
1602
|
|| record.state === 'draining'
|
|
1607
1603
|
|| record.state === 'disabled'
|
|
@@ -1628,7 +1624,6 @@ const normalizeBinding = (
|
|
|
1628
1624
|
}
|
|
1629
1625
|
|
|
1630
1626
|
const normalized: ICoreMailBindingDesiredState = {
|
|
1631
|
-
schemaVersion: 2,
|
|
1632
1627
|
bindingId: requireIdentifier(record.bindingId, `${pathArg}.bindingId`),
|
|
1633
1628
|
serviceId: requireIdentifier(record.serviceId, `${pathArg}.serviceId`),
|
|
1634
1629
|
tenantId: requireIdentifier(record.tenantId, `${pathArg}.tenantId`),
|
|
@@ -1771,12 +1766,9 @@ export const normalizeCoreMailDesiredState = (
|
|
|
1771
1766
|
assertKeys(
|
|
1772
1767
|
record,
|
|
1773
1768
|
'desiredState',
|
|
1774
|
-
['
|
|
1769
|
+
['configEpoch', 'bindings', 'gateway', 'cursorKeys'],
|
|
1775
1770
|
['smtp'],
|
|
1776
1771
|
);
|
|
1777
|
-
if (record.schemaVersion !== 2) {
|
|
1778
|
-
fail('desiredState.schemaVersion must be 2');
|
|
1779
|
-
}
|
|
1780
1772
|
const bindings = readArray(
|
|
1781
1773
|
record.bindings,
|
|
1782
1774
|
'desiredState.bindings',
|
|
@@ -1804,7 +1796,6 @@ export const normalizeCoreMailDesiredState = (
|
|
|
1804
1796
|
compareStrings(leftArg.bindingId, rightArg.bindingId),
|
|
1805
1797
|
);
|
|
1806
1798
|
const normalized: ICoreMailDesiredState = {
|
|
1807
|
-
schemaVersion: 2,
|
|
1808
1799
|
configEpoch: requireSafeInteger(record.configEpoch, 'desiredState.configEpoch', 1),
|
|
1809
1800
|
bindings,
|
|
1810
1801
|
gateway: normalizeGateway(record.gateway, 'desiredState.gateway'),
|
|
@@ -1999,13 +1990,9 @@ export const normalizeCoreMailControlBootstrap = (
|
|
|
1999
1990
|
assertKeys(
|
|
2000
1991
|
record,
|
|
2001
1992
|
'controlBootstrap',
|
|
2002
|
-
['
|
|
1993
|
+
['coreMailServiceId', 'credentials'],
|
|
2003
1994
|
);
|
|
2004
|
-
if (record.schemaVersion !== 1) {
|
|
2005
|
-
fail('controlBootstrap.schemaVersion must be 1');
|
|
2006
|
-
}
|
|
2007
1995
|
return deepFreezeValue({
|
|
2008
|
-
schemaVersion: 1,
|
|
2009
1996
|
coreMailServiceId: requireIdentifier(
|
|
2010
1997
|
record.coreMailServiceId,
|
|
2011
1998
|
'controlBootstrap.coreMailServiceId',
|
|
@@ -2024,13 +2011,9 @@ export const normalizeCoreMailGatewayPeerDesiredState = (
|
|
|
2024
2011
|
assertKeys(
|
|
2025
2012
|
record,
|
|
2026
2013
|
'gatewayPeer',
|
|
2027
|
-
['
|
|
2014
|
+
['coreMailServiceId', 'transferOrigin', 'credentials'],
|
|
2028
2015
|
);
|
|
2029
|
-
if (record.schemaVersion !== 1) {
|
|
2030
|
-
fail('gatewayPeer.schemaVersion must be 1');
|
|
2031
|
-
}
|
|
2032
2016
|
return deepFreezeValue({
|
|
2033
|
-
schemaVersion: 1,
|
|
2034
2017
|
coreMailServiceId: requireIdentifier(
|
|
2035
2018
|
record.coreMailServiceId,
|
|
2036
2019
|
'gatewayPeer.coreMailServiceId',
|
package/ts/data/coremail.ts
CHANGED
|
@@ -12,7 +12,7 @@ export type TCoreMailSha256 = `sha256:${string}`;
|
|
|
12
12
|
export type TCoreMailCapability = 'outbound' | 'inbound';
|
|
13
13
|
export type TCoreMailBindingState = 'active' | 'draining' | 'disabled';
|
|
14
14
|
export type TCoreMailCredentialState = 'current' | 'retiring';
|
|
15
|
-
export type TCoreMailCredentialVerifierFormat = 'argon2id
|
|
15
|
+
export type TCoreMailCredentialVerifierFormat = 'argon2id';
|
|
16
16
|
export type TCoreMailPartKind = 'text' | 'html' | 'attachment';
|
|
17
17
|
export type TCoreMailTransferMethod = 'PUT' | 'GET';
|
|
18
18
|
export type TCoreMailSubmissionState =
|
|
@@ -195,7 +195,7 @@ export interface ICoreMailBindingCredentialVerifier {
|
|
|
195
195
|
credentialId: string;
|
|
196
196
|
version: number;
|
|
197
197
|
state: TCoreMailCredentialState;
|
|
198
|
-
/**
|
|
198
|
+
/** The verifier contract this hash follows. CoreMail accepts only argon2id. */
|
|
199
199
|
format: TCoreMailCredentialVerifierFormat;
|
|
200
200
|
/** Password-verifier string only. Plaintext credential material is never part of desired state. */
|
|
201
201
|
verificationHash: string;
|
|
@@ -203,7 +203,6 @@ export interface ICoreMailBindingCredentialVerifier {
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
export interface ICoreMailBindingDesiredState {
|
|
206
|
-
schemaVersion: 2;
|
|
207
206
|
bindingId: string;
|
|
208
207
|
serviceId: string;
|
|
209
208
|
tenantId: string;
|
|
@@ -237,7 +236,6 @@ export interface ICoreMailGatewayDesiredState {
|
|
|
237
236
|
* configuration; the matching plaintext is delivered only to Coreflow.
|
|
238
237
|
*/
|
|
239
238
|
export interface ICoreMailControlBootstrap {
|
|
240
|
-
schemaVersion: 1;
|
|
241
239
|
coreMailServiceId: string;
|
|
242
240
|
credentials: ICoreMailBindingCredentialVerifier[];
|
|
243
241
|
}
|
|
@@ -247,7 +245,6 @@ export interface ICoreMailControlBootstrap {
|
|
|
247
245
|
* transferOrigin is authoritative control-plane data, never peer supplied.
|
|
248
246
|
*/
|
|
249
247
|
export interface ICoreMailGatewayPeerDesiredState {
|
|
250
|
-
schemaVersion: 1;
|
|
251
248
|
coreMailServiceId: string;
|
|
252
249
|
transferOrigin: string;
|
|
253
250
|
credentials: ICoreMailBindingCredentialVerifier[];
|
|
@@ -288,7 +285,6 @@ export interface ICoreMailSmtpDesiredState {
|
|
|
288
285
|
}
|
|
289
286
|
|
|
290
287
|
export interface ICoreMailDesiredState {
|
|
291
|
-
schemaVersion: 2;
|
|
292
288
|
configEpoch: number;
|
|
293
289
|
bindings: ICoreMailBindingDesiredState[];
|
|
294
290
|
gateway: ICoreMailGatewayDesiredState;
|
|
@@ -486,7 +482,7 @@ export const coreMailTransferProtocol = Object.freeze({
|
|
|
486
482
|
});
|
|
487
483
|
|
|
488
484
|
export const coreMailCredentialVerifierPolicy = Object.freeze({
|
|
489
|
-
format: 'argon2id
|
|
485
|
+
format: 'argon2id' as const,
|
|
490
486
|
version: 19,
|
|
491
487
|
memoryCost: 65_536,
|
|
492
488
|
timeCost: 3,
|
|
@@ -12,12 +12,14 @@ import type {
|
|
|
12
12
|
TSha256Digest,
|
|
13
13
|
} from './immutableimage.js';
|
|
14
14
|
import {
|
|
15
|
+
isCoreflowRuntimeCapabilityList,
|
|
15
16
|
normalizeImmutableReleaseTag,
|
|
16
17
|
normalizeSha256Digest,
|
|
17
18
|
validateImageRolloutStatus,
|
|
18
19
|
validateImmutableImageDeploymentPlan,
|
|
19
20
|
} from './immutableimage.js';
|
|
20
21
|
import type { IRegistryTarget } from './registry.js';
|
|
22
|
+
import { hasExactKeys } from '../private/dataproperties.js';
|
|
21
23
|
|
|
22
24
|
export type TServiceDeploymentAdoptionDecision = 'GO' | 'NO-GO';
|
|
23
25
|
|
|
@@ -115,7 +117,6 @@ export interface IServiceDeploymentAdoptionRolloutResult {
|
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
interface IServiceDeploymentAdoptionReportBase {
|
|
118
|
-
schemaVersion: 1;
|
|
119
120
|
mutationPerformed: false;
|
|
120
121
|
requestId: string;
|
|
121
122
|
generatedAt: number;
|
|
@@ -202,7 +203,6 @@ export type TServiceDeploymentAdoptionRetentionPhase = 'prepare' | 'commit';
|
|
|
202
203
|
* retained for the exact adoption plan without mutating the Docker service.
|
|
203
204
|
*/
|
|
204
205
|
export interface IServiceDeploymentAdoptionRetentionAttestation {
|
|
205
|
-
schemaVersion: 1;
|
|
206
206
|
phase: TServiceDeploymentAdoptionRetentionPhase;
|
|
207
207
|
retainedWithoutMutation: true;
|
|
208
208
|
serviceId: string;
|
|
@@ -213,12 +213,26 @@ export interface IServiceDeploymentAdoptionRetentionAttestation {
|
|
|
213
213
|
attestedAt: number;
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
+
/** Every key a retention attestation carries; nothing else is admitted. */
|
|
217
|
+
const retentionAttestationKeys = [
|
|
218
|
+
'phase',
|
|
219
|
+
'retainedWithoutMutation',
|
|
220
|
+
'serviceId',
|
|
221
|
+
'operationId',
|
|
222
|
+
'adoptionConfigurationDigest',
|
|
223
|
+
'immutableReport',
|
|
224
|
+
'deployments',
|
|
225
|
+
'attestedAt',
|
|
226
|
+
] as const;
|
|
227
|
+
|
|
216
228
|
export const validateServiceDeploymentAdoptionRetentionAttestation = (
|
|
217
229
|
attestationArg: unknown,
|
|
218
230
|
): string[] => {
|
|
219
231
|
if (!isRecord(attestationArg)) return ['retention attestation must be an object'];
|
|
220
232
|
const errors: string[] = [];
|
|
221
|
-
if (attestationArg
|
|
233
|
+
if (!hasExactKeys(attestationArg, retentionAttestationKeys)) {
|
|
234
|
+
errors.push('retention attestation must use its exact schema');
|
|
235
|
+
}
|
|
222
236
|
if (attestationArg.phase !== 'prepare' && attestationArg.phase !== 'commit') {
|
|
223
237
|
errors.push('retention attestation phase is invalid');
|
|
224
238
|
}
|
|
@@ -237,6 +251,10 @@ export const validateServiceDeploymentAdoptionRetentionAttestation = (
|
|
|
237
251
|
}
|
|
238
252
|
if (!isRecord(attestationArg.immutableReport)) {
|
|
239
253
|
errors.push('retention attestation requires an immutable report envelope');
|
|
254
|
+
} else if (!isCoreflowRuntimeCapabilityList(attestationArg.immutableReport.reporterCapabilities)) {
|
|
255
|
+
// The envelope states what the reporter can do; a list that is not canonical cannot be
|
|
256
|
+
// compared against the one its registration stated, so the attestation is refused here.
|
|
257
|
+
errors.push('retention attestation reporter capabilities must be a canonical capability list');
|
|
240
258
|
}
|
|
241
259
|
if (!Array.isArray(attestationArg.deployments) || attestationArg.deployments.length < 1) {
|
|
242
260
|
errors.push('retention attestation requires at least one deployment');
|
|
@@ -500,10 +518,34 @@ export const validateServiceDeploymentAdoptionRolloutResult = (
|
|
|
500
518
|
return errors;
|
|
501
519
|
};
|
|
502
520
|
|
|
521
|
+
/** Every key an adoption report carries, whatever it decided. */
|
|
522
|
+
const reportKeys = [
|
|
523
|
+
'mutationPerformed',
|
|
524
|
+
'requestId',
|
|
525
|
+
'generatedAt',
|
|
526
|
+
'runtimeAttestation',
|
|
527
|
+
'decision',
|
|
528
|
+
'registry',
|
|
529
|
+
'runtimeTasks',
|
|
530
|
+
'blockers',
|
|
531
|
+
] as const;
|
|
532
|
+
|
|
533
|
+
/** A GO report also states the scope it adopts into and the digest it adopted. */
|
|
534
|
+
const goReportKeys = [...reportKeys, 'service', 'targetScope', 'adoptionDigest'] as const;
|
|
535
|
+
|
|
536
|
+
/** A NO-GO report may have stopped before it read the service or resolved a scope. */
|
|
537
|
+
const noGoReportOptionalKeys = ['service', 'targetScope'] as const;
|
|
538
|
+
|
|
503
539
|
export const validateServiceDeploymentAdoptionReport = (reportArg: unknown): string[] => {
|
|
504
540
|
if (!isRecord(reportArg)) return ['adoption report must be an object'];
|
|
505
541
|
const errors: string[] = [];
|
|
506
|
-
if (
|
|
542
|
+
if (!hasExactKeys(
|
|
543
|
+
reportArg,
|
|
544
|
+
reportArg.decision === 'GO' ? goReportKeys : reportKeys,
|
|
545
|
+
reportArg.decision === 'GO' ? [] : noGoReportOptionalKeys,
|
|
546
|
+
)) {
|
|
547
|
+
errors.push('adoption report must use its exact decision schema');
|
|
548
|
+
}
|
|
507
549
|
if (reportArg.mutationPerformed !== false) {
|
|
508
550
|
errors.push('adoption preflight must be mutation-free');
|
|
509
551
|
}
|
|
@@ -3,6 +3,7 @@ import type { IGatewayRouteDnsResult } from './gateway.js';
|
|
|
3
3
|
import type { IImageRolloutStatus, IImmutableImageDeploymentPlan, TSha256Digest } from './immutableimage.js';
|
|
4
4
|
import { normalizeImmutableReleaseTag, normalizeSha256Digest } from './immutableimage.js';
|
|
5
5
|
import type { IRegistryTarget } from './registry.js';
|
|
6
|
+
import { hasExactKeys } from '../private/dataproperties.js';
|
|
6
7
|
import { normalizeServiceAbsolutePath, validateServiceContainerArgs } from './service.js';
|
|
7
8
|
import type { TServiceTargetPortRef } from './serviceports.js';
|
|
8
9
|
|
|
@@ -148,12 +149,26 @@ const validateStringArray = (
|
|
|
148
149
|
&& validatorArg(itemArg))
|
|
149
150
|
&& new Set(valueArg).size === valueArg.length;
|
|
150
151
|
|
|
152
|
+
/** Every key a proposed configuration carries; `containerArgs` is the one a template may omit. */
|
|
153
|
+
const proposedConfigurationKeys = [
|
|
154
|
+
'declarationComplete',
|
|
155
|
+
'projectName',
|
|
156
|
+
'targetPlatforms',
|
|
157
|
+
'publicDomains',
|
|
158
|
+
'environmentVariableNames',
|
|
159
|
+
'containerPorts',
|
|
160
|
+
'volumeMounts',
|
|
161
|
+
'requiredCapabilities',
|
|
162
|
+
] as const;
|
|
163
|
+
|
|
151
164
|
export const validateDeploymentProposedConfiguration = (
|
|
152
165
|
configurationArg: unknown,
|
|
153
166
|
): string[] => {
|
|
154
167
|
if (!isRecord(configurationArg)) return ['proposedConfiguration must be an object'];
|
|
155
168
|
const errors: string[] = [];
|
|
156
|
-
if (configurationArg
|
|
169
|
+
if (!hasExactKeys(configurationArg, proposedConfigurationKeys, ['containerArgs'])) {
|
|
170
|
+
errors.push('proposedConfiguration must use its exact schema');
|
|
171
|
+
}
|
|
157
172
|
if (typeof configurationArg.declarationComplete !== 'boolean') {
|
|
158
173
|
errors.push('declarationComplete must be boolean');
|
|
159
174
|
}
|
|
@@ -142,7 +142,6 @@ export interface IDeploymentPreflightProposedVolumeMount {
|
|
|
142
142
|
* cluster names through this contract.
|
|
143
143
|
*/
|
|
144
144
|
export interface IDeploymentPreflightProposedConfiguration {
|
|
145
|
-
schemaVersion: 1;
|
|
146
145
|
declarationComplete: boolean;
|
|
147
146
|
projectName: string;
|
|
148
147
|
targetPlatforms: TImmutableContainerPlatform[];
|
|
@@ -194,7 +193,6 @@ export interface IDeploymentPreflightRequestData {
|
|
|
194
193
|
}
|
|
195
194
|
|
|
196
195
|
export interface IDeploymentPreflightReport {
|
|
197
|
-
schemaVersion: 2;
|
|
198
196
|
decision: TDeploymentPreflightDecision;
|
|
199
197
|
mutationPerformed: false;
|
|
200
198
|
generatedAt: number;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isCanonicalTokenList } from '../private/tokenlist.js';
|
|
2
|
+
|
|
1
3
|
/** Canonical lower-case OCI sha256 digest. */
|
|
2
4
|
export type TSha256Digest = `sha256:${string}`;
|
|
3
5
|
|
|
@@ -62,22 +64,70 @@ export type TImmutableImageRolloutStatus =
|
|
|
62
64
|
| 'rolling-back'
|
|
63
65
|
| 'rolled-back';
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
/**
|
|
68
|
+
* What a Coreflow build can do, named one capability at a time.
|
|
69
|
+
*
|
|
70
|
+
* A capability used to be advertised as the shape version the build spoke, which said two things
|
|
71
|
+
* at once: that the contract existed and which of its shapes was meant. The contract version is
|
|
72
|
+
* the interfaces version both peers exchange, so what is left to state is the capability itself.
|
|
73
|
+
*/
|
|
74
|
+
export const coreflowRuntimeCapabilities = Object.freeze([
|
|
75
|
+
/** Answers the node-scoped Corestore inventory probe. */
|
|
76
|
+
'corestore-inventory',
|
|
77
|
+
/** Deploys an image by its immutable digest and reports the rollout. */
|
|
78
|
+
'immutable-image-deployment',
|
|
79
|
+
/** Opens sealed secret material addressed to its recipient key. */
|
|
80
|
+
'sealed-secret-material',
|
|
81
|
+
/** Submits replay-safe secret deployment reports. */
|
|
82
|
+
'secret-deployment-report',
|
|
83
|
+
/** Consumes exact, cluster-scoped resolved secret manifests. */
|
|
84
|
+
'secret-manifest',
|
|
85
|
+
/** Enrolls as a secret recipient and answers the enrollment challenge. */
|
|
86
|
+
'secret-recipient-enrollment',
|
|
87
|
+
/** Writes the WorkloadInit environment map and launches through the wrapper. */
|
|
88
|
+
'workload-init-environment',
|
|
89
|
+
] as const);
|
|
90
|
+
|
|
91
|
+
/** One capability a Coreflow build states in its secret-runtime registration. */
|
|
92
|
+
export type TCoreflowRuntimeCapability = typeof coreflowRuntimeCapabilities[number];
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The capabilities a build may legitimately lack.
|
|
96
|
+
*
|
|
97
|
+
* `corestore-inventory` depends on the node's Corestore deployment rather than on the contracts
|
|
98
|
+
* the build was compiled against, so a build without one still registers.
|
|
99
|
+
*/
|
|
100
|
+
export const optionalCoreflowRuntimeCapabilities = Object.freeze(
|
|
101
|
+
['corestore-inventory'] as const satisfies readonly TCoreflowRuntimeCapability[],
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The capabilities every build of this major has, so a registration that omits one is refused.
|
|
106
|
+
*
|
|
107
|
+
* Filtered out of the vocabulary rather than listed again: a capability added to the vocabulary is
|
|
108
|
+
* required from that moment unless it is named optional, which is the decision worth stating.
|
|
109
|
+
*/
|
|
110
|
+
export const requiredCoreflowRuntimeCapabilities: readonly TCoreflowRuntimeCapability[] =
|
|
111
|
+
Object.freeze(coreflowRuntimeCapabilities.filter((capabilityArg) => (
|
|
112
|
+
!optionalCoreflowRuntimeCapabilities.some((optionalArg) => optionalArg === capabilityArg)
|
|
113
|
+
)));
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* True when a value is exactly a canonical capability list that carries every capability this
|
|
117
|
+
* major requires ā the canonical-list rule plus this contract's own coverage clause.
|
|
118
|
+
*/
|
|
119
|
+
export const isCoreflowRuntimeCapabilityList = (
|
|
120
|
+
valueArg: unknown,
|
|
121
|
+
): valueArg is TCoreflowRuntimeCapability[] => (
|
|
122
|
+
isCanonicalTokenList(valueArg, coreflowRuntimeCapabilities)
|
|
123
|
+
&& requiredCoreflowRuntimeCapabilities.every(
|
|
124
|
+
(capabilityArg) => valueArg.some((entryArg) => entryArg === capabilityArg),
|
|
125
|
+
)
|
|
126
|
+
);
|
|
77
127
|
|
|
78
128
|
export type TImmutableContainerPlatform = 'linux/amd64' | 'linux/arm64';
|
|
79
129
|
|
|
80
|
-
export interface
|
|
130
|
+
export interface IImmutableContainerInvocationPlatformEvidence {
|
|
81
131
|
platform: TImmutableContainerPlatform;
|
|
82
132
|
platformManifestDigest: TSha256Digest;
|
|
83
133
|
imageConfigDigest: TSha256Digest;
|
|
@@ -85,14 +135,13 @@ export interface IImmutableContainerInvocationPlatformEvidenceV1 {
|
|
|
85
135
|
effectiveArgv: string[];
|
|
86
136
|
}
|
|
87
137
|
|
|
88
|
-
export interface
|
|
89
|
-
schemaVersion: 1;
|
|
138
|
+
export interface IImmutableContainerInvocation {
|
|
90
139
|
/** Sorted, unique, non-empty and limited to the authoritative platform union. */
|
|
91
140
|
targetPlatforms: TImmutableContainerPlatform[];
|
|
92
141
|
/** The one effective argv shared by every target platform. */
|
|
93
142
|
argv: string[];
|
|
94
143
|
/** Sorted exact one-to-one platform evidence. */
|
|
95
|
-
evidence:
|
|
144
|
+
evidence: IImmutableContainerInvocationPlatformEvidence[];
|
|
96
145
|
digest: TSha256Digest;
|
|
97
146
|
}
|
|
98
147
|
|
|
@@ -248,7 +297,7 @@ export interface IImmutableImageDeploymentPlan {
|
|
|
248
297
|
digestPinnedImageReference: string;
|
|
249
298
|
manifestMediaType: TOciManifestMediaType;
|
|
250
299
|
/** Mandatory immutable command/config evidence for every target platform. */
|
|
251
|
-
containerInvocation:
|
|
300
|
+
containerInvocation: IImmutableContainerInvocation;
|
|
252
301
|
createdAt: number;
|
|
253
302
|
mode: TImmutableImageRolloutMode;
|
|
254
303
|
/** Full pre-adoption service configuration fence, required only for adoption. */
|
|
@@ -313,7 +362,8 @@ export interface IImmutableRolloutReportEnvelope {
|
|
|
313
362
|
rolloutGeneration: number;
|
|
314
363
|
reporterSessionId: string;
|
|
315
364
|
reportSequence: number;
|
|
316
|
-
|
|
365
|
+
/** Sorted and duplicate-free; every required capability of this major is present. */
|
|
366
|
+
reporterCapabilities: TCoreflowRuntimeCapability[];
|
|
317
367
|
reporterNodeIds: string[];
|
|
318
368
|
reporterNodeNames: string[];
|
|
319
369
|
}
|
|
@@ -368,9 +418,8 @@ const validateImmutableArgv = (argvArg: unknown): argvArg is string[] => (
|
|
|
368
418
|
);
|
|
369
419
|
|
|
370
420
|
export const createImmutableContainerInvocationDigestInput = (
|
|
371
|
-
invocationArg: Omit<
|
|
421
|
+
invocationArg: Omit<IImmutableContainerInvocation, 'digest'> | IImmutableContainerInvocation,
|
|
372
422
|
): string => JSON.stringify({
|
|
373
|
-
schemaVersion: invocationArg.schemaVersion,
|
|
374
423
|
targetPlatforms: invocationArg.targetPlatforms,
|
|
375
424
|
argv: invocationArg.argv,
|
|
376
425
|
evidence: invocationArg.evidence.map((entryArg) => ({
|
|
@@ -382,7 +431,7 @@ export const createImmutableContainerInvocationDigestInput = (
|
|
|
382
431
|
});
|
|
383
432
|
|
|
384
433
|
export const computeImmutableContainerInvocationDigest = async (
|
|
385
|
-
invocationArg: Omit<
|
|
434
|
+
invocationArg: Omit<IImmutableContainerInvocation, 'digest'> | IImmutableContainerInvocation,
|
|
386
435
|
): Promise<TSha256Digest> => {
|
|
387
436
|
const input = new TextEncoder().encode(createImmutableContainerInvocationDigestInput(invocationArg));
|
|
388
437
|
const digest = new Uint8Array(await globalThis.crypto.subtle.digest(
|
|
@@ -395,7 +444,7 @@ export const computeImmutableContainerInvocationDigest = async (
|
|
|
395
444
|
};
|
|
396
445
|
|
|
397
446
|
export const verifyImmutableContainerInvocationDigest = async (
|
|
398
|
-
invocationArg:
|
|
447
|
+
invocationArg: IImmutableContainerInvocation,
|
|
399
448
|
): Promise<boolean> => invocationArg.digest
|
|
400
449
|
=== await computeImmutableContainerInvocationDigest(invocationArg);
|
|
401
450
|
|
|
@@ -411,12 +460,10 @@ export const validateImmutableContainerInvocation = (
|
|
|
411
460
|
'argv',
|
|
412
461
|
'digest',
|
|
413
462
|
'evidence',
|
|
414
|
-
'schemaVersion',
|
|
415
463
|
'targetPlatforms',
|
|
416
464
|
])) {
|
|
417
465
|
errors.push('containerInvocation must use its exact schema');
|
|
418
466
|
}
|
|
419
|
-
if (invocation.schemaVersion !== 1) errors.push('containerInvocation schemaVersion must be 1');
|
|
420
467
|
const platforms = Array.isArray(invocation.targetPlatforms)
|
|
421
468
|
? invocation.targetPlatforms
|
|
422
469
|
: [];
|
package/ts/data/index.ts
CHANGED
|
@@ -32,7 +32,7 @@ export * from './networkdelivery.js';
|
|
|
32
32
|
export * from './networklease.js';
|
|
33
33
|
export * from './networknode.js';
|
|
34
34
|
export * from './networkprojection.js';
|
|
35
|
-
export type {
|
|
35
|
+
export type { IRuntimeNetworkRouterPacketGrant, IRuntimeNetworkRouterProjection } from './networkrouter.js';
|
|
36
36
|
export * from './networkprotection.js';
|
|
37
37
|
export * from './networksigning.js';
|
|
38
38
|
export * from './privatenetwork.js';
|
|
@@ -29,7 +29,6 @@ const deepFreezeVector = <T>(valueArg: T): T => {
|
|
|
29
29
|
* quote, and a backslash. Consumers compare both JSON and SHA-256 verbatim.
|
|
30
30
|
*/
|
|
31
31
|
export const isolatedRestoreCanonicalDigestGoldenVectors: {
|
|
32
|
-
version: 1;
|
|
33
32
|
resourceMappings: IIsolatedRestoreCanonicalDigestGoldenVector<
|
|
34
33
|
TIsolatedRestoreResourceMapping[]
|
|
35
34
|
>;
|
|
@@ -40,7 +39,6 @@ export const isolatedRestoreCanonicalDigestGoldenVectors: {
|
|
|
40
39
|
IIsolatedRestoreGrantClaims
|
|
41
40
|
>;
|
|
42
41
|
} = deepFreezeVector({
|
|
43
|
-
version: 1,
|
|
44
42
|
resourceMappings: {
|
|
45
43
|
input: [
|
|
46
44
|
{
|
|
@@ -91,7 +89,6 @@ export const isolatedRestoreCanonicalDigestGoldenVectors: {
|
|
|
91
89
|
},
|
|
92
90
|
archiveManifest: {
|
|
93
91
|
input: {
|
|
94
|
-
version: 1,
|
|
95
92
|
backupId: 'backup-0001',
|
|
96
93
|
createdAt: 1700000000123,
|
|
97
94
|
objects: [
|
|
@@ -122,12 +119,11 @@ export const isolatedRestoreCanonicalDigestGoldenVectors: {
|
|
|
122
119
|
'{"backupId":"backup-0001","createdAt":1700000000123,"objects":[{"path":"config.json","sha256":"0000000000000000000000000000000000000000000000000000000000000000","size":2},' +
|
|
123
120
|
'{"path":"snapshots/snapshot-volume.json","sha256":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","size":3},' +
|
|
124
121
|
'{"path":"snapshots/snapshot-database.json","sha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","size":5},' +
|
|
125
|
-
'{"path":"snapshots/snapshot-objectstorage.json","sha256":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","size":7}],"totalSize":17
|
|
126
|
-
sha256: '
|
|
122
|
+
'{"path":"snapshots/snapshot-objectstorage.json","sha256":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","size":7}],"totalSize":17}',
|
|
123
|
+
sha256: '5063bbb4e967fc01023fe498274039395bfb3dc82f85a35acd6cda64ac723cb9',
|
|
127
124
|
},
|
|
128
125
|
grantClaims: {
|
|
129
126
|
input: {
|
|
130
|
-
grantVersion: 1,
|
|
131
127
|
iss: 'urn:foss:restore:š:Ć©:eĢ:"quoted":\\backslash',
|
|
132
128
|
aud: 'corestore.restore',
|
|
133
129
|
sub: 'cloudly-control',
|
|
@@ -143,15 +139,15 @@ export const isolatedRestoreCanonicalDigestGoldenVectors: {
|
|
|
143
139
|
stagingArchiveId: 'archive-0001',
|
|
144
140
|
operation: 'prepare',
|
|
145
141
|
resourceMappingsSha256: '3c084580fc258dcb5dc25b80d7331eb1d9072a124f640df3ce26eba4917afe70',
|
|
146
|
-
archiveManifestSha256: '
|
|
142
|
+
archiveManifestSha256: '5063bbb4e967fc01023fe498274039395bfb3dc82f85a35acd6cda64ac723cb9',
|
|
147
143
|
iat: 2_000_000_000,
|
|
148
144
|
nbf: 2_000_000_000,
|
|
149
145
|
exp: 2_000_000_120,
|
|
150
146
|
},
|
|
151
147
|
canonicalJson:
|
|
152
|
-
'{"archiveManifestSha256":"
|
|
148
|
+
'{"archiveManifestSha256":"5063bbb4e967fc01023fe498274039395bfb3dc82f85a35acd6cda64ac723cb9","aud":"corestore.restore","authorizationId":"authorization-0001","clusterId":"cluster-eu-1","exp":2000000120,"iat":2000000000,' +
|
|
153
149
|
'"iss":"urn:foss:restore:š:Ć©:eĢ:\\"quoted\\":\\\\backslash","jti":"grant-0001","nbf":2000000000,"operation":"prepare","resourceMappingsSha256":"3c084580fc258dcb5dc25b80d7331eb1d9072a124f640df3ce26eba4917afe70",' +
|
|
154
150
|
'"restoreId":"restore-0001","scratchNamespaceId":"scratch-0001","sourceBackupId":"backup-0001","sourceServiceId":"service-source","stagingArchiveId":"archive-0001","sub":"cloudly-control","targetNodeName":"node-1","tenantId":"tenant-0001"}',
|
|
155
|
-
sha256: '
|
|
151
|
+
sha256: '7346ba0b19a66535183c7afa6cb1f76236fd0c7f9f678a1695cca9874f8f3743',
|
|
156
152
|
},
|
|
157
153
|
});
|