@serve.zone/interfaces 32.58.0 → 32.60.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/changelog.md +84 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/domain.d.ts +6 -0
- package/dist_ts/data/externalregistry.d.ts +37 -1
- package/dist_ts/data/index.d.ts +1 -0
- package/dist_ts/data/index.js +2 -1
- package/dist_ts/data/launchersecretowner.d.ts +60 -0
- package/dist_ts/data/launchersecretowner.js +94 -0
- package/dist_ts/data/secret.d.ts +44 -1
- package/dist_ts/data/secret.js +27 -6
- package/dist_ts/data/serviceruntime.d.ts +9 -2
- package/dist_ts/data/serviceruntime.js +2 -1
- package/dist_ts/platform/objectstorageenvironment.d.ts +12 -3
- package/dist_ts/platform/objectstorageenvironment.js +22 -6
- package/dist_ts/requests/externalregistry.d.ts +12 -6
- package/dist_ts/requests/service.d.ts +16 -1
- package/package.json +1 -1
- package/readme.md +76 -12
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/domain.ts +8 -1
- package/ts/data/externalregistry.ts +60 -2
- package/ts/data/index.ts +1 -0
- package/ts/data/launchersecretowner.ts +145 -0
- package/ts/data/secret.ts +65 -7
- package/ts/data/serviceruntime.ts +9 -1
- package/ts/platform/objectstorageenvironment.ts +26 -8
- package/ts/requests/externalregistry.ts +12 -6
- package/ts/requests/service.ts +16 -1
|
@@ -89,6 +89,7 @@ const serviceRuntimeRefusals = [
|
|
|
89
89
|
'network-workload-pool-missing', 'network-workload-pool-exhausted',
|
|
90
90
|
'volume-driver-unsupported', 'volume-options-unsupported', 'volume-shared-unsupported',
|
|
91
91
|
'volume-placement-unsupported', 'volume-initialization-unknown', 'volume-ownership-unknown',
|
|
92
|
+
'launcher-secret-ownership-unknown',
|
|
92
93
|
'objectstorage-endpoint-missing', 'objectstorage-binding-invalid', 'objectstorage-environment-conflict',
|
|
93
94
|
'objectstorage-endpoint-unselected', 'database-endpoint-missing', 'database-endpoint-unselected',
|
|
94
95
|
'published-port-reserved', 'published-port-symmetric-without-egress', 'readiness-network-unsupported',
|
|
@@ -128,11 +129,18 @@ export type TServiceRuntimeWaitingReason = typeof serviceRuntimeWaitingReasons[n
|
|
|
128
129
|
* `volume-ownership-unknown` a `run-as` ownership under `runAs: null`
|
|
129
130
|
* (`deriveServiceVolumeClaimInitialization`); neither is defaulted.
|
|
130
131
|
*
|
|
132
|
+
* `launcher-secret-ownership-unknown` is a service with launcher-environment secrets whose runtime
|
|
133
|
+
* spec runs the image's own user (`runAs: null`) while that user's numeric owner is not known: a
|
|
134
|
+
* named non-root user, a numeric part above the identity bound, a group a `0o440` delivery would grant that the image does not state
|
|
135
|
+
* numerically, or platforms of the pinned index that derive different owners
|
|
136
|
+
* (`deriveLauncherSecretDeliveryOwner`). WorkloadInit could not read secret files owned by a guess.
|
|
137
|
+
*
|
|
131
138
|
* The object-storage refusals name why a binding's environment cannot be composed
|
|
132
139
|
* (`composeObjectStorageServiceEnvironment`): `objectstorage-endpoint-missing` a binding whose node
|
|
133
140
|
* states no valid `corestoreObjectStorage`, `objectstorage-binding-invalid` a binding
|
|
134
141
|
* `createObjectStorageBindingEnvironment` refuses, and `objectstorage-environment-conflict` a name
|
|
135
|
-
* the service's own environment or another binding already
|
|
142
|
+
* the service's own environment, one of its launcher-environment secrets or another binding already
|
|
143
|
+
* sets.
|
|
136
144
|
*
|
|
137
145
|
* `database-endpoint-missing` is an enabled database binding placed on a node that states no valid
|
|
138
146
|
* `corestoreDatabase`: its credential cannot be addressed to any host a workload reaches, so it is
|
|
@@ -201,10 +201,17 @@ const findEnvironmentCollisions = (
|
|
|
201
201
|
keysArg: readonly string[],
|
|
202
202
|
): string[] => keysArg.filter((keyArg) => claimedKeysArg.has(keyArg)).sort();
|
|
203
203
|
|
|
204
|
-
const describeEnvironmentCollisions = (
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
)
|
|
204
|
+
const describeEnvironmentCollisions = (
|
|
205
|
+
collisionsArg: readonly string[],
|
|
206
|
+
secretNamesArg: ReadonlySet<string> = new Set(),
|
|
207
|
+
): string => {
|
|
208
|
+
const secretCollisions = collisionsArg.filter((keyArg) => secretNamesArg.has(keyArg));
|
|
209
|
+
return `objectstorage binding environment collides with ${collisionsArg.join(', ')} already set on `
|
|
210
|
+
+ 'the workload' + (secretCollisions.length > 0
|
|
211
|
+
? `; ${secretCollisions.join(', ')} reaches it as a launcher-environment secret, which would `
|
|
212
|
+
+ 'replace the binding\'s value'
|
|
213
|
+
: '');
|
|
214
|
+
};
|
|
208
215
|
|
|
209
216
|
/**
|
|
210
217
|
* A workload environment with one binding's environment added.
|
|
@@ -252,8 +259,8 @@ export type TObjectStorageEnvironmentWaitingReason = Extract<
|
|
|
252
259
|
* `corestoreObjectStorage`; `objectstorage-binding-invalid` a binding
|
|
253
260
|
* `createObjectStorageBindingEnvironment()` refuses (not `objectstorage`, no canonical bucket, no
|
|
254
261
|
* canonical retention intent, or evidence that does not prove this binding);
|
|
255
|
-
* `objectstorage-environment-conflict` a name the service's own environment
|
|
256
|
-
* already sets.
|
|
262
|
+
* `objectstorage-environment-conflict` a name the service's own environment, one of its
|
|
263
|
+
* launcher-environment secrets or another binding already sets.
|
|
257
264
|
*/
|
|
258
265
|
export type TObjectStorageEnvironmentRefusal = Extract<
|
|
259
266
|
TServiceRuntimeRefusal,
|
|
@@ -285,16 +292,27 @@ export type TObjectStorageServiceEnvironmentComposition =
|
|
|
285
292
|
* already claims all twenty of its names, so a collision with it is refused now, not once its
|
|
286
293
|
* evidence arrives. The first refusal is answered, otherwise the first wait, otherwise the
|
|
287
294
|
* composed environment. The inputs are not changed.
|
|
295
|
+
*
|
|
296
|
+
* `secretEnvironmentNamesArg` names the variables the workload receives as launcher-environment
|
|
297
|
+
* secrets (each `ISecretResolvedLauncherEnvironmentDelivery.variableName` of its desired
|
|
298
|
+
* manifest), names only, never a value. The launcher sets a secret over a plain variable of the same name, so a
|
|
299
|
+
* secret named like one of a binding's names would silently replace the binding's value: such a
|
|
300
|
+
* name claims the binding's name exactly as the service's own environment does, and is refused as
|
|
301
|
+
* `objectstorage-environment-conflict`. A secret by any other name is not this composition's
|
|
302
|
+
* concern, and neither are a binding's credential names (`corestoreObjectStorageCredentialSecretKeys`),
|
|
303
|
+
* which the binding itself delivers as secrets and never as plain names.
|
|
288
304
|
*/
|
|
289
305
|
export const composeObjectStorageServiceEnvironment = async (
|
|
290
306
|
serviceEnvironmentArg: Readonly<Record<string, string>>,
|
|
291
307
|
sourcesArg: readonly IObjectStorageBindingEnvironmentSource[],
|
|
308
|
+
secretEnvironmentNamesArg: readonly string[] = [],
|
|
292
309
|
): Promise<TObjectStorageServiceEnvironmentComposition> => {
|
|
293
310
|
const sources = [...sourcesArg].sort((leftArg, rightArg) => (
|
|
294
311
|
leftArg.binding.id < rightArg.binding.id ? -1 : leftArg.binding.id > rightArg.binding.id ? 1 : 0
|
|
295
312
|
));
|
|
296
313
|
let environment: Record<string, string> = { ...serviceEnvironmentArg };
|
|
297
|
-
const
|
|
314
|
+
const secretNames: ReadonlySet<string> = new Set(secretEnvironmentNamesArg);
|
|
315
|
+
const claimedKeys = new Set([...Object.keys(environment), ...secretNames]);
|
|
298
316
|
let wait: Extract<TObjectStorageServiceEnvironmentComposition, { status: 'waiting' }> | null = null;
|
|
299
317
|
for (const source of sources) {
|
|
300
318
|
const bindingId = source.binding.id;
|
|
@@ -308,7 +326,7 @@ export const composeObjectStorageServiceEnvironment = async (
|
|
|
308
326
|
const collisions = findEnvironmentCollisions(claimedKeys, keys);
|
|
309
327
|
if (collisions.length > 0) {
|
|
310
328
|
return { status: 'refused', reason: 'objectstorage-environment-conflict', bindingId,
|
|
311
|
-
message: describeEnvironmentCollisions(collisions) };
|
|
329
|
+
message: describeEnvironmentCollisions(collisions, secretNames) };
|
|
312
330
|
}
|
|
313
331
|
for (const key of keys) claimedKeys.add(key);
|
|
314
332
|
if (resolution.status === 'composed') {
|
|
@@ -12,7 +12,7 @@ export interface IReq_GetRegistryById extends plugins.typedrequestInterfaces.imp
|
|
|
12
12
|
id: string;
|
|
13
13
|
};
|
|
14
14
|
response: {
|
|
15
|
-
registry: data.
|
|
15
|
+
registry: data.IExternalRegistryPublic;
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -25,7 +25,7 @@ export interface IReq_GetRegistries extends plugins.typedrequestInterfaces.imple
|
|
|
25
25
|
identity: userInterfaces.IIdentity;
|
|
26
26
|
};
|
|
27
27
|
response: {
|
|
28
|
-
registries: data.
|
|
28
|
+
registries: data.IExternalRegistryPublic[];
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -39,7 +39,7 @@ export interface IReq_CreateRegistry extends plugins.typedrequestInterfaces.impl
|
|
|
39
39
|
registryData: data.IExternalRegistry['data'];
|
|
40
40
|
};
|
|
41
41
|
response: {
|
|
42
|
-
registry: data.
|
|
42
|
+
registry: data.IExternalRegistryPublic;
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -51,10 +51,14 @@ export interface IReq_UpdateRegistry extends plugins.typedrequestInterfaces.impl
|
|
|
51
51
|
request: {
|
|
52
52
|
identity: userInterfaces.IIdentity;
|
|
53
53
|
registryId: string;
|
|
54
|
-
|
|
54
|
+
/**
|
|
55
|
+
* The operator fields to change; a field left out keeps its stored value. `password` is
|
|
56
|
+
* write-only: missing or empty keeps the stored credential, and `authType: 'none'` removes it.
|
|
57
|
+
*/
|
|
58
|
+
registryData: Partial<data.TExternalRegistryOperatorData>;
|
|
55
59
|
};
|
|
56
60
|
response: {
|
|
57
|
-
resultRegistry: data.
|
|
61
|
+
resultRegistry: data.IExternalRegistryPublic;
|
|
58
62
|
};
|
|
59
63
|
}
|
|
60
64
|
|
|
@@ -82,8 +86,10 @@ export interface IReq_VerifyRegistry extends plugins.typedrequestInterfaces.impl
|
|
|
82
86
|
registryId: string;
|
|
83
87
|
};
|
|
84
88
|
response: {
|
|
89
|
+
/** True exactly for the `authenticated` and `anonymous` outcomes. */
|
|
85
90
|
success: boolean;
|
|
91
|
+
outcome: data.TExternalRegistryVerifyOutcome;
|
|
86
92
|
message?: string;
|
|
87
|
-
registry
|
|
93
|
+
registry: data.IExternalRegistryPublic;
|
|
88
94
|
};
|
|
89
95
|
}
|
package/ts/requests/service.ts
CHANGED
|
@@ -455,7 +455,22 @@ extends plugins.typedrequestInterfaces.implementsTR<
|
|
|
455
455
|
request: {
|
|
456
456
|
identity: IIdentity;
|
|
457
457
|
serviceId: string;
|
|
458
|
-
|
|
458
|
+
/**
|
|
459
|
+
* The fields to change, merged over the stored service one key deep: a key the update omits
|
|
460
|
+
* keeps its stored value, and a key it states replaces the stored value whole (a stated
|
|
461
|
+
* `ports`, `mail` or `domains` is the complete new value, not a patch of the old one).
|
|
462
|
+
* `containerArgs: null` removes the stored argument vector; no other field takes `null`.
|
|
463
|
+
* `registryTarget` is the exception to "replaces": Cloudly derives it from the service and
|
|
464
|
+
* its image version, so a stated one only makes Cloudly derive it again and is never stored.
|
|
465
|
+
* An optional field cannot be cleared yet: a key whose value is `undefined` is dropped in
|
|
466
|
+
* transit, so it reads as omitted (explicit `null` removal for optional fields is a follow-up).
|
|
467
|
+
*
|
|
468
|
+
* Cloudly's guards ask which keys an update states, so send only the fields that change: a
|
|
469
|
+
* service with a runtime spec refuses any update stating `placement` or `scaleFactor`, and an
|
|
470
|
+
* immutable service refuses `imageId`, `imageVersion`, `registryTarget`, `scaleFactor` and
|
|
471
|
+
* `placement`, even when the stated value repeats the stored one.
|
|
472
|
+
*/
|
|
473
|
+
serviceData: Partial<TServiceUpdateWritableData>;
|
|
459
474
|
};
|
|
460
475
|
response: {
|
|
461
476
|
service: IService;
|