@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,7 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readDataElements, readDataProperty, readExactDataRecord,
|
|
3
|
+
} from '../private/dataproperties.js';
|
|
1
4
|
import { isPlausibleUnicastIpv4 } from '../private/ipv4.js';
|
|
2
5
|
|
|
3
6
|
/** Cloudly owns these definitions. Membership never follows node placement. */
|
|
4
|
-
export interface
|
|
7
|
+
export interface IPrivateNetworkPolicy {
|
|
5
8
|
connectivity: 'member-full-mesh';
|
|
6
9
|
/** null denies external resolution; private names are never forwarded. */
|
|
7
10
|
externalDns: {
|
|
@@ -12,8 +15,7 @@ export interface IPrivateNetworkPolicyV1 {
|
|
|
12
15
|
} | null;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
export interface
|
|
16
|
-
schemaVersion: 1;
|
|
18
|
+
export interface IPrivateNetwork {
|
|
17
19
|
id: string;
|
|
18
20
|
organizationId: string;
|
|
19
21
|
/** Immutable server-owned keys; display-name changes do not rename DNS. */
|
|
@@ -22,52 +24,50 @@ export interface IPrivateNetworkV1 {
|
|
|
22
24
|
name: string;
|
|
23
25
|
revision: number;
|
|
24
26
|
state: 'active' | 'retiring' | 'retired';
|
|
25
|
-
policy:
|
|
27
|
+
policy: IPrivateNetworkPolicy;
|
|
26
28
|
createdAt: number;
|
|
27
29
|
updatedAt: number;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
export interface
|
|
32
|
+
export interface IPrivateNetworkAttachment {
|
|
31
33
|
networkId: string;
|
|
32
34
|
/** Sorted unique single-label aliases, reserved per network for this service. */
|
|
33
35
|
aliases: string[];
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
/** Desired membership only. Acceptance is neither packet enforcement nor DNS readiness. */
|
|
37
|
-
export interface
|
|
38
|
-
schemaVersion: 1;
|
|
39
|
+
export interface IServicePrivateNetworks {
|
|
39
40
|
organizationId: string;
|
|
40
41
|
serviceId: string;
|
|
41
42
|
revision: number;
|
|
42
43
|
/** Sorted by networkId; every network must have the same canonical organization. */
|
|
43
|
-
attachments:
|
|
44
|
+
attachments: IPrivateNetworkAttachment[];
|
|
44
45
|
/** Exactly the sole attachment, or explicit selection/null when several exist. */
|
|
45
46
|
defaultNetworkId: string | null;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
interface
|
|
49
|
-
schemaVersion: 1;
|
|
49
|
+
interface IPrivateNetworkMutationBase {
|
|
50
50
|
organizationId: string;
|
|
51
51
|
/** Retain the exact body and this identifier across retries. */
|
|
52
52
|
mutationId: string;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
export type
|
|
56
|
-
| { operation: 'create'; expectedRevision: null; name: string; policy:
|
|
57
|
-
| { operation: 'update'; networkId: string; expectedRevision: number; name: string; policy:
|
|
55
|
+
export type TPrivateNetworkMutation = IPrivateNetworkMutationBase & (
|
|
56
|
+
| { operation: 'create'; expectedRevision: null; name: string; policy: IPrivateNetworkPolicy }
|
|
57
|
+
| { operation: 'update'; networkId: string; expectedRevision: number; name: string; policy: IPrivateNetworkPolicy }
|
|
58
58
|
/** Retirement completes only after outstanding grants are denied or independently fenced. */
|
|
59
59
|
| { operation: 'retire'; networkId: string; expectedRevision: number }
|
|
60
60
|
);
|
|
61
61
|
|
|
62
|
-
export interface
|
|
62
|
+
export interface ISetServicePrivateNetworks extends IPrivateNetworkMutationBase {
|
|
63
63
|
serviceId: string;
|
|
64
64
|
/** null means the service has never had a membership document; not an empty list. */
|
|
65
65
|
expectedRevision: number | null;
|
|
66
|
-
attachments:
|
|
66
|
+
attachments: IPrivateNetworkAttachment[];
|
|
67
67
|
defaultNetworkId: string | null;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
export const
|
|
70
|
+
export const privateNetworkContract = Object.freeze({
|
|
71
71
|
privateRoot: 'internal.',
|
|
72
72
|
maximumAttachments: 16,
|
|
73
73
|
maximumAliasesPerAttachment: 32,
|
|
@@ -83,29 +83,17 @@ export const privateNetworkV1Contract = Object.freeze({
|
|
|
83
83
|
const fail = (): never => { throw new Error('Private network contract rejected.'); };
|
|
84
84
|
function requireValue(value: unknown): asserts value { if (!value) fail(); }
|
|
85
85
|
const safe = <T>(operation: () => T): T => { try { return operation(); } catch { return fail(); } };
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
requireValue(actual.length === keys.length && keys.every(key => actual.includes(key)));
|
|
91
|
-
const result: Record<string, unknown> = Object.create(null);
|
|
92
|
-
for (const key of keys) {
|
|
93
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
94
|
-
requireValue(descriptor?.enumerable && Object.hasOwn(descriptor, 'value'));
|
|
95
|
-
result[key] = descriptor.value;
|
|
96
|
-
}
|
|
86
|
+
/** Exactly this shape's keys, read once as data; an accessor is refused, never invoked. */
|
|
87
|
+
const object = (value: unknown, keys: readonly string[]): Record<string, unknown> => {
|
|
88
|
+
const result = readExactDataRecord(value, keys);
|
|
89
|
+
requireValue(result !== null);
|
|
97
90
|
return result;
|
|
98
91
|
};
|
|
92
|
+
/** A bounded dense list, read the same way as a record, then read element by element. */
|
|
99
93
|
const array = <T>(value: unknown, maximum: number, read: (item: unknown) => T): T[] => {
|
|
100
|
-
|
|
101
|
-
requireValue(
|
|
102
|
-
|
|
103
|
-
for (let index = 0; index < value.length; index++) {
|
|
104
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
105
|
-
requireValue(descriptor?.enumerable && Object.hasOwn(descriptor, 'value'));
|
|
106
|
-
result.push(read(descriptor.value));
|
|
107
|
-
}
|
|
108
|
-
return result;
|
|
94
|
+
const elements = readDataElements(value, maximum);
|
|
95
|
+
requireValue(elements !== null);
|
|
96
|
+
return elements.map(read);
|
|
109
97
|
};
|
|
110
98
|
const identifier = (value: unknown): string => {
|
|
111
99
|
requireValue(typeof value === 'string' && /^[A-Za-z0-9][A-Za-z0-9:._-]{0,199}$/.test(value));
|
|
@@ -148,12 +136,12 @@ const publicSuffix = (value: unknown): string => {
|
|
|
148
136
|
};
|
|
149
137
|
|
|
150
138
|
/** Structural validation only; backend IP ownership/reachability and policy fences are required. */
|
|
151
|
-
export const
|
|
139
|
+
export const snapshotPrivateNetworkPolicy = (value: unknown): IPrivateNetworkPolicy => safe(() => {
|
|
152
140
|
const policy = object(value, ['connectivity', 'externalDns']);
|
|
153
141
|
requireValue(policy.connectivity === 'member-full-mesh');
|
|
154
142
|
if (policy.externalDns === null) return { connectivity: 'member-full-mesh', externalDns: null };
|
|
155
143
|
const external = object(policy.externalDns, ['upstreams', 'allowAnyPublicName', 'permittedSuffixes']);
|
|
156
|
-
const upstreams = array(external.upstreams,
|
|
144
|
+
const upstreams = array(external.upstreams, privateNetworkContract.maximumUpstreams, entry => {
|
|
157
145
|
const upstream = object(entry, ['address', 'port']);
|
|
158
146
|
const port = counter(upstream.port);
|
|
159
147
|
requireValue(port <= 65535);
|
|
@@ -161,18 +149,18 @@ export const snapshotPrivateNetworkPolicyV1 = (value: unknown): IPrivateNetworkP
|
|
|
161
149
|
});
|
|
162
150
|
requireValue(upstreams.length > 0 && new Set(upstreams.map(upstream => `${upstream.address}:${upstream.port}`)).size === upstreams.length);
|
|
163
151
|
requireValue(typeof external.allowAnyPublicName === 'boolean');
|
|
164
|
-
const permittedSuffixes = sorted(array(external.permittedSuffixes,
|
|
152
|
+
const permittedSuffixes = sorted(array(external.permittedSuffixes, privateNetworkContract.maximumPermittedSuffixes, publicSuffix));
|
|
165
153
|
requireValue(external.allowAnyPublicName ? permittedSuffixes.length === 0 : permittedSuffixes.length > 0);
|
|
166
154
|
return { connectivity: 'member-full-mesh', externalDns: {
|
|
167
155
|
upstreams, allowAnyPublicName: external.allowAnyPublicName, permittedSuffixes,
|
|
168
156
|
} };
|
|
169
157
|
});
|
|
170
158
|
|
|
171
|
-
const membership = (attachmentsValue: unknown, defaultValue: unknown): Pick<
|
|
172
|
-
const attachments = array(attachmentsValue,
|
|
159
|
+
const membership = (attachmentsValue: unknown, defaultValue: unknown): Pick<IServicePrivateNetworks, 'attachments' | 'defaultNetworkId'> => {
|
|
160
|
+
const attachments = array(attachmentsValue, privateNetworkContract.maximumAttachments, entry => {
|
|
173
161
|
const attachment = object(entry, ['networkId', 'aliases']);
|
|
174
162
|
return { networkId: identifier(attachment.networkId),
|
|
175
|
-
aliases: sorted(array(attachment.aliases,
|
|
163
|
+
aliases: sorted(array(attachment.aliases, privateNetworkContract.maximumAliasesPerAttachment, label)) };
|
|
176
164
|
});
|
|
177
165
|
sorted(attachments.map(attachment => attachment.networkId));
|
|
178
166
|
const defaultNetworkId = defaultValue === null ? null : identifier(defaultValue);
|
|
@@ -181,58 +169,54 @@ const membership = (attachmentsValue: unknown, defaultValue: unknown): Pick<ISer
|
|
|
181
169
|
return { attachments, defaultNetworkId };
|
|
182
170
|
};
|
|
183
171
|
|
|
184
|
-
export const
|
|
185
|
-
const network = object(value, ['
|
|
172
|
+
export const snapshotPrivateNetwork = (value: unknown): IPrivateNetwork => safe(() => {
|
|
173
|
+
const network = object(value, ['id', 'organizationId', 'organizationDnsKey', 'networkDnsKey',
|
|
186
174
|
'name', 'revision', 'state', 'policy', 'createdAt', 'updatedAt']);
|
|
187
|
-
requireValue(
|
|
175
|
+
requireValue(['active', 'retiring', 'retired'].includes(network.state as string));
|
|
188
176
|
const createdAt = counter(network.createdAt);
|
|
189
177
|
const updatedAt = counter(network.updatedAt);
|
|
190
178
|
requireValue(updatedAt >= createdAt);
|
|
191
|
-
return {
|
|
179
|
+
return { id: identifier(network.id), organizationId: identifier(network.organizationId),
|
|
192
180
|
organizationDnsKey: dnsKey(network.organizationDnsKey, 'o'), networkDnsKey: dnsKey(network.networkDnsKey, 'n'),
|
|
193
|
-
name: name(network.name), revision: counter(network.revision), state: network.state as
|
|
194
|
-
policy:
|
|
181
|
+
name: name(network.name), revision: counter(network.revision), state: network.state as IPrivateNetwork['state'],
|
|
182
|
+
policy: snapshotPrivateNetworkPolicy(network.policy), createdAt, updatedAt };
|
|
195
183
|
});
|
|
196
184
|
|
|
197
|
-
export const
|
|
198
|
-
const service = object(value, ['
|
|
199
|
-
|
|
200
|
-
return { schemaVersion: 1, organizationId: identifier(service.organizationId), serviceId: identifier(service.serviceId),
|
|
185
|
+
export const snapshotServicePrivateNetworks = (value: unknown): IServicePrivateNetworks => safe(() => {
|
|
186
|
+
const service = object(value, ['organizationId', 'serviceId', 'revision', 'attachments', 'defaultNetworkId']);
|
|
187
|
+
return { organizationId: identifier(service.organizationId), serviceId: identifier(service.serviceId),
|
|
201
188
|
revision: counter(service.revision), ...membership(service.attachments, service.defaultNetworkId) };
|
|
202
189
|
});
|
|
203
190
|
|
|
204
|
-
export const
|
|
205
|
-
const request = object(value, ['
|
|
206
|
-
|
|
207
|
-
return { schemaVersion: 1, organizationId: identifier(request.organizationId), serviceId: identifier(request.serviceId),
|
|
191
|
+
export const snapshotSetServicePrivateNetworks = (value: unknown): ISetServicePrivateNetworks => safe(() => {
|
|
192
|
+
const request = object(value, ['organizationId', 'serviceId', 'mutationId', 'expectedRevision', 'attachments', 'defaultNetworkId']);
|
|
193
|
+
return { organizationId: identifier(request.organizationId), serviceId: identifier(request.serviceId),
|
|
208
194
|
mutationId: identifier(request.mutationId), expectedRevision: request.expectedRevision === null ? null : counter(request.expectedRevision),
|
|
209
195
|
...membership(request.attachments, request.defaultNetworkId) };
|
|
210
196
|
});
|
|
211
197
|
|
|
212
|
-
export const
|
|
213
|
-
|
|
214
|
-
const operation = Object.getOwnPropertyDescriptor(value, 'operation')?.value;
|
|
198
|
+
export const snapshotPrivateNetworkMutation = (value: unknown): TPrivateNetworkMutation => safe(() => {
|
|
199
|
+
const operation = readDataProperty(value, 'operation')?.value;
|
|
215
200
|
requireValue(operation === 'create' || operation === 'update' || operation === 'retire');
|
|
216
|
-
const request = object(value, ['
|
|
201
|
+
const request = object(value, ['organizationId', 'mutationId', 'operation', 'expectedRevision',
|
|
217
202
|
...(operation === 'create' ? [] : ['networkId']), ...(operation === 'retire' ? [] : ['name', 'policy'])]);
|
|
218
|
-
|
|
219
|
-
const base = { schemaVersion: 1 as const, organizationId: identifier(request.organizationId), mutationId: identifier(request.mutationId) };
|
|
203
|
+
const base = { organizationId: identifier(request.organizationId), mutationId: identifier(request.mutationId) };
|
|
220
204
|
if (operation === 'create') {
|
|
221
205
|
requireValue(request.expectedRevision === null);
|
|
222
|
-
return { ...base, operation, expectedRevision: null, name: name(request.name), policy:
|
|
206
|
+
return { ...base, operation, expectedRevision: null, name: name(request.name), policy: snapshotPrivateNetworkPolicy(request.policy) };
|
|
223
207
|
}
|
|
224
208
|
const current = { networkId: identifier(request.networkId), expectedRevision: counter(request.expectedRevision) };
|
|
225
209
|
if (operation === 'retire') return { ...base, ...current, operation };
|
|
226
|
-
return { ...base, ...current, operation, name: name(request.name), policy:
|
|
210
|
+
return { ...base, ...current, operation, name: name(request.name), policy: snapshotPrivateNetworkPolicy(request.policy) };
|
|
227
211
|
});
|
|
228
212
|
|
|
229
213
|
/** Pure naming helper; it does not reserve a name or create any public DNS/ingress record. */
|
|
230
|
-
export const
|
|
231
|
-
const network =
|
|
232
|
-
return `${label(aliasValue)}.${network.networkDnsKey}.${network.organizationDnsKey}.${
|
|
214
|
+
export const buildPrivateNetworkFqdn = (networkValue: unknown, aliasValue: unknown): string => safe(() => {
|
|
215
|
+
const network = snapshotPrivateNetwork(networkValue);
|
|
216
|
+
return `${label(aliasValue)}.${network.networkDnsKey}.${network.organizationDnsKey}.${privateNetworkContract.privateRoot}`;
|
|
233
217
|
});
|
|
234
218
|
|
|
235
|
-
export interface
|
|
219
|
+
export interface IServicePrivateNetworkDnsPolicy {
|
|
236
220
|
organizationId: string;
|
|
237
221
|
serviceId: string;
|
|
238
222
|
membershipRevision: number;
|
|
@@ -260,11 +244,11 @@ const minimalSuffixes = (values: string[]): string[] => {
|
|
|
260
244
|
* The caller must fence these exact revisions before issuing runtime authority.
|
|
261
245
|
* An inactive/missing/extra network is rejected, never silently omitted.
|
|
262
246
|
*/
|
|
263
|
-
export const
|
|
247
|
+
export const composeServicePrivateNetworkDnsPolicy = (
|
|
264
248
|
membershipValue: unknown, networksValue: unknown,
|
|
265
|
-
):
|
|
266
|
-
const member =
|
|
267
|
-
const networks = array(networksValue,
|
|
249
|
+
): IServicePrivateNetworkDnsPolicy => safe(() => {
|
|
250
|
+
const member = snapshotServicePrivateNetworks(membershipValue);
|
|
251
|
+
const networks = array(networksValue, privateNetworkContract.maximumAttachments, snapshotPrivateNetwork);
|
|
268
252
|
requireValue(networks.length === member.attachments.length
|
|
269
253
|
&& new Set(networks.map(network => network.id)).size === networks.length
|
|
270
254
|
&& new Set(networks.map(network => network.networkDnsKey)).size === networks.length
|
|
@@ -273,10 +257,10 @@ export const composeServicePrivateNetworkDnsPolicyV1 = (
|
|
|
273
257
|
&& network.state === 'active' && member.attachments.some(attachment => attachment.networkId === network.id));
|
|
274
258
|
const ordered = member.attachments.map(attachment => networks.find(network => network.id === attachment.networkId)!);
|
|
275
259
|
const networkSuffixes = ordered.map(network => ({ networkId: network.id, networkRevision: network.revision,
|
|
276
|
-
dnsSuffix: `${network.networkDnsKey}.${network.organizationDnsKey}.${
|
|
260
|
+
dnsSuffix: `${network.networkDnsKey}.${network.organizationDnsKey}.${privateNetworkContract.privateRoot}` }));
|
|
277
261
|
const searchDomains = member.defaultNetworkId === null ? []
|
|
278
262
|
: [networkSuffixes.find(network => network.networkId === member.defaultNetworkId)!.dnsSuffix];
|
|
279
|
-
let externalDns:
|
|
263
|
+
let externalDns: IServicePrivateNetworkDnsPolicy['externalDns'] = null;
|
|
280
264
|
if (ordered.length > 0 && ordered.every(network => network.policy.externalDns !== null)) {
|
|
281
265
|
const policies = ordered.map(network => network.policy.externalDns!);
|
|
282
266
|
const upstreams = policies[0].upstreams.filter(upstream => policies.every(policy => policy.upstreams.some(
|