@serve.zone/interfaces 32.59.0 → 32.61.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 +4 -2
- package/changelog.md +87 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/delegatedadmintoken.d.ts +142 -0
- package/dist_ts/data/delegatedadmintoken.js +197 -0
- package/dist_ts/data/externalregistry.d.ts +37 -1
- package/dist_ts/data/gateway.d.ts +23 -4
- package/dist_ts/data/gateway.js +1 -1
- package/dist_ts/data/index.d.ts +2 -0
- package/dist_ts/data/index.js +3 -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 +67 -1
- package/dist_ts/data/secret.js +59 -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/admin.d.ts +52 -0
- package/dist_ts/requests/externalregistry.d.ts +12 -6
- package/dist_ts/requests/identity.d.ts +4 -0
- package/dist_ts/requests/service.d.ts +16 -1
- package/package.json +5 -8
- package/readme.md +76 -12
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/delegatedadmintoken.ts +282 -0
- package/ts/data/externalregistry.ts +60 -2
- package/ts/data/gateway.ts +24 -3
- package/ts/data/index.ts +2 -0
- package/ts/data/launchersecretowner.ts +145 -0
- package/ts/data/secret.ts +103 -7
- package/ts/data/serviceruntime.ts +9 -1
- package/ts/platform/objectstorageenvironment.ts +26 -8
- package/ts/requests/admin.ts +51 -0
- package/ts/requests/externalregistry.ts +12 -6
- package/ts/requests/identity.ts +4 -0
- package/ts/requests/service.ts +16 -1
|
@@ -133,8 +133,14 @@ export const validateObjectStorageBindingEnvironment = async (environmentArg, pa
|
|
|
133
133
|
return errors;
|
|
134
134
|
};
|
|
135
135
|
const findEnvironmentCollisions = (claimedKeysArg, keysArg) => keysArg.filter((keyArg) => claimedKeysArg.has(keyArg)).sort();
|
|
136
|
-
const describeEnvironmentCollisions = (collisionsArg
|
|
137
|
-
|
|
136
|
+
const describeEnvironmentCollisions = (collisionsArg, secretNamesArg = new Set()) => {
|
|
137
|
+
const secretCollisions = collisionsArg.filter((keyArg) => secretNamesArg.has(keyArg));
|
|
138
|
+
return `objectstorage binding environment collides with ${collisionsArg.join(', ')} already set on `
|
|
139
|
+
+ 'the workload' + (secretCollisions.length > 0
|
|
140
|
+
? `; ${secretCollisions.join(', ')} reaches it as a launcher-environment secret, which would `
|
|
141
|
+
+ 'replace the binding\'s value'
|
|
142
|
+
: '');
|
|
143
|
+
};
|
|
138
144
|
/**
|
|
139
145
|
* A workload environment with one binding's environment added.
|
|
140
146
|
*
|
|
@@ -160,11 +166,21 @@ export const mergeObjectStorageBindingEnvironment = (environmentArg, bindingEnvi
|
|
|
160
166
|
* already claims all twenty of its names, so a collision with it is refused now, not once its
|
|
161
167
|
* evidence arrives. The first refusal is answered, otherwise the first wait, otherwise the
|
|
162
168
|
* composed environment. The inputs are not changed.
|
|
169
|
+
*
|
|
170
|
+
* `secretEnvironmentNamesArg` names the variables the workload receives as launcher-environment
|
|
171
|
+
* secrets (each `ISecretResolvedLauncherEnvironmentDelivery.variableName` of its desired
|
|
172
|
+
* manifest), names only, never a value. The launcher sets a secret over a plain variable of the same name, so a
|
|
173
|
+
* secret named like one of a binding's names would silently replace the binding's value: such a
|
|
174
|
+
* name claims the binding's name exactly as the service's own environment does, and is refused as
|
|
175
|
+
* `objectstorage-environment-conflict`. A secret by any other name is not this composition's
|
|
176
|
+
* concern, and neither are a binding's credential names (`corestoreObjectStorageCredentialSecretKeys`),
|
|
177
|
+
* which the binding itself delivers as secrets and never as plain names.
|
|
163
178
|
*/
|
|
164
|
-
export const composeObjectStorageServiceEnvironment = async (serviceEnvironmentArg, sourcesArg) => {
|
|
179
|
+
export const composeObjectStorageServiceEnvironment = async (serviceEnvironmentArg, sourcesArg, secretEnvironmentNamesArg = []) => {
|
|
165
180
|
const sources = [...sourcesArg].sort((leftArg, rightArg) => (leftArg.binding.id < rightArg.binding.id ? -1 : leftArg.binding.id > rightArg.binding.id ? 1 : 0));
|
|
166
181
|
let environment = { ...serviceEnvironmentArg };
|
|
167
|
-
const
|
|
182
|
+
const secretNames = new Set(secretEnvironmentNamesArg);
|
|
183
|
+
const claimedKeys = new Set([...Object.keys(environment), ...secretNames]);
|
|
168
184
|
let wait = null;
|
|
169
185
|
for (const source of sources) {
|
|
170
186
|
const bindingId = source.binding.id;
|
|
@@ -178,7 +194,7 @@ export const composeObjectStorageServiceEnvironment = async (serviceEnvironmentA
|
|
|
178
194
|
const collisions = findEnvironmentCollisions(claimedKeys, keys);
|
|
179
195
|
if (collisions.length > 0) {
|
|
180
196
|
return { status: 'refused', reason: 'objectstorage-environment-conflict', bindingId,
|
|
181
|
-
message: describeEnvironmentCollisions(collisions) };
|
|
197
|
+
message: describeEnvironmentCollisions(collisions, secretNames) };
|
|
182
198
|
}
|
|
183
199
|
for (const key of keys)
|
|
184
200
|
claimedKeys.add(key);
|
|
@@ -191,4 +207,4 @@ export const composeObjectStorageServiceEnvironment = async (serviceEnvironmentA
|
|
|
191
207
|
}
|
|
192
208
|
return wait ?? { status: 'composed', environment };
|
|
193
209
|
};
|
|
194
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
210
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0c3RvcmFnZWVudmlyb25tZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvcGxhdGZvcm0vb2JqZWN0c3RvcmFnZWVudmlyb25tZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1BLE9BQU8sRUFDTCxzQ0FBc0MsRUFDdEMsb0NBQW9DLEVBQ3BDLHdDQUF3QyxFQUN4Qyx1Q0FBdUMsRUFDdkMscUNBQXFDLEdBQ3RDLE1BQU0sb0JBQW9CLENBQUM7QUFTNUIsT0FBTyxFQUNMLHVDQUF1QyxFQUN2QyxxQ0FBcUMsRUFDckMseUNBQXlDLEVBQ3pDLHNDQUFzQyxFQUN0QyxvQ0FBb0MsR0FDckMsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsYUFBYSxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFakY7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUNBQW1DLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUMvRCxHQUFHLG9DQUFvQztJQUN2QyxHQUFHLHFDQUFxQztDQUNoQyxDQUFDLENBQUM7QUF3Qlo7OztHQUdHO0FBQ0gsTUFBTSx5QkFBeUIsR0FBRyxLQUFLLEVBQ3JDLFVBQTRCLEVBQzVCLFdBQWtELEVBQ1YsRUFBRTtJQUMxQyxNQUFNLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMvQyxJQUFJLE9BQU8sS0FBSyxJQUFJLElBQUksT0FBTyxDQUFDLFVBQVUsS0FBSyxlQUFlLEVBQUUsQ0FBQztRQUMvRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsK0JBQStCO1lBQ2pFLE9BQU8sRUFBRSxxRUFBcUUsRUFBRSxDQUFDO0lBQ3JGLENBQUM7SUFDRCxNQUFNLFdBQVcsR0FBRyxPQUFPLE9BQU8sQ0FBQyxFQUFFLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFX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
|
|
@@ -2,6 +2,7 @@ import * as plugins from '../plugins.js';
|
|
|
2
2
|
import type { IIdentity, IIdentityCredential, IServiceDeploymentGrant } from '../data/user.js';
|
|
3
3
|
import type { IServiceMachineCredentialMetadata, IServiceMachineCredentialMutationResult, TServiceMachineCredentialMutation } from '../data/servicecredential.js';
|
|
4
4
|
import type { IDeploymentMachineUserMetadata, IDeploymentMachineUserMutationResult, TDeploymentMachineUserMutation } from '../data/deploymentmachineuser.js';
|
|
5
|
+
import type { IDelegatedAdminTokenMetadata, IDelegatedAdminTokenMint, IDelegatedAdminTokenMintResult } from '../data/delegatedadmintoken.js';
|
|
5
6
|
export interface IReq_Admin_GetServiceMachineCredential extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Admin_GetServiceMachineCredential> {
|
|
6
7
|
method: 'getServiceMachineCredential';
|
|
7
8
|
request: {
|
|
@@ -175,3 +176,54 @@ export interface IReq_Cloudly_Coreflow_ReconcileBaseServices extends plugins.typ
|
|
|
175
176
|
routingProof?: ICoreflowRoutingProofResult;
|
|
176
177
|
};
|
|
177
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Mints one delegated admin token (`delegatedAdminTokenContract`) for what the request states
|
|
181
|
+
* (`IDelegatedAdminTokenMint`: its scopes, optional `lifetimeMs` and `secretKeyPrefixes`). Requires
|
|
182
|
+
* a human administrator who signed in within five minutes; a delegated session is refused. The
|
|
183
|
+
* plaintext token is answered on this answer only and is never retrievable again, so the request is
|
|
184
|
+
* sent once and its answer goes past every traffic hook. `lifetimeMs` absent is
|
|
185
|
+
* `defaultLifetimeMs`; Cloudly refuses any lifetime above `maximumLifetimeMs`. Refusals travel as
|
|
186
|
+
* `IDelegatedAdminTokenErrorData`.
|
|
187
|
+
*/
|
|
188
|
+
export interface IReq_Admin_MintDelegatedAdminToken extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Admin_MintDelegatedAdminToken> {
|
|
189
|
+
method: 'mintDelegatedAdminToken';
|
|
190
|
+
request: {
|
|
191
|
+
identity: IIdentityCredential;
|
|
192
|
+
} & IDelegatedAdminTokenMint;
|
|
193
|
+
response: IDelegatedAdminTokenMintResult;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Lists the active delegated admin tokens, value-free, newest first: not expired, not revoked,
|
|
197
|
+
* and their administrator still a human administrator at the credential generation each was
|
|
198
|
+
* minted under. At most `delegatedAdminTokenContract.maximumListedTokens` are answered;
|
|
199
|
+
* `truncated` is true exactly when active tokens beyond them were left out, so no token that
|
|
200
|
+
* needs revoking is hidden without notice. Requires an administrator; a delegated session is
|
|
201
|
+
* refused. Refusals travel as `IDelegatedAdminTokenErrorData`.
|
|
202
|
+
*/
|
|
203
|
+
export interface IReq_Admin_GetDelegatedAdminTokens extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Admin_GetDelegatedAdminTokens> {
|
|
204
|
+
method: 'getDelegatedAdminTokens';
|
|
205
|
+
request: {
|
|
206
|
+
identity: IIdentityCredential;
|
|
207
|
+
};
|
|
208
|
+
response: {
|
|
209
|
+
tokens: IDelegatedAdminTokenMetadata[];
|
|
210
|
+
truncated: boolean;
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Revokes one active delegated admin token; once the revocation commits, no use of the token
|
|
215
|
+
* commits after it, and every session exchanged for it is refused. A success has committed.
|
|
216
|
+
* Requires an administrator, the minting one or any other; a delegated session is refused.
|
|
217
|
+
* Refusals travel as `IDelegatedAdminTokenErrorData`: a token that already does not act (revoked,
|
|
218
|
+
* expired, or its administrator's credential or role changed) is `DELEGATED_ADMIN_TOKEN_INACTIVE`.
|
|
219
|
+
*/
|
|
220
|
+
export interface IReq_Admin_RevokeDelegatedAdminToken extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Admin_RevokeDelegatedAdminToken> {
|
|
221
|
+
method: 'revokeDelegatedAdminToken';
|
|
222
|
+
request: {
|
|
223
|
+
identity: IIdentityCredential;
|
|
224
|
+
tokenId: string;
|
|
225
|
+
};
|
|
226
|
+
response: {
|
|
227
|
+
metadata: IDelegatedAdminTokenMetadata;
|
|
228
|
+
};
|
|
229
|
+
}
|
|
@@ -8,7 +8,7 @@ export interface IReq_GetRegistryById extends plugins.typedrequestInterfaces.imp
|
|
|
8
8
|
id: string;
|
|
9
9
|
};
|
|
10
10
|
response: {
|
|
11
|
-
registry: data.
|
|
11
|
+
registry: data.IExternalRegistryPublic;
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
14
|
export interface IReq_GetRegistries extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetRegistries> {
|
|
@@ -17,7 +17,7 @@ export interface IReq_GetRegistries extends plugins.typedrequestInterfaces.imple
|
|
|
17
17
|
identity: userInterfaces.IIdentity;
|
|
18
18
|
};
|
|
19
19
|
response: {
|
|
20
|
-
registries: data.
|
|
20
|
+
registries: data.IExternalRegistryPublic[];
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
export interface IReq_CreateRegistry extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_CreateRegistry> {
|
|
@@ -27,7 +27,7 @@ export interface IReq_CreateRegistry extends plugins.typedrequestInterfaces.impl
|
|
|
27
27
|
registryData: data.IExternalRegistry['data'];
|
|
28
28
|
};
|
|
29
29
|
response: {
|
|
30
|
-
registry: data.
|
|
30
|
+
registry: data.IExternalRegistryPublic;
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
export interface IReq_UpdateRegistry extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_UpdateRegistry> {
|
|
@@ -35,10 +35,14 @@ export interface IReq_UpdateRegistry extends plugins.typedrequestInterfaces.impl
|
|
|
35
35
|
request: {
|
|
36
36
|
identity: userInterfaces.IIdentity;
|
|
37
37
|
registryId: string;
|
|
38
|
-
|
|
38
|
+
/**
|
|
39
|
+
* The operator fields to change; a field left out keeps its stored value. `password` is
|
|
40
|
+
* write-only: missing or empty keeps the stored credential, and `authType: 'none'` removes it.
|
|
41
|
+
*/
|
|
42
|
+
registryData: Partial<data.TExternalRegistryOperatorData>;
|
|
39
43
|
};
|
|
40
44
|
response: {
|
|
41
|
-
resultRegistry: data.
|
|
45
|
+
resultRegistry: data.IExternalRegistryPublic;
|
|
42
46
|
};
|
|
43
47
|
}
|
|
44
48
|
export interface IReq_DeleteRegistryById extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_DeleteRegistryById> {
|
|
@@ -58,8 +62,10 @@ export interface IReq_VerifyRegistry extends plugins.typedrequestInterfaces.impl
|
|
|
58
62
|
registryId: string;
|
|
59
63
|
};
|
|
60
64
|
response: {
|
|
65
|
+
/** True exactly for the `authenticated` and `anonymous` outcomes. */
|
|
61
66
|
success: boolean;
|
|
67
|
+
outcome: data.TExternalRegistryVerifyOutcome;
|
|
62
68
|
message?: string;
|
|
63
|
-
registry
|
|
69
|
+
registry: data.IExternalRegistryPublic;
|
|
64
70
|
};
|
|
65
71
|
}
|
|
@@ -2,6 +2,10 @@ import * as plugins from '../plugins.js';
|
|
|
2
2
|
import * as userInterfaces from '../data/user.js';
|
|
3
3
|
/**
|
|
4
4
|
* get the identity that then will be used to get the config
|
|
5
|
+
*
|
|
6
|
+
* A delegated admin token (`delegatedAdminTokenContract`) is exchanged here too. Its identity is
|
|
7
|
+
* `type: 'machine'`, `role: 'api'`, `userId: 'delegated-admin-token:<tokenId>'`, expiring with the
|
|
8
|
+
* token; only the requests of the token's scopes admit it, and each re-reads the token.
|
|
5
9
|
*/
|
|
6
10
|
export interface IRequest_Any_Cloudly_CoreflowManager_GetIdentityByToken extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IRequest_Any_Cloudly_CoreflowManager_GetIdentityByToken> {
|
|
7
11
|
method: 'getIdentityByToken';
|
|
@@ -317,7 +317,22 @@ export interface IRequest_Any_Cloudly_UpdateService extends plugins.typedrequest
|
|
|
317
317
|
request: {
|
|
318
318
|
identity: IIdentity;
|
|
319
319
|
serviceId: string;
|
|
320
|
-
|
|
320
|
+
/**
|
|
321
|
+
* The fields to change, merged over the stored service one key deep: a key the update omits
|
|
322
|
+
* keeps its stored value, and a key it states replaces the stored value whole (a stated
|
|
323
|
+
* `ports`, `mail` or `domains` is the complete new value, not a patch of the old one).
|
|
324
|
+
* `containerArgs: null` removes the stored argument vector; no other field takes `null`.
|
|
325
|
+
* `registryTarget` is the exception to "replaces": Cloudly derives it from the service and
|
|
326
|
+
* its image version, so a stated one only makes Cloudly derive it again and is never stored.
|
|
327
|
+
* An optional field cannot be cleared yet: a key whose value is `undefined` is dropped in
|
|
328
|
+
* transit, so it reads as omitted (explicit `null` removal for optional fields is a follow-up).
|
|
329
|
+
*
|
|
330
|
+
* Cloudly's guards ask which keys an update states, so send only the fields that change: a
|
|
331
|
+
* service with a runtime spec refuses any update stating `placement` or `scaleFactor`, and an
|
|
332
|
+
* immutable service refuses `imageId`, `imageVersion`, `registryTarget`, `scaleFactor` and
|
|
333
|
+
* `placement`, even when the stated value repeats the stored one.
|
|
334
|
+
*/
|
|
335
|
+
serviceData: Partial<TServiceUpdateWritableData>;
|
|
321
336
|
};
|
|
322
337
|
response: {
|
|
323
338
|
service: IService;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serve.zone/interfaces",
|
|
3
|
-
"version": "32.
|
|
3
|
+
"version": "32.61.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.",
|
|
6
6
|
"exports": {
|
|
@@ -27,10 +27,7 @@
|
|
|
27
27
|
"@tsclass/tsclass": "^9.5.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@git.zone/
|
|
31
|
-
"@git.zone/tsdoc": "^3.0.2",
|
|
32
|
-
"@git.zone/tsrun": "^3.0.3",
|
|
33
|
-
"@git.zone/tstest": "^8.0.0",
|
|
30
|
+
"@git.zone/tsrepo": "^1.1.1",
|
|
34
31
|
"@types/node": "26.6.5",
|
|
35
32
|
"typescript": "^6.0.3"
|
|
36
33
|
},
|
|
@@ -64,8 +61,8 @@
|
|
|
64
61
|
"last 1 chrome versions"
|
|
65
62
|
],
|
|
66
63
|
"scripts": {
|
|
67
|
-
"test": "
|
|
68
|
-
"build": "
|
|
69
|
-
"buildDocs": "
|
|
64
|
+
"test": "tsrepo test test/ --verbose --logfile --timeout 60",
|
|
65
|
+
"build": "tsrepo build tsfolders",
|
|
66
|
+
"buildDocs": "tsrepo docs"
|
|
70
67
|
}
|
|
71
68
|
}
|
package/readme.md
CHANGED
|
@@ -2103,15 +2103,17 @@ evidence has not arrived). `refused` carries a `TServiceRuntimeRefusal`:
|
|
|
2103
2103
|
`node-authority-unsupported`, `network-policy-missing`, `network-policy-mismatch`,
|
|
2104
2104
|
`network-workload-pool-missing`, `network-workload-pool-exhausted`, `volume-driver-unsupported`,
|
|
2105
2105
|
`volume-options-unsupported`, `volume-shared-unsupported`, `volume-placement-unsupported`,
|
|
2106
|
-
`volume-initialization-unknown`, `volume-ownership-unknown`, `
|
|
2107
|
-
`objectstorage-binding-invalid`, `objectstorage-environment-conflict`,
|
|
2106
|
+
`volume-initialization-unknown`, `volume-ownership-unknown`, `launcher-secret-ownership-unknown`,
|
|
2107
|
+
`objectstorage-endpoint-missing`, `objectstorage-binding-invalid`, `objectstorage-environment-conflict`,
|
|
2108
2108
|
`objectstorage-endpoint-unselected`, `database-endpoint-missing`, `database-endpoint-unselected`,
|
|
2109
2109
|
`cluster-relay-missing` or `cluster-ingress-environment-conflict`.
|
|
2110
2110
|
The first four volume
|
|
2111
2111
|
refusals name what a local storage claim cannot express: a volume driver other than a node-local
|
|
2112
2112
|
directory, driver or mount options, one volume mounted by more than one replica or service, and a
|
|
2113
2113
|
placement that does not pin each volume to one node. The other two name what Cloudly will not guess,
|
|
2114
|
-
see [Service Volume Initialization](#service-volume-initialization).
|
|
2114
|
+
see [Service Volume Initialization](#service-volume-initialization).
|
|
2115
|
+
`launcher-secret-ownership-unknown` is a launcher-environment secret file owner Cloudly cannot know,
|
|
2116
|
+
see [Launcher Secret Ownership](#launcher-secret-ownership). Of the four object-storage
|
|
2115
2117
|
refusals, `objectstorage-endpoint-missing`, `objectstorage-binding-invalid` and
|
|
2116
2118
|
`objectstorage-environment-conflict` name why a binding's environment cannot be composed, see
|
|
2117
2119
|
[Object-Storage Binding Environment](#object-storage-binding-environment), and
|
|
@@ -2194,6 +2196,48 @@ Cloudly knows. The rule decides the first generation of a claim only: every late
|
|
|
2194
2196
|
that claim's own initialization and ownership, whatever `runAs` says by then, since the node refuses
|
|
2195
2197
|
a claim whose initial ownership changed.
|
|
2196
2198
|
|
|
2199
|
+
### Launcher Secret Ownership
|
|
2200
|
+
|
|
2201
|
+
WorkloadInit reads a workload's launcher-environment secret files as the workload's own process
|
|
2202
|
+
identity, so their owner comes from that identity and never from a fixed `0:0`.
|
|
2203
|
+
`deriveLauncherSecretDeliveryOwner({ runAs, imageUsers, launcherDeliveries })` is the one rule, and
|
|
2204
|
+
answers `TLauncherSecretDeliveryOwner`: `derived` with `{ uid, gid }`, `not-required` for a workload
|
|
2205
|
+
without launcher deliveries, or `refused` with `reason: 'launcher-secret-ownership-unknown'`,
|
|
2206
|
+
`variableName` (the group-readable delivery that caused it, else `null`) and a `message`.
|
|
2207
|
+
|
|
2208
|
+
`runAs` is the runtime spec's `profile.runAs`. `imageUsers` holds the image user of the pinned
|
|
2209
|
+
digest's image config in Cloudly's canonical form (the registry manager's `parseCanonicalImageUser`
|
|
2210
|
+
answer, `null` for an image without a user or with an empty `User`, never the raw registry value):
|
|
2211
|
+
one entry for a single-platform manifest, one per platform of a multi-platform index.
|
|
2212
|
+
`launcherDeliveries` are the workload's launcher deliveries as their callers state them
|
|
2213
|
+
(`variableName` and `mode`); group readability is computed from them, never passed in.
|
|
2214
|
+
|
|
2215
|
+
| `runAs` | Image user | Owner |
|
|
2216
|
+
| --- | --- | --- |
|
|
2217
|
+
| `{ user, group }` | any | `user:group` |
|
|
2218
|
+
| `null` | none | `0:0`, the runtime config's root default |
|
|
2219
|
+
| `null` | numeric `u:g` (`root` is `0`) | `u:g` |
|
|
2220
|
+
| `null` | numeric `u`, or `u:<name>` | `u:0` while every delivery is `0o400`; refused, naming the first `0o440` delivery by variable name, otherwise |
|
|
2221
|
+
| `null` | a named user other than `root` | refused |
|
|
2222
|
+
| `null` | a numeric part above `2147483647` | refused |
|
|
2223
|
+
|
|
2224
|
+
An owner-readable (`0o400`) file grants its group nothing, so an unstated group is `0`; a `0o440`
|
|
2225
|
+
file would grant group `0` instead of the image's own group, so it refuses. Every platform of a
|
|
2226
|
+
multi-platform index must derive the same owner, or the workload is refused: it gets one delivery,
|
|
2227
|
+
never one per platform. Without launcher deliveries nothing about the image refuses. Only a
|
|
2228
|
+
structurally malformed input throws.
|
|
2229
|
+
|
|
2230
|
+
The owner travels in the resolved manifest, not in what a caller states. `TSecretDelivery`
|
|
2231
|
+
(`ISecretLauncherEnvironmentDelivery | ISecretFileDelivery`) is a caller's delivery: a Secret's
|
|
2232
|
+
`defaultDelivery`, a SecretSet attachment override, a create request, an App Store declaration. Its
|
|
2233
|
+
launcher member's `uid` and `gid` are optional and deprecated: the resolver ignores them, and
|
|
2234
|
+
`validateSecretDelivery` prefers neither and tolerates both (bounded) until the next major removes
|
|
2235
|
+
them. `TSecretResolvedDelivery` (`ISecretResolvedLauncherEnvironmentDelivery | ISecretFileDelivery`)
|
|
2236
|
+
is `IResolvedSecretManifestEntry.delivery`: its launcher member requires `uid` and `gid` under the
|
|
2237
|
+
same keys, so the manifest's wire format and digest are unchanged for every node.
|
|
2238
|
+
`createResolvedSecretDelivery(delivery, owner)` builds it from a caller's delivery and the derived
|
|
2239
|
+
owner, and `validateSecretResolvedDelivery` checks it. File deliveries keep their stated owner.
|
|
2240
|
+
|
|
2197
2241
|
### Runtime Assignment Views
|
|
2198
2242
|
|
|
2199
2243
|
`data.IServiceRuntimeAssignmentView` is one replica slot's current assignment as an administrator
|
|
@@ -2998,6 +3042,15 @@ Common data contracts include:
|
|
|
2998
3042
|
`proposeClusterNodeName`) and the named `clusterNodeHostnameRefusals` of
|
|
2999
3043
|
`setClusterNodeHostname` and `resetClusterNodeHostname`.
|
|
3000
3044
|
- `IService`, `IDeployment`, `IImage`, `IRegistryTarget`, and `IExternalRegistry` for workload delivery.
|
|
3045
|
+
- External registries: `IExternalRegistry` is the stored registry, credential included, and is
|
|
3046
|
+
never answered. Every `requests.externalRegistry` response carries `IExternalRegistryPublic`: the
|
|
3047
|
+
registry without `data.password` and with `passwordConfigured`. `data.password` (a password, access
|
|
3048
|
+
token or API key) is write-only: create stores it; an update (`registryData`, a `Partial` of
|
|
3049
|
+
`TExternalRegistryOperatorData`, never status, errors or timestamps) keeps the stored one when it
|
|
3050
|
+
is missing or empty, and `authType: 'none'` removes it. `verifyExternalRegistry` answers a
|
|
3051
|
+
`TExternalRegistryVerifyOutcome`: only `authenticated` proves the credentials;
|
|
3052
|
+
`credentials-not-exercised` means the registry answered anonymously although credentials are
|
|
3053
|
+
configured.
|
|
3001
3054
|
- Service port contracts including `IServiceTargetPort`, `IServiceDomainRoute`, and `IServicePublicPortMapping` for canonical backend targets, domain target references, and edge/Coretraffic TCP/UDP public exposure.
|
|
3002
3055
|
- `IDomain`, `IDnsEntry`, and traffic contracts for routing and DNS management. `IDomain.data.gatewayListedAt` records when the dcrouter gateway last listed the domain to this Cloudly and is absent while the gateway does not list it; it is separate from the operator's `activationState`.
|
|
3003
3056
|
- Traffic and gateway route contracts including `ICoretrafficPortRouteConfig`, routing `portRoutes`, and `IGatewayClientRoute` client-owned route views. Gateway route intent supports optional match `domains`, `transport`, and `remoteIngress`, plus explicit route `priority` and `managedRouteKind`. Ownership can combine `hostname` with `routeRef` so a normal route and a path-specific managed route for the same hostname reconcile independently.
|
|
@@ -4612,12 +4665,20 @@ to a workload environment and refuses, naming every key, a name that is already
|
|
|
4612
4665
|
service itself or by a second object-storage binding — instead of letting one value replace
|
|
4613
4666
|
another.
|
|
4614
4667
|
|
|
4615
|
-
**Reporting.** `composeObjectStorageServiceEnvironment(serviceEnvironment, sources
|
|
4616
|
-
whole service and answers in the service runtime vocabulary,
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4668
|
+
**Reporting.** `composeObjectStorageServiceEnvironment(serviceEnvironment, sources,
|
|
4669
|
+
secretEnvironmentNames?)` composes a whole service and answers in the service runtime vocabulary,
|
|
4670
|
+
so a producer never classifies the errors above. Each
|
|
4671
|
+
`IObjectStorageBindingEnvironmentSource { binding, endpoint }` is an enabled object-storage binding
|
|
4672
|
+
and the `corestoreObjectStorage` of the node it is placed on, `null` when that node states none; a
|
|
4673
|
+
binding placed on no node is not a source, and its service waits as `bindings-pending`.
|
|
4674
|
+
`secretEnvironmentNames` names, without values, the variables the workload receives as
|
|
4675
|
+
launcher-environment secrets (the `variableName` of each `launcher-environment` delivery in its
|
|
4676
|
+
desired secret manifest; none when omitted). The launcher sets a secret over a plain variable of
|
|
4677
|
+
the same name, so a secret named like a binding's name would silently replace the binding's
|
|
4678
|
+
endpoint: it claims the name exactly as the service's own environment does. Secrets by any other
|
|
4679
|
+
name, including the binding's own credentials (`corestoreObjectStorageCredentialSecretKeys`, never
|
|
4680
|
+
plain names), do not concern the composition. `secretEnvironmentNames` becomes required in the
|
|
4681
|
+
coordinated major. The answer is a `TObjectStorageServiceEnvironmentComposition`:
|
|
4621
4682
|
|
|
4622
4683
|
| `status` | `reason` | When |
|
|
4623
4684
|
| --- | --- | --- |
|
|
@@ -4625,7 +4686,7 @@ that node states none; a binding placed on no node is not a source, and its serv
|
|
|
4625
4686
|
| `waiting` | `objectstorage-retention-pending` | A binding declares compliance retention whose evidence has not arrived. |
|
|
4626
4687
|
| `refused` | `objectstorage-endpoint-missing` | The binding's node states no valid `corestoreObjectStorage`. |
|
|
4627
4688
|
| `refused` | `objectstorage-binding-invalid` | `createObjectStorageBindingEnvironment()` refuses the binding: not `objectstorage`, no canonical bucket, no canonical retention intent, or evidence that does not prove this binding. |
|
|
4628
|
-
| `refused` | `objectstorage-environment-conflict` | The service's own environment or another binding already sets one of the binding's names. |
|
|
4689
|
+
| `refused` | `objectstorage-environment-conflict` | The service's own environment, one of its launcher-environment secrets or another binding already sets one of the binding's names. |
|
|
4629
4690
|
|
|
4630
4691
|
`waiting` and `refused` carry the `bindingId` and the contract's `message`. Bindings are taken in
|
|
4631
4692
|
id order, so the verdict does not depend on the order of the sources, and a refusal outranks a
|
|
@@ -4682,7 +4743,10 @@ object-storage endpoint. What they are addressed to is a fact about the node, ow
|
|
|
4682
4743
|
### Launcher Environment Delivery
|
|
4683
4744
|
|
|
4684
4745
|
Launcher environment delivery uses stable `szsv-<base32-sha256>` Docker
|
|
4685
|
-
resource names and `/run/serve.zone/secrets/<resource>` source paths.
|
|
4746
|
+
resource names and `/run/serve.zone/secrets/<resource>` source paths. Each
|
|
4747
|
+
source file is owned by the workload identity the resolved manifest states,
|
|
4748
|
+
derived by `deriveLauncherSecretDeliveryOwner` (see
|
|
4749
|
+
[Launcher Secret Ownership](#launcher-secret-ownership)). The
|
|
4686
4750
|
nonsecret map is written to `/run/serve.zone/workloadinit-map.json` with mode
|
|
4687
4751
|
0444. Runtime assets under `/opt/serve.zone/runtime-assets` are read-only, the
|
|
4688
4752
|
wrapper itself lives at
|
|
@@ -4781,7 +4845,7 @@ pnpm test
|
|
|
4781
4845
|
pnpm run buildDocs
|
|
4782
4846
|
```
|
|
4783
4847
|
|
|
4784
|
-
The package is authored as ESM TypeScript and built with `
|
|
4848
|
+
The package is authored as ESM TypeScript and built with `tsrepo build tsfolders`.
|
|
4785
4849
|
|
|
4786
4850
|
## License and Legal Information
|
|
4787
4851
|
|