@serve.zone/interfaces 31.8.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 +512 -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/clusterruntime.d.ts +39 -0
- package/dist_ts/data/clusterruntime.js +11 -0
- 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 +5 -1
- package/dist_ts/data/index.js +5 -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 +78 -0
- package/dist_ts/data/networkaddressplan.js +114 -0
- package/dist_ts/data/networkauthority.d.ts +20 -22
- package/dist_ts/data/networkauthority.js +29 -43
- 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 +37 -0
- package/dist_ts/data/networknode.js +6 -0
- 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 +37 -100
- 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 +128 -0
- package/dist_ts/data/serviceruntime.js +92 -0
- 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 +14 -10
- package/dist_ts/private/networkcontract.js +15 -1
- package/dist_ts/private/producercontract.d.ts +11 -0
- package/dist_ts/private/producercontract.js +21 -0
- package/dist_ts/private/releaseversion.d.ts +37 -0
- package/dist_ts/private/releaseversion.js +48 -0
- package/dist_ts/private/runtimepolicy.d.ts +31 -0
- package/dist_ts/private/runtimepolicy.js +90 -0
- 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 +47 -10
- package/dist_ts/requests/cluster.js +1 -1
- 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 +87 -31
- 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/requests/service.d.ts +60 -0
- 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 +540 -269
- 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/clusterruntime.ts +45 -0
- 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 +5 -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 +175 -0
- package/ts/data/networkauthority.ts +45 -61
- 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 +37 -0
- 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 +62 -122
- 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 +208 -0
- 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 +23 -9
- package/ts/private/producercontract.ts +19 -0
- package/ts/private/releaseversion.ts +70 -0
- package/ts/private/runtimepolicy.ts +105 -0
- 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 +58 -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 +90 -41
- 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/requests/service.ts +81 -0
- 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
|
@@ -1,17 +1,11 @@
|
|
|
1
|
+
import { readDataElements, readDataProperty, readExactDataRecord, } from '../private/dataproperties.js';
|
|
1
2
|
const fail = () => { throw new Error('Service credential contract rejected.'); };
|
|
2
3
|
function requireValue(value) { if (!value)
|
|
3
4
|
fail(); }
|
|
5
|
+
/** Exactly this shape's keys, read once as data; an accessor is refused, never invoked. */
|
|
4
6
|
const object = (value, keys) => {
|
|
5
|
-
|
|
6
|
-
requireValue(
|
|
7
|
-
const actual = Reflect.ownKeys(value);
|
|
8
|
-
requireValue(actual.length === keys.length && keys.every((key) => actual.includes(key)));
|
|
9
|
-
const copy = Object.create(null);
|
|
10
|
-
for (const key of keys) {
|
|
11
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
12
|
-
requireValue(descriptor && Object.hasOwn(descriptor, 'value') && descriptor.enumerable);
|
|
13
|
-
copy[key] = descriptor.value;
|
|
14
|
-
}
|
|
7
|
+
const copy = readExactDataRecord(value, keys);
|
|
8
|
+
requireValue(copy !== null);
|
|
15
9
|
return copy;
|
|
16
10
|
};
|
|
17
11
|
const identifier = (value) => {
|
|
@@ -23,11 +17,8 @@ const counter = (value) => {
|
|
|
23
17
|
return value;
|
|
24
18
|
};
|
|
25
19
|
const capabilities = (value) => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
requireValue(keys.length === 2 && keys.includes('length') && keys.includes('0'));
|
|
29
|
-
const entry = Object.getOwnPropertyDescriptor(value, '0');
|
|
30
|
-
requireValue(entry && Object.hasOwn(entry, 'value') && entry.enumerable && entry.value === 'platform:session');
|
|
20
|
+
const entries = readDataElements(value, 1);
|
|
21
|
+
requireValue(entries !== null && entries.length === 1 && entries[0] === 'platform:session');
|
|
31
22
|
return ['platform:session'];
|
|
32
23
|
};
|
|
33
24
|
const safe = (operation) => { try {
|
|
@@ -37,19 +28,17 @@ catch {
|
|
|
37
28
|
return fail();
|
|
38
29
|
} };
|
|
39
30
|
/** Structural copy only; the backend must fence live service ownership and credential authority. */
|
|
40
|
-
export const
|
|
31
|
+
export const snapshotServiceMachineGrant = (value) => safe(() => {
|
|
41
32
|
const grant = object(value, ['organizationId', 'serviceId', 'capabilities']);
|
|
42
33
|
return { organizationId: identifier(grant.organizationId), serviceId: identifier(grant.serviceId),
|
|
43
34
|
capabilities: capabilities(grant.capabilities) };
|
|
44
35
|
});
|
|
45
|
-
export const
|
|
46
|
-
|
|
47
|
-
const operation = Object.getOwnPropertyDescriptor(value, 'operation')?.value;
|
|
36
|
+
export const snapshotServiceMachineCredentialMutation = (value) => safe(() => {
|
|
37
|
+
const operation = readDataProperty(value, 'operation')?.value;
|
|
48
38
|
requireValue(operation === 'ensure' || operation === 'rotate' || operation === 'revoke');
|
|
49
|
-
const request = object(value, ['
|
|
39
|
+
const request = object(value, ['organizationId', 'serviceId', 'mutationId', 'operation',
|
|
50
40
|
'expectedGeneration', ...(operation === 'revoke' ? [] : ['capabilities', 'expiresAt'])]);
|
|
51
|
-
|
|
52
|
-
const base = { schemaVersion: 1, organizationId: identifier(request.organizationId),
|
|
41
|
+
const base = { organizationId: identifier(request.organizationId),
|
|
53
42
|
serviceId: identifier(request.serviceId), mutationId: identifier(request.mutationId) };
|
|
54
43
|
if (operation === 'revoke')
|
|
55
44
|
return { ...base, operation, expectedGeneration: counter(request.expectedGeneration) };
|
|
@@ -60,10 +49,10 @@ export const snapshotServiceMachineCredentialMutationV1 = (value) => safe(() =>
|
|
|
60
49
|
}
|
|
61
50
|
return { ...base, ...material, operation, expectedGeneration: counter(request.expectedGeneration) };
|
|
62
51
|
});
|
|
63
|
-
export const
|
|
64
|
-
const metadata = object(value, ['
|
|
52
|
+
export const snapshotServiceMachineCredentialMetadata = (value) => safe(() => {
|
|
53
|
+
const metadata = object(value, ['credentialId', 'userId', 'grant', 'generation', 'state',
|
|
65
54
|
'expiresAt', 'createdAt', 'updatedAt', 'delivery']);
|
|
66
|
-
requireValue(metadata.
|
|
55
|
+
requireValue(metadata.state === 'active' || metadata.state === 'revoked');
|
|
67
56
|
const createdAt = counter(metadata.createdAt);
|
|
68
57
|
const updatedAt = counter(metadata.updatedAt);
|
|
69
58
|
requireValue(updatedAt >= createdAt);
|
|
@@ -74,8 +63,8 @@ export const snapshotServiceMachineCredentialMetadataV1 = (value) => safe(() =>
|
|
|
74
63
|
}
|
|
75
64
|
else
|
|
76
65
|
requireValue(metadata.delivery === null);
|
|
77
|
-
return {
|
|
78
|
-
grant:
|
|
66
|
+
return { credentialId: identifier(metadata.credentialId), userId: identifier(metadata.userId),
|
|
67
|
+
grant: snapshotServiceMachineGrant(metadata.grant), generation: counter(metadata.generation),
|
|
79
68
|
state: metadata.state, expiresAt: counter(metadata.expiresAt), createdAt, updatedAt, delivery };
|
|
80
69
|
});
|
|
81
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
70
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZWNyZWRlbnRpYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL3NlcnZpY2VjcmVkZW50aWFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxtQkFBbUIsR0FDeEQsTUFBTSw4QkFBOEIsQ0FBQztBQXdEdEMsTUFBTSxJQUFJLEdBQUcsR0FBVSxFQUFFLEdBQUcsTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hGLFNBQVMsWUFBWSxDQUFDLEtBQWMsSUFBbUIsSUFBSSxDQUFDLEtBQUs7SUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUUsMkZBQTJGO0FBQzNGLE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBYyxFQUFFLElBQXVCLEVBQTJCLEVBQUU7SUFDbEYsTUFBTSxJQUFJLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzlDLFlBQVksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUM7SUFDNUIsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDLENBQUM7QUFDRixNQUFNLFVBQVUsR0FBRyxDQUFDLEtBQWMsRUFBVSxFQUFFO0lBQzVDLFlBQVksQ0FBQyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUkscUNBQXFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDN0YsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDLENBQUM7QUFDRixNQUFNLE9BQU8sR0FBRyxDQUFDLEtBQWMsRUFBVSxFQUFFO0lBQ3pDLFlBQVksQ0FBQyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJ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
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { IRuntimeAssignmentObservation, IRuntimeAssignmentReference, TRuntimeAssignmentDisposition } from './runtimeassignment.js';
|
|
2
|
+
import type { IRuntimeConfigLogPolicy, TRuntimeConfigReadiness } from './runtimeconfig.js';
|
|
3
|
+
/** `nodes` pins the service to exactly these nodes: sorted, unique and never empty. */
|
|
4
|
+
export type TServiceRuntimePlacement = {
|
|
5
|
+
kind: 'every-node';
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'nodes';
|
|
8
|
+
nodeIds: string[];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* The execution policy a service's runtime configs are built with. It carries everything the
|
|
12
|
+
* runtime config seals except what only the service and its image supply: environment, working
|
|
13
|
+
* directory and target ports. A readiness probe names a target port, which the runtime config then
|
|
14
|
+
* requires the service to declare.
|
|
15
|
+
*/
|
|
16
|
+
export interface IServiceRuntimeProfile {
|
|
17
|
+
/** null explicitly requests no CPU quota. */
|
|
18
|
+
cpuMillis: number | null;
|
|
19
|
+
memoryBytes: number;
|
|
20
|
+
readiness: TRuntimeConfigReadiness;
|
|
21
|
+
logs: IRuntimeConfigLogPolicy;
|
|
22
|
+
readonlyRootfs: boolean;
|
|
23
|
+
/** null runs the image's own OCI user, exactly as a runtime config's null identity pair does. */
|
|
24
|
+
runAs: {
|
|
25
|
+
user: number;
|
|
26
|
+
group: number;
|
|
27
|
+
} | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* `isolated` gives the workload no network authority. `attached` joins the runtime network with
|
|
31
|
+
* public egress on or off and the platform endpoints it may reach, by id: sorted and unique.
|
|
32
|
+
*/
|
|
33
|
+
export type TServiceRuntimeNetwork = {
|
|
34
|
+
mode: 'isolated';
|
|
35
|
+
} | {
|
|
36
|
+
mode: 'attached';
|
|
37
|
+
publicEgress: boolean;
|
|
38
|
+
platformEndpointIds: string[];
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* What Cloudly runs for one service on a Pallet cluster. Stored complete, never defaulted at read
|
|
42
|
+
* time, and beside the service document rather than inside it, so a hold written by a cutover
|
|
43
|
+
* never races an operator's service edit.
|
|
44
|
+
*/
|
|
45
|
+
export interface IServiceRuntimeSpec {
|
|
46
|
+
/** The service id. */
|
|
47
|
+
id: string;
|
|
48
|
+
/** The service's organization, copied by Cloudly; never caller-chosen. */
|
|
49
|
+
organizationId: string;
|
|
50
|
+
clusterId: string;
|
|
51
|
+
placement: TServiceRuntimePlacement;
|
|
52
|
+
replicasPerNode: number;
|
|
53
|
+
/** While true, the service runs nowhere and every slot keeps its storage. */
|
|
54
|
+
hold: boolean;
|
|
55
|
+
profile: IServiceRuntimeProfile;
|
|
56
|
+
network: TServiceRuntimeNetwork;
|
|
57
|
+
/** Compare-and-swap counter; every write advances it by one. */
|
|
58
|
+
revision: number;
|
|
59
|
+
}
|
|
60
|
+
/** What an administrator writes; Cloudly supplies the service id, organization and revision. */
|
|
61
|
+
export type TServiceRuntimeSpecWritableData = Omit<IServiceRuntimeSpec, 'id' | 'organizationId' | 'revision'>;
|
|
62
|
+
export declare const serviceRuntimeContract: Readonly<{
|
|
63
|
+
readonly maximumReplicasPerNode: 64;
|
|
64
|
+
/** A service whose placement desires more replicas than this is refused as `replica-limit`. */
|
|
65
|
+
readonly maximumReplicas: 64;
|
|
66
|
+
/** A node can run workloads only as an egress member of the protected authority, which admits at most this many. */
|
|
67
|
+
readonly maximumPinnedNodes: 256;
|
|
68
|
+
readonly maximumPlatformEndpoints: 64;
|
|
69
|
+
/** The largest `limit` `getClusterRuntimeAssignments` accepts; Cloudly refuses a larger one. */
|
|
70
|
+
readonly maximumAssignmentPageSize: 256;
|
|
71
|
+
}>;
|
|
72
|
+
declare const serviceRuntimeWaitingReasons: readonly ["node-network-pending", "conflict", "failure-backoff"];
|
|
73
|
+
declare const serviceRuntimeRefusals: readonly ["cluster-runtime-missing", "organization-missing", "image-plan-missing", "platform-unsupported", "secrets-unsupported", "volumes-unsupported", "port-protocol-unsupported", "readiness-target-undeclared", "environment-too-large", "no-eligible-node", "replica-limit"];
|
|
74
|
+
/**
|
|
75
|
+
* Why the producer is not converging yet, though nothing needs an administrator:
|
|
76
|
+
* `node-network-pending` waits for a node's network readiness, `conflict` for a sweep over inputs
|
|
77
|
+
* that changed while it ran, `failure-backoff` for a failed replica's backoff to elapse.
|
|
78
|
+
*/
|
|
79
|
+
export type TServiceRuntimeWaitingReason = typeof serviceRuntimeWaitingReasons[number];
|
|
80
|
+
/** Why the producer admits nothing for this spec revision. A refusal never retires running slots. */
|
|
81
|
+
export type TServiceRuntimeRefusal = typeof serviceRuntimeRefusals[number];
|
|
82
|
+
interface IServiceRuntimeStatusBase {
|
|
83
|
+
/** The service id. */
|
|
84
|
+
id: string;
|
|
85
|
+
/** The spec revision this verdict is about. */
|
|
86
|
+
specRevision: number;
|
|
87
|
+
/** Unix milliseconds on Cloudly's clock. Written only when the verdict changes. */
|
|
88
|
+
changedAt: number;
|
|
89
|
+
}
|
|
90
|
+
/** The producer's verdict on one spec revision. */
|
|
91
|
+
export type IServiceRuntimeStatus = IServiceRuntimeStatusBase & ({
|
|
92
|
+
state: 'converged' | 'converging';
|
|
93
|
+
reason: null;
|
|
94
|
+
} | {
|
|
95
|
+
state: 'waiting';
|
|
96
|
+
reason: TServiceRuntimeWaitingReason;
|
|
97
|
+
} | {
|
|
98
|
+
state: 'refused';
|
|
99
|
+
reason: TServiceRuntimeRefusal;
|
|
100
|
+
});
|
|
101
|
+
/**
|
|
102
|
+
* `delivered` once the node's own evidence, an observation or a terminal receipt, cites this exact
|
|
103
|
+
* revision; `undelivered` until then. Cloudly keeps no acknowledgement journal, so a revision the
|
|
104
|
+
* node admitted but has not yet reported on reads as undelivered.
|
|
105
|
+
*/
|
|
106
|
+
export type TServiceRuntimeAssignmentDelivery = 'undelivered' | 'delivered';
|
|
107
|
+
/** One replica slot's current assignment, as an administrator reads it. */
|
|
108
|
+
export interface IServiceRuntimeAssignmentView {
|
|
109
|
+
serviceId: string;
|
|
110
|
+
replicaId: string;
|
|
111
|
+
nodeId: string;
|
|
112
|
+
/** The current revision; its generation is the one the disposition belongs to. */
|
|
113
|
+
assignment: IRuntimeAssignmentReference;
|
|
114
|
+
disposition: TRuntimeAssignmentDisposition;
|
|
115
|
+
/** The latest accepted observation of this attempt, which may cite an earlier revision. */
|
|
116
|
+
observation: Pick<IRuntimeAssignmentObservation, 'phase' | 'ready' | 'observedAt' | 'sequence'> | null;
|
|
117
|
+
/** Joined stop and remove receipts of this attempt. */
|
|
118
|
+
terminalReceiptCount: 0 | 1 | 2;
|
|
119
|
+
delivery: TServiceRuntimeAssignmentDelivery;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Structural snapshot for exact persistence and for a spec write. Whether the cluster, the nodes and
|
|
123
|
+
* the platform endpoints exist, and whether the service declares the readiness target, is Cloudly's.
|
|
124
|
+
*/
|
|
125
|
+
export declare const snapshotServiceRuntimeSpec: (value: unknown) => IServiceRuntimeSpec;
|
|
126
|
+
/** Structural snapshot for exact persistence: a reason belongs to exactly one state. */
|
|
127
|
+
export declare const snapshotServiceRuntimeStatus: (value: unknown) => IServiceRuntimeStatus;
|
|
128
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { runtimeNetworkAuthorityContract } from './networkauthority.js';
|
|
2
|
+
import { captureNetwork, networkCanonical, networkCounter, networkId, networkList, networkRecord, networkSorted, requireNetwork } from '../private/networkcontract.js';
|
|
3
|
+
import { failProducer, isOneOf, producerSafe, variantOf } from '../private/producercontract.js';
|
|
4
|
+
import { assertRuntimeReadiness, isBoundedInteger, isRuntimeCpuMillis, isRuntimeIdentityNumber, isRuntimeLogPolicy, isRuntimeMemoryBytes } from '../private/runtimepolicy.js';
|
|
5
|
+
export const serviceRuntimeContract = Object.freeze({
|
|
6
|
+
maximumReplicasPerNode: 64,
|
|
7
|
+
/** A service whose placement desires more replicas than this is refused as `replica-limit`. */
|
|
8
|
+
maximumReplicas: 64,
|
|
9
|
+
/** A node can run workloads only as an egress member of the protected authority, which admits at most this many. */
|
|
10
|
+
maximumPinnedNodes: runtimeNetworkAuthorityContract.maximumEgressAuthorities,
|
|
11
|
+
maximumPlatformEndpoints: runtimeNetworkAuthorityContract.maximumPlatformEndpoints,
|
|
12
|
+
/** The largest `limit` `getClusterRuntimeAssignments` accepts; Cloudly refuses a larger one. */
|
|
13
|
+
maximumAssignmentPageSize: 256,
|
|
14
|
+
});
|
|
15
|
+
const serviceRuntimeWaitingReasons = ['node-network-pending', 'conflict', 'failure-backoff'];
|
|
16
|
+
const serviceRuntimeRefusals = [
|
|
17
|
+
'cluster-runtime-missing', 'organization-missing', 'image-plan-missing', 'platform-unsupported',
|
|
18
|
+
'secrets-unsupported', 'volumes-unsupported', 'port-protocol-unsupported', 'readiness-target-undeclared',
|
|
19
|
+
'environment-too-large', 'no-eligible-node', 'replica-limit',
|
|
20
|
+
];
|
|
21
|
+
const sortedIds = (value, maximum) => networkSorted(networkList(value, maximum, networkId), id => id);
|
|
22
|
+
const placementOf = (value) => {
|
|
23
|
+
const kind = variantOf(value, 'kind');
|
|
24
|
+
if (kind === 'every-node') {
|
|
25
|
+
networkRecord(value, ['kind']);
|
|
26
|
+
return { kind };
|
|
27
|
+
}
|
|
28
|
+
requireNetwork(kind === 'nodes');
|
|
29
|
+
const nodeIds = sortedIds(networkRecord(value, ['kind', 'nodeIds']).nodeIds, serviceRuntimeContract.maximumPinnedNodes);
|
|
30
|
+
requireNetwork(nodeIds.length > 0);
|
|
31
|
+
return { kind, nodeIds };
|
|
32
|
+
};
|
|
33
|
+
const runAsOf = (value) => {
|
|
34
|
+
if (value === null)
|
|
35
|
+
return null;
|
|
36
|
+
const item = networkRecord(value, ['user', 'group']);
|
|
37
|
+
requireNetwork(isRuntimeIdentityNumber(item.user) && isRuntimeIdentityNumber(item.group));
|
|
38
|
+
return { user: item.user, group: item.group };
|
|
39
|
+
};
|
|
40
|
+
const profileOf = (value) => {
|
|
41
|
+
const item = networkRecord(value, ['cpuMillis', 'memoryBytes', 'readiness', 'logs', 'readonlyRootfs', 'runAs']);
|
|
42
|
+
requireNetwork(isRuntimeCpuMillis(item.cpuMillis) && isRuntimeMemoryBytes(item.memoryBytes)
|
|
43
|
+
&& isRuntimeLogPolicy(item.logs) && typeof item.readonlyRootfs === 'boolean');
|
|
44
|
+
// The profile precedes the service's target ports; the runtime config refuses a target they do not declare.
|
|
45
|
+
assertRuntimeReadiness(item.readiness, () => true, failProducer);
|
|
46
|
+
const { maximumLineBytes, maximumBufferedBytes, retentionMs } = item.logs;
|
|
47
|
+
return { cpuMillis: item.cpuMillis, memoryBytes: item.memoryBytes,
|
|
48
|
+
readiness: JSON.parse(networkCanonical(item.readiness)),
|
|
49
|
+
logs: { maximumLineBytes, maximumBufferedBytes, retentionMs }, readonlyRootfs: item.readonlyRootfs, runAs: runAsOf(item.runAs) };
|
|
50
|
+
};
|
|
51
|
+
const networkOf = (value) => {
|
|
52
|
+
const mode = variantOf(value, 'mode');
|
|
53
|
+
if (mode === 'isolated') {
|
|
54
|
+
networkRecord(value, ['mode']);
|
|
55
|
+
return { mode };
|
|
56
|
+
}
|
|
57
|
+
requireNetwork(mode === 'attached');
|
|
58
|
+
const item = networkRecord(value, ['mode', 'publicEgress', 'platformEndpointIds']);
|
|
59
|
+
requireNetwork(typeof item.publicEgress === 'boolean');
|
|
60
|
+
return { mode, publicEgress: item.publicEgress,
|
|
61
|
+
platformEndpointIds: sortedIds(item.platformEndpointIds, serviceRuntimeContract.maximumPlatformEndpoints) };
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Structural snapshot for exact persistence and for a spec write. Whether the cluster, the nodes and
|
|
65
|
+
* the platform endpoints exist, and whether the service declares the readiness target, is Cloudly's.
|
|
66
|
+
*/
|
|
67
|
+
export const snapshotServiceRuntimeSpec = (value) => producerSafe(() => {
|
|
68
|
+
const item = networkRecord(captureNetwork(value), ['id', 'organizationId', 'clusterId', 'placement',
|
|
69
|
+
'replicasPerNode', 'hold', 'profile', 'network', 'revision']);
|
|
70
|
+
requireNetwork(isBoundedInteger(item.replicasPerNode, 1, serviceRuntimeContract.maximumReplicasPerNode)
|
|
71
|
+
&& typeof item.hold === 'boolean');
|
|
72
|
+
return { id: networkId(item.id), organizationId: networkId(item.organizationId), clusterId: networkId(item.clusterId),
|
|
73
|
+
placement: placementOf(item.placement), replicasPerNode: item.replicasPerNode, hold: item.hold,
|
|
74
|
+
profile: profileOf(item.profile), network: networkOf(item.network), revision: networkCounter(item.revision) };
|
|
75
|
+
});
|
|
76
|
+
/** Structural snapshot for exact persistence: a reason belongs to exactly one state. */
|
|
77
|
+
export const snapshotServiceRuntimeStatus = (value) => producerSafe(() => {
|
|
78
|
+
const item = networkRecord(captureNetwork(value), ['id', 'specRevision', 'state', 'reason', 'changedAt']);
|
|
79
|
+
const base = { id: networkId(item.id), specRevision: networkCounter(item.specRevision),
|
|
80
|
+
changedAt: networkCounter(item.changedAt) };
|
|
81
|
+
if (item.state === 'converged' || item.state === 'converging') {
|
|
82
|
+
requireNetwork(item.reason === null);
|
|
83
|
+
return { ...base, state: item.state, reason: null };
|
|
84
|
+
}
|
|
85
|
+
if (item.state === 'waiting') {
|
|
86
|
+
requireNetwork(isOneOf(serviceRuntimeWaitingReasons, item.reason));
|
|
87
|
+
return { ...base, state: item.state, reason: item.reason };
|
|
88
|
+
}
|
|
89
|
+
requireNetwork(item.state === 'refused' && isOneOf(serviceRuntimeRefusals, item.reason));
|
|
90
|
+
return { ...base, state: item.state, reason: item.reason };
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZXJ1bnRpbWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL3NlcnZpY2VydW50aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlBLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFDN0csY0FBYyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxnQkFBZ0IsRUFBRSxrQkFBa0IsRUFBRSx1QkFBdUIsRUFBRSxrQkFBa0IsRUFDaEgsb0JBQW9CLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQXdENUQsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNsRCxzQkFBc0IsRUFBRSxFQUFFO0lBQzFCLCtGQUErRjtJQUMvRixlQUFlLEVBQUUsRUFBRTtJQUNuQixvSEFBb0g7SUFDcEgsa0JBQWtCLEVBQUUsK0JBQStCLENBQUMsd0JBQXdCO0lBQzVFLHdCQUF3QixFQUFFLCtCQUErQixDQUFDLHdCQUF3QjtJQUNsRixnR0FBZ0c7SUFDaEcseUJBQXlCLEVBQUUsR0FBRztDQUN0QixDQUFDLENBQUM7QUFFWixNQUFNLDRCQUE0QixHQUFHLENBQUMsc0JBQXNCLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixDQUFVLENBQUM7QUFDdEcsTUFBTSxzQkFBc0IsR0FBRztJQUM3Qix5QkFBeUIsRUFBRSxzQkFBc0IsRUFBRSxvQkFBb0IsRUFBRSxzQkFBc0I7SUFDL0YscUJBQXFCLEVBQUUscUJBQXFCLEVBQUUsMkJBQTJCLEVBQUUsNkJBQTZC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QUksQ0FBQyxLQUFLLEtBQUssV0FBVyxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssWUFBWSxFQUFFLENBQUM7UUFDOUQsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLENBQUM7UUFDckMsT0FBTyxFQUFFLEdBQUcsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUN0RCxDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzdCLGNBQWMsQ0FBQyxPQUFPLENBQUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDbkUsT0FBTyxFQUFFLEdBQUcsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDN0QsQ0FBQztJQUNELGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxLQUFLLFNBQVMsSUFBSSxPQUFPLENBQUMsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDekYsT0FBTyxFQUFFLEdBQUcsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDN0QsQ0FBQyxDQUFDLENBQUMifQ==
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { type IProtocolOffer } from '../protocol.js';
|
|
1
2
|
/** Host observations only. Container and workload readiness belong to Pallet. */
|
|
2
|
-
export interface
|
|
3
|
-
schemaVersion: 2;
|
|
3
|
+
export interface ISparkNodeReport {
|
|
4
4
|
observedAt: number;
|
|
5
5
|
metrics: {
|
|
6
6
|
cpuUsagePercent: number;
|
|
@@ -24,31 +24,44 @@ export interface ISparkNodeReportV2 {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
/** HTTPS POST body. Never log, persist, or return nodeToken. */
|
|
27
|
-
export interface
|
|
27
|
+
export interface ISparkNodeHeartbeatRequest {
|
|
28
28
|
nodeId: string;
|
|
29
29
|
nodeToken: string;
|
|
30
|
-
|
|
30
|
+
/** Read and negotiated before the node is authenticated; see `sparkNodeHeartbeatContract`. */
|
|
31
|
+
protocol: IProtocolOffer;
|
|
32
|
+
report: ISparkNodeReport;
|
|
31
33
|
}
|
|
32
34
|
/** Historical acceptance evidence, not current authority or workload readiness. */
|
|
33
|
-
export interface
|
|
34
|
-
schemaVersion: 2;
|
|
35
|
+
export interface ISparkNodeHeartbeatReceipt {
|
|
35
36
|
accepted: true;
|
|
36
37
|
nodeId: string;
|
|
37
38
|
credentialGeneration: number;
|
|
38
39
|
sessionEpoch: number;
|
|
39
40
|
acceptedAt: number;
|
|
41
|
+
/** The controller's offer, so an accepted node judges the session it just reported into. */
|
|
42
|
+
protocol: IProtocolOffer;
|
|
40
43
|
}
|
|
41
44
|
/** Persist only after the server's current Spark credential transaction commits. */
|
|
42
|
-
export interface
|
|
43
|
-
report:
|
|
44
|
-
receipt:
|
|
45
|
+
export interface ISparkNodeReportRecord {
|
|
46
|
+
report: ISparkNodeReport;
|
|
47
|
+
receipt: ISparkNodeHeartbeatReceipt;
|
|
45
48
|
}
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
/**
|
|
50
|
+
* The node runtime's own heartbeat route.
|
|
51
|
+
*
|
|
52
|
+
* Judged in the one server order `protocol.readProtocolOffer` states, against this server's
|
|
53
|
+
* `sparkNode` offer and within `maxRequestBytes`. The route carries no typed error, so a refusal
|
|
54
|
+
* is answered with `protocolRefusalStatus` and an `IProtocolRefusal` body — before the report is
|
|
55
|
+
* snapshotted and before the node is authenticated, because a route that authenticated first would
|
|
56
|
+
* answer a peer of another major with a credential verdict it cannot act on.
|
|
57
|
+
*/
|
|
58
|
+
export declare const sparkNodeHeartbeatContract: Readonly<{
|
|
59
|
+
readonly endpoint: "/spark/nodes/heartbeat";
|
|
48
60
|
readonly maxRequestBytes: 8192;
|
|
49
61
|
readonly maxResponseBytes: 2048;
|
|
62
|
+
readonly protocolRefusalStatus: 422;
|
|
50
63
|
}>;
|
|
51
64
|
/** Exact inert JSON records; detaches and freezes before any consumer awaits. */
|
|
52
|
-
export declare const
|
|
53
|
-
export declare const
|
|
54
|
-
export declare const
|
|
65
|
+
export declare const snapshotSparkNodeReport: (valueArg: unknown) => ISparkNodeReport;
|
|
66
|
+
export declare const snapshotSparkNodeHeartbeatRequest: (valueArg: unknown) => ISparkNodeHeartbeatRequest;
|
|
67
|
+
export declare const snapshotSparkNodeHeartbeatReceipt: (valueArg: unknown) => ISparkNodeHeartbeatReceipt;
|
|
@@ -1,26 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { isReleaseVersion } from '../private/releaseversion.js';
|
|
2
|
+
import { readExactDataRecord } from '../private/dataproperties.js';
|
|
3
|
+
import { protocolRefusalHttpStatus, readProtocolOffer } from '../protocol.js';
|
|
4
|
+
/**
|
|
5
|
+
* The node runtime's own heartbeat route.
|
|
6
|
+
*
|
|
7
|
+
* Judged in the one server order `protocol.readProtocolOffer` states, against this server's
|
|
8
|
+
* `sparkNode` offer and within `maxRequestBytes`. The route carries no typed error, so a refusal
|
|
9
|
+
* is answered with `protocolRefusalStatus` and an `IProtocolRefusal` body — before the report is
|
|
10
|
+
* snapshotted and before the node is authenticated, because a route that authenticated first would
|
|
11
|
+
* answer a peer of another major with a credential verdict it cannot act on.
|
|
12
|
+
*/
|
|
13
|
+
export const sparkNodeHeartbeatContract = Object.freeze({
|
|
14
|
+
endpoint: '/spark/nodes/heartbeat',
|
|
3
15
|
maxRequestBytes: 8192,
|
|
4
16
|
maxResponseBytes: 2048,
|
|
17
|
+
protocolRefusalStatus: protocolRefusalHttpStatus,
|
|
5
18
|
});
|
|
6
19
|
const fail = () => { throw new Error('Spark node heartbeat contract rejected.'); };
|
|
7
20
|
function requireValue(valueArg) {
|
|
8
21
|
if (!valueArg)
|
|
9
22
|
fail();
|
|
10
23
|
}
|
|
24
|
+
/** Exactly these keys, carrying data: the shared reader refuses an accessor instead of running it. */
|
|
11
25
|
const record = (valueArg, keysArg) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
requireValue(prototype === Object.prototype || prototype === null);
|
|
15
|
-
const keys = Reflect.ownKeys(valueArg);
|
|
16
|
-
requireValue(keys.length === keysArg.length);
|
|
17
|
-
const result = Object.create(null);
|
|
18
|
-
for (const key of keys) {
|
|
19
|
-
requireValue(typeof key === 'string' && keysArg.includes(key));
|
|
20
|
-
const descriptor = Object.getOwnPropertyDescriptor(valueArg, key);
|
|
21
|
-
requireValue(descriptor?.enumerable && Object.hasOwn(descriptor, 'value'));
|
|
22
|
-
result[key] = descriptor.value;
|
|
23
|
-
}
|
|
26
|
+
const result = readExactDataRecord(valueArg, keysArg);
|
|
27
|
+
requireValue(result !== null);
|
|
24
28
|
return result;
|
|
25
29
|
};
|
|
26
30
|
const text = (valueArg, patternArg, maxLengthArg) => {
|
|
@@ -28,6 +32,9 @@ const text = (valueArg, patternArg, maxLengthArg) => {
|
|
|
28
32
|
&& valueArg.match(patternArg)?.[0] === valueArg);
|
|
29
33
|
return valueArg;
|
|
30
34
|
};
|
|
35
|
+
// The shared grammar, not a copy of it: a stored bundle version has to be one the release
|
|
36
|
+
// comparison can order, and a second rule here would be a second answer to that question.
|
|
37
|
+
const releaseVersion = (valueArg) => (isReleaseVersion(valueArg) ? valueArg : fail());
|
|
31
38
|
const number = (valueArg, maxArg = Number.MAX_SAFE_INTEGER) => {
|
|
32
39
|
requireValue(typeof valueArg === 'number' && Number.isFinite(valueArg)
|
|
33
40
|
&& !Object.is(valueArg, -0) && valueArg >= 0 && valueArg <= maxArg);
|
|
@@ -39,9 +46,8 @@ const integer = (valueArg, minimumArg) => {
|
|
|
39
46
|
return value;
|
|
40
47
|
};
|
|
41
48
|
/** Exact inert JSON records; detaches and freezes before any consumer awaits. */
|
|
42
|
-
export const
|
|
43
|
-
const value = record(valueArg, ['
|
|
44
|
-
requireValue(value.schemaVersion === 2);
|
|
49
|
+
export const snapshotSparkNodeReport = (valueArg) => {
|
|
50
|
+
const value = record(valueArg, ['observedAt', 'metrics', 'runtime']);
|
|
45
51
|
const metrics = record(value.metrics, ['cpuUsagePercent', 'memoryUsedMB', 'memoryAvailableMB',
|
|
46
52
|
'diskUsedGB', 'diskAvailableGB']);
|
|
47
53
|
const runtime = record(value.runtime, ['hostname', 'platform', 'arch', 'osRelease', 'bundle',
|
|
@@ -52,7 +58,6 @@ export const snapshotSparkNodeReportV2 = (valueArg) => {
|
|
|
52
58
|
requireValue(hostname.split('.').every((label) => /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(label)));
|
|
53
59
|
const bundle = record(runtime.bundle, ['version', 'sourceCommit', 'manifestSha256']);
|
|
54
60
|
return Object.freeze({
|
|
55
|
-
schemaVersion: 2,
|
|
56
61
|
observedAt: integer(value.observedAt, 1),
|
|
57
62
|
metrics: Object.freeze({
|
|
58
63
|
cpuUsagePercent: number(metrics.cpuUsagePercent, 100),
|
|
@@ -63,7 +68,7 @@ export const snapshotSparkNodeReportV2 = (valueArg) => {
|
|
|
63
68
|
hostname, platform: 'linux', arch: runtime.arch,
|
|
64
69
|
osRelease: text(runtime.osRelease, /^[\x20-\x7e]+$/, 256),
|
|
65
70
|
bundle: Object.freeze({
|
|
66
|
-
version:
|
|
71
|
+
version: releaseVersion(bundle.version),
|
|
67
72
|
sourceCommit: text(bundle.sourceCommit, /^[a-f0-9]{40}$/, 40),
|
|
68
73
|
manifestSha256: text(bundle.manifestSha256, /^[a-f0-9]{64}$/, 64),
|
|
69
74
|
}),
|
|
@@ -71,23 +76,25 @@ export const snapshotSparkNodeReportV2 = (valueArg) => {
|
|
|
71
76
|
}),
|
|
72
77
|
});
|
|
73
78
|
};
|
|
74
|
-
export const
|
|
75
|
-
const value = record(valueArg, ['nodeId', 'nodeToken', 'report']);
|
|
79
|
+
export const snapshotSparkNodeHeartbeatRequest = (valueArg) => {
|
|
80
|
+
const value = record(valueArg, ['nodeId', 'nodeToken', 'protocol', 'report']);
|
|
76
81
|
return Object.freeze({
|
|
77
82
|
nodeId: text(value.nodeId, /^[A-Za-z0-9_-]+$/, 128),
|
|
78
83
|
// Both freshly enrolled and explicitly adopted credentials use this bearer format.
|
|
79
84
|
nodeToken: text(value.nodeToken, /^secureToken[a-f0-9]{64}$/, 75),
|
|
80
|
-
|
|
85
|
+
protocol: readProtocolOffer(value),
|
|
86
|
+
report: snapshotSparkNodeReport(value.report),
|
|
81
87
|
});
|
|
82
88
|
};
|
|
83
|
-
export const
|
|
84
|
-
const value = record(valueArg, ['
|
|
85
|
-
'sessionEpoch', 'acceptedAt']);
|
|
86
|
-
requireValue(value.
|
|
89
|
+
export const snapshotSparkNodeHeartbeatReceipt = (valueArg) => {
|
|
90
|
+
const value = record(valueArg, ['accepted', 'nodeId', 'credentialGeneration',
|
|
91
|
+
'sessionEpoch', 'acceptedAt', 'protocol']);
|
|
92
|
+
requireValue(value.accepted === true);
|
|
87
93
|
return Object.freeze({
|
|
88
|
-
|
|
94
|
+
accepted: true, nodeId: text(value.nodeId, /^[A-Za-z0-9_-]+$/, 128),
|
|
89
95
|
credentialGeneration: integer(value.credentialGeneration, 1),
|
|
90
96
|
sessionEpoch: integer(value.sessionEpoch, 0), acceptedAt: integer(value.acceptedAt, 1),
|
|
97
|
+
protocol: readProtocolOffer(value),
|
|
91
98
|
});
|
|
92
99
|
};
|
|
93
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
100
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bhcmtub2RlcmVwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvZGF0YS9zcGFya25vZGVyZXBvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDaEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbkUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLGlCQUFpQixFQUF1QixNQUFNLGdCQUFnQixDQUFDO0FBaURuRzs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDdEQsUUFBUSxFQUFFLHdCQUF3QjtJQUNsQyxlQUFlLEVBQUUsSUFBSTtJQUNyQixnQkFBZ0IsRUFBRSxJQUFJO0lBQ3RCLHFCQUFxQixFQUFFLHlCQUF5QjtDQUN4QyxDQUFDLENBQUM7QUFFWixNQUFNLElBQUksR0FBRyxHQUFVLEVBQUUsR0FBRyxNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUYsU0FBUyxZQUFZLENBQUMsUUFBaUI7SUFDckMsSUFBSSxDQUFDLFFBQVE7UUFBRSxJQUFJLEVBQUUsQ0FBQztBQUN4QixDQUFDO0FBQ0Qsc0dBQXNHO0FBQ3RHLE1BQU0sTUFBTSxHQUFHLENBQUMsUUFBaUIsRUFBRSxPQUEwQixFQUEyQixFQUFFO0lBQ3hGLE1BQU0sTUFBTSxHQUFHLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN0RCxZQUFZLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxDQUFDO0lBQzlCLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMsQ0FBQztBQUNGLE1BQU0sSUFBSSxHQUFHLENBQUMsUUFBaUIsRUFBRSxVQUFrQixFQUFFLFlBQW9CLEVBQVUsRUFBRTtJQUNuRixZQUFZLENBQUMs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
|
|
@@ -78,7 +78,6 @@ export interface IWebPushBinding {
|
|
|
78
78
|
* from their authenticated API after receiving this event.
|
|
79
79
|
*/
|
|
80
80
|
export interface IWebPushNotificationPayload {
|
|
81
|
-
schemaVersion: 1;
|
|
82
81
|
event: 'notificationAvailable';
|
|
83
82
|
eventId: string;
|
|
84
83
|
/** Same-origin application route beginning with a single slash. */
|
package/dist_ts/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ import * as data from './data/index.js';
|
|
|
2
2
|
import * as appstore from './appstore/index.js';
|
|
3
3
|
import * as platform from './platform/index.js';
|
|
4
4
|
import * as platformservice from './platformservice/index.js';
|
|
5
|
+
import * as protocol from './protocol.js';
|
|
5
6
|
import * as requests from './requests/index.js';
|
|
6
|
-
export { appstore, data, platform, platformservice, requests };
|
|
7
|
+
export { appstore, data, platform, platformservice, protocol, requests };
|
package/dist_ts/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as data from './data/index.js';
|
|
|
2
2
|
import * as appstore from './appstore/index.js';
|
|
3
3
|
import * as platform from './platform/index.js';
|
|
4
4
|
import * as platformservice from './platformservice/index.js';
|
|
5
|
+
import * as protocol from './protocol.js';
|
|
5
6
|
import * as requests from './requests/index.js';
|
|
6
|
-
export { appstore, data, platform, platformservice, requests };
|
|
7
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
7
|
+
export { appstore, data, platform, platformservice, protocol, requests };
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssSUFBSSxNQUFNLGlCQUFpQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxRQUFRLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxLQUFLLFFBQVEsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEtBQUssZUFBZSxNQUFNLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sS0FBSyxRQUFRLE1BQU0sZUFBZSxDQUFDO0FBQzFDLE9BQU8sS0FBSyxRQUFRLE1BQU0scUJBQXFCLENBQUM7QUFFaEQsT0FBTyxFQUNMLFFBQVEsRUFDUixJQUFJLEVBQ0osUUFBUSxFQUNSLGVBQWUsRUFDZixRQUFRLEVBQ1IsUUFBUSxFQUNULENBQUEifQ==
|