@wtfalch/foundry 0.32.0 → 0.33.1
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/dist/bootstrap/bootstrap.d.ts +18 -1
- package/dist/bootstrap/bootstrap.js +167 -28
- package/dist/bootstrap/declare.d.ts +5 -1
- package/dist/bootstrap/declare.js +3 -1
- package/dist/bootstrap/index.d.ts +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -0
- package/dist/org.d.ts +6 -2
- package/dist/org.js +16 -0
- package/dist/plan/boule.d.ts +24 -1
- package/dist/plan/boule.js +29 -1
- package/dist/plan/diff.d.ts +3 -1
- package/dist/plan/diff.js +125 -9
- package/dist/plan/executor.d.ts +65 -7
- package/dist/plan/executor.js +144 -18
- package/dist/plan/health-targets.js +1 -1
- package/dist/plan/index.d.ts +2 -0
- package/dist/plan/index.js +1 -0
- package/dist/plan/plan-apply.d.ts +23 -0
- package/dist/plan/plan-apply.js +11 -0
- package/dist/plan/platform-diff.d.ts +33 -12
- package/dist/plan/platform-diff.js +95 -31
- package/dist/plan/platform-org.d.ts +2 -0
- package/dist/plan/platform-org.js +2 -0
- package/dist/plan/platform-providers.d.ts +51 -4
- package/dist/plan/platform-providers.js +296 -79
- package/dist/plan/sign-in-org.d.ts +99 -0
- package/dist/plan/sign-in-org.js +133 -0
- package/dist/plan.d.ts +18 -0
- package/package.json +1 -1
|
@@ -172,6 +172,12 @@ export interface StepExecutor {
|
|
|
172
172
|
* an executor without it supplies none.
|
|
173
173
|
*/
|
|
174
174
|
ownEdgePorts?(): Partial<Record<EdgePortName, boolean>>;
|
|
175
|
+
/**
|
|
176
|
+
* Every secret this executor minted or read so far (peer password, bridge
|
|
177
|
+
* secret, invite code and link). The host's run adds them to its redactor
|
|
178
|
+
* after each step, so an error or progress line that quotes one is masked.
|
|
179
|
+
*/
|
|
180
|
+
secretsHandled?(): readonly string[];
|
|
175
181
|
}
|
|
176
182
|
/**
|
|
177
183
|
* #167: {@link StepExecutionContext}'s platform-scoped counterpart -- what
|
|
@@ -395,6 +401,12 @@ export interface FoundryPlanApplyOptions {
|
|
|
395
401
|
* reported blocked instead of planned.
|
|
396
402
|
*/
|
|
397
403
|
edgeWorkers?: boolean;
|
|
404
|
+
/**
|
|
405
|
+
* True when the host's executor was built with `ownerInviteMail`. Optional,
|
|
406
|
+
* and false without it: each owner's invite is then reported blocked
|
|
407
|
+
* instead of planned.
|
|
408
|
+
*/
|
|
409
|
+
ownerInviteMail?: boolean;
|
|
398
410
|
/**
|
|
399
411
|
* #177: true when the host's executor was built with its own `filesOrganisation`
|
|
400
412
|
* / `aiOrganisation` port. Without one, the org step needs the platform's
|
|
@@ -408,6 +420,15 @@ export interface FoundryPlanApplyOptions {
|
|
|
408
420
|
* reported blocked instead of planned to fail.
|
|
409
421
|
*/
|
|
410
422
|
edge?: boolean;
|
|
423
|
+
/**
|
|
424
|
+
* Narrows every org plan to the steps `step` accepts, and its blocked items
|
|
425
|
+
* to the keys `blocked` accepts, so a plan, its stale check and its apply
|
|
426
|
+
* all see the same slice. Absent: the whole plan.
|
|
427
|
+
*/
|
|
428
|
+
onlySteps?: {
|
|
429
|
+
step(action: StepAction): boolean;
|
|
430
|
+
blocked(key: string): boolean;
|
|
431
|
+
};
|
|
411
432
|
/** Overridable for tests; defaults to `() => new Date()`. */
|
|
412
433
|
now?: () => Date;
|
|
413
434
|
/** #441: how long a mutation lease lasts before another caller may take it over. Defaults to 30 minutes. */
|
|
@@ -486,9 +507,11 @@ export declare class FoundryPlanApply implements PlanApply {
|
|
|
486
507
|
private readonly zitadelIdTokenUserinfo;
|
|
487
508
|
private readonly broker;
|
|
488
509
|
private readonly edgeWorkers;
|
|
510
|
+
private readonly ownerInviteMail;
|
|
489
511
|
private readonly hostFiles;
|
|
490
512
|
private readonly hostAi;
|
|
491
513
|
private readonly hostEdge;
|
|
514
|
+
private readonly onlySteps;
|
|
492
515
|
private readonly now;
|
|
493
516
|
private readonly leaseTtlMs;
|
|
494
517
|
private readonly appliedVersions;
|
package/dist/plan/plan-apply.js
CHANGED
|
@@ -140,9 +140,11 @@ export class FoundryPlanApply {
|
|
|
140
140
|
zitadelIdTokenUserinfo;
|
|
141
141
|
broker;
|
|
142
142
|
edgeWorkers;
|
|
143
|
+
ownerInviteMail;
|
|
143
144
|
hostFiles;
|
|
144
145
|
hostAi;
|
|
145
146
|
hostEdge;
|
|
147
|
+
onlySteps;
|
|
146
148
|
now;
|
|
147
149
|
leaseTtlMs;
|
|
148
150
|
appliedVersions;
|
|
@@ -162,9 +164,11 @@ export class FoundryPlanApply {
|
|
|
162
164
|
this.zitadelIdTokenUserinfo = options.zitadelIdTokenUserinfo ?? false;
|
|
163
165
|
this.broker = options.broker ?? false;
|
|
164
166
|
this.edgeWorkers = options.edgeWorkers ?? false;
|
|
167
|
+
this.ownerInviteMail = options.ownerInviteMail ?? false;
|
|
165
168
|
this.hostFiles = options.filesOrganisation ?? false;
|
|
166
169
|
this.hostAi = options.aiOrganisation ?? false;
|
|
167
170
|
this.hostEdge = options.edge ?? false;
|
|
171
|
+
this.onlySteps = options.onlySteps;
|
|
168
172
|
this.now = options.now ?? (() => new Date());
|
|
169
173
|
this.leaseTtlMs = options.leaseTtlMs ?? DEFAULT_LEASE_TTL_MS;
|
|
170
174
|
this.appliedVersions = options.appliedVersions;
|
|
@@ -911,6 +915,7 @@ export class FoundryPlanApply {
|
|
|
911
915
|
zitadelIdTokenUserinfo: this.zitadelIdTokenUserinfo,
|
|
912
916
|
broker: this.broker,
|
|
913
917
|
edgeWorkers: this.edgeWorkers,
|
|
918
|
+
ownerInviteMail: this.ownerInviteMail,
|
|
914
919
|
otherSlugs,
|
|
915
920
|
now: () => this.now().getTime(),
|
|
916
921
|
archonUrl,
|
|
@@ -926,6 +931,11 @@ export class FoundryPlanApply {
|
|
|
926
931
|
key: 'hosting:invalid',
|
|
927
932
|
});
|
|
928
933
|
}
|
|
934
|
+
if (this.onlySteps) {
|
|
935
|
+
const { step, blocked } = this.onlySteps;
|
|
936
|
+
detail.plannedSteps = detail.plannedSteps.filter(({ action }) => step(action));
|
|
937
|
+
detail.unmanaged = detail.unmanaged.filter((item) => item.key === undefined || blocked(item.key));
|
|
938
|
+
}
|
|
929
939
|
return { org, plan: toPlan(detail), detail };
|
|
930
940
|
}
|
|
931
941
|
/**
|
|
@@ -1489,6 +1499,7 @@ function canonical(plan) {
|
|
|
1489
1499
|
// version-change line must still be caught as stale, the same as any
|
|
1490
1500
|
// other field here.
|
|
1491
1501
|
versionChanges: [...(plan.versionChanges ?? [])].sort((x, y) => x.description.localeCompare(y.description)),
|
|
1502
|
+
notes: [...(plan.notes ?? [])].sort((x, y) => x.key.localeCompare(y.key)),
|
|
1492
1503
|
};
|
|
1493
1504
|
}
|
|
1494
1505
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DeclaredOrg, EnvSharedSecret, HostingEntry, OrgId } from '../org.js';
|
|
2
|
-
import { type Plan, type UnmanagedItem, type VersionChangeItem } from '../plan.js';
|
|
2
|
+
import { type Plan, type PlanNote, type UnmanagedItem, type VersionChangeItem } from '../plan.js';
|
|
3
3
|
import type { DeclaredPlatform } from '../platform.js';
|
|
4
4
|
import type { PlannedStep } from './diff.js';
|
|
5
5
|
import type { LiveResource } from './live.js';
|
|
@@ -16,6 +16,8 @@ export interface PlatformPlanDetail {
|
|
|
16
16
|
unmanaged: UnmanagedItem[];
|
|
17
17
|
/** #251: see {@link VersionChangeItem}. Never folded into `plannedSteps`. */
|
|
18
18
|
versionChanges: VersionChangeItem[];
|
|
19
|
+
/** Advisory lines that block no step; see {@link PlanNote}. */
|
|
20
|
+
notes: PlanNote[];
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* The `Plan` (#19's public contract) a {@link PlatformPlanDetail} carries,
|
|
@@ -161,12 +163,11 @@ export declare const PLATFORM_ARCHON_DEPLOYMENT_SCOPE_KEY = "archon_deployment";
|
|
|
161
163
|
*/
|
|
162
164
|
export declare const PLATFORM_ARCHON_APPLIED_BROKER_SCOPE_KEY = "archon_applied_broker_app";
|
|
163
165
|
/**
|
|
164
|
-
* The
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
* has recorded it.
|
|
166
|
+
* The sign-in org id the last Archon apply set as `AUTH_ORGANIZATION_ID` and
|
|
167
|
+
* registered its broker entry under. `planArchon` plans the step again when
|
|
168
|
+
* {@link archonAuthOrganizationId} differs from it.
|
|
168
169
|
*/
|
|
169
|
-
export declare const
|
|
170
|
+
export declare const PLATFORM_ARCHON_APPLIED_AUTH_ORG_SCOPE_KEY = "archon_applied_auth_org";
|
|
170
171
|
/**
|
|
171
172
|
* #475: whether the last successful Archon apply patched the app with
|
|
172
173
|
* `custom_network_aliases` and `is_consistent_container_name_enabled: false`
|
|
@@ -183,11 +184,11 @@ export declare const PLATFORM_ARCHON_APPLIED_OPERATOR_SCOPE_KEY = "archon_applie
|
|
|
183
184
|
*/
|
|
184
185
|
export declare const PLATFORM_ARCHON_APPLIED_ROLLING_UPDATE_SCOPE_KEY = "archon_applied_rolling_update";
|
|
185
186
|
/**
|
|
186
|
-
* The
|
|
187
|
-
* {@link
|
|
188
|
-
*
|
|
187
|
+
* The sign-in org Archon accepts: the platform owner company's own
|
|
188
|
+
* ({@link PLATFORM_OWNER_ORG_SCOPE_KEY}), else the platform's `foundry` org for
|
|
189
|
+
* a platform with no owner company declared. Undefined when neither is recorded.
|
|
189
190
|
*/
|
|
190
|
-
export declare function
|
|
191
|
+
export declare function archonAuthOrganizationId(recorded: Readonly<Record<string, string>>): string | undefined;
|
|
191
192
|
/**
|
|
192
193
|
* #175: set to '1' before the step points the tunnel at `http_status:404`
|
|
193
194
|
* (Access app rebuild), cleared to '' once the real ingress is written back.
|
|
@@ -207,6 +208,26 @@ export declare const PLATFORM_AUTH_SMTP_SCOPE_KEY = "zitadel_platform_smtp_provi
|
|
|
207
208
|
* requested, so the invite goes out once. `none` when no owner is declared.
|
|
208
209
|
*/
|
|
209
210
|
export declare const PLATFORM_AUTH_OWNER_INVITE_SCOPE_KEY = "zitadel_platform_owner_invite_user_id";
|
|
211
|
+
/** The platform's own ZITADEL org (`foundry`, the one `provisionPlatformAuth` mints its admin user in). */
|
|
212
|
+
export declare const PLATFORM_ZITADEL_ORG_SCOPE_KEY = "zitadel_platform_org";
|
|
213
|
+
/**
|
|
214
|
+
* The id of the platform owner company's own sign-in organisation, made by
|
|
215
|
+
* `platform:auth` with the same name and primary domain a company apply uses,
|
|
216
|
+
* so that apply finds this org and makes no second one. `none` when the owner
|
|
217
|
+
* company is not declared. Archon signs people in from this org; the
|
|
218
|
+
* `foundry` org ({@link PLATFORM_ZITADEL_ORG_SCOPE_KEY}) holds no people.
|
|
219
|
+
*/
|
|
220
|
+
export declare const PLATFORM_OWNER_ORG_SCOPE_KEY = "zitadel_platform_owner_org";
|
|
221
|
+
/** The primary domain `platform:auth` registered on the owner company's sign-in org. */
|
|
222
|
+
export declare const PLATFORM_OWNER_ORG_DOMAIN_SCOPE_KEY = "zitadel_platform_owner_org_domain";
|
|
223
|
+
/** The owner org's sign-in domain the sign-in server refused to make primary; set instead of failing, reported as blocked. */
|
|
224
|
+
export declare const PLATFORM_OWNER_ORG_DOMAIN_BLOCKED_SCOPE_KEY = "zitadel_platform_owner_org_domain_blocked";
|
|
225
|
+
/**
|
|
226
|
+
* The sign-in org the recorded owner invite ({@link PLATFORM_AUTH_OWNER_INVITE_SCOPE_KEY})
|
|
227
|
+
* was made in. An invite recorded against another org (the `foundry` org, on a
|
|
228
|
+
* platform applied before the owner moved) plans the auth step again.
|
|
229
|
+
*/
|
|
230
|
+
export declare const PLATFORM_AUTH_OWNER_INVITE_ORG_SCOPE_KEY = "zitadel_platform_owner_invite_org";
|
|
210
231
|
/**
|
|
211
232
|
* #394: the id of the role-less ZITADEL machine user that reserves the
|
|
212
233
|
* username `admin` in the platform's own org, so nobody can sign up under a
|
|
@@ -216,8 +237,6 @@ export declare const PLATFORM_AUTH_OWNER_INVITE_SCOPE_KEY = "zitadel_platform_ow
|
|
|
216
237
|
export declare const PLATFORM_AUTH_RESERVED_ADMIN_USERNAME_SCOPE_KEY = "zitadel_platform_reserved_admin_username";
|
|
217
238
|
/** #394: recorded once the platform's own ZITADEL org has self-registration forced off. */
|
|
218
239
|
export declare const PLATFORM_AUTH_REGISTRATION_CLOSED_SCOPE_KEY = "zitadel_platform_registration_closed";
|
|
219
|
-
/** The platform's own ZITADEL org (`foundry`, the one `provisionPlatformAuth` mints its admin user in). */
|
|
220
|
-
export declare const PLATFORM_ZITADEL_ORG_SCOPE_KEY = "zitadel_platform_org";
|
|
221
240
|
export declare const PLATFORM_AUTH_ADMIN_USER_SCOPE_KEY = "zitadel_platform_admin_user_id";
|
|
222
241
|
export declare const PLATFORM_AUTH_ADMIN_UNDELIVERED_SCOPE_KEY = "zitadel_platform_admin_user_undelivered";
|
|
223
242
|
/** #283: the created instance's id, recorded once its owner token is delivered. */
|
|
@@ -974,6 +993,8 @@ export interface PlanPlatformOptions {
|
|
|
974
993
|
* these. Default `[]`.
|
|
975
994
|
*/
|
|
976
995
|
authOtherInputsMissing?: string[];
|
|
996
|
+
/** C3: why the owner's invite cannot be made (no work address, no mail port). The rest of the step still plans. */
|
|
997
|
+
authOwnerInvite?: string;
|
|
977
998
|
files?: string;
|
|
978
999
|
integrations?: string;
|
|
979
1000
|
ai?: string;
|
|
@@ -6,6 +6,7 @@ import { versionChangeNeedsConfirmation } from './confirm-upgrade.js';
|
|
|
6
6
|
import { ACCESS_PROVIDER_RECORD_KEY } from './gates.js';
|
|
7
7
|
import { legacyAppHostname } from './hostnames.js';
|
|
8
8
|
import { callsSfuAppliedFingerprint } from './platform-sfu.js';
|
|
9
|
+
import { ZITADEL_ORG_DOMAIN_BLOCKED_SCOPE_KEY, signInDomainBlockedText } from './sign-in-org.js';
|
|
9
10
|
import { withStepSystem } from './step-system.js';
|
|
10
11
|
/**
|
|
11
12
|
* The `Plan` (#19's public contract) a {@link PlatformPlanDetail} carries,
|
|
@@ -22,6 +23,7 @@ export function toPlatformPlan(detail, ownerOrgId) {
|
|
|
22
23
|
steps: detail.plannedSteps.map((p) => p.step),
|
|
23
24
|
unmanaged: detail.unmanaged,
|
|
24
25
|
versionChanges: detail.versionChanges,
|
|
26
|
+
notes: detail.notes,
|
|
25
27
|
};
|
|
26
28
|
}
|
|
27
29
|
function resourceKey(system, kind, key) {
|
|
@@ -195,12 +197,11 @@ export const PLATFORM_ARCHON_DEPLOYMENT_SCOPE_KEY = 'archon_deployment';
|
|
|
195
197
|
*/
|
|
196
198
|
export const PLATFORM_ARCHON_APPLIED_BROKER_SCOPE_KEY = 'archon_applied_broker_app';
|
|
197
199
|
/**
|
|
198
|
-
* The
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* has recorded it.
|
|
200
|
+
* The sign-in org id the last Archon apply set as `AUTH_ORGANIZATION_ID` and
|
|
201
|
+
* registered its broker entry under. `planArchon` plans the step again when
|
|
202
|
+
* {@link archonAuthOrganizationId} differs from it.
|
|
202
203
|
*/
|
|
203
|
-
export const
|
|
204
|
+
export const PLATFORM_ARCHON_APPLIED_AUTH_ORG_SCOPE_KEY = 'archon_applied_auth_org';
|
|
204
205
|
/**
|
|
205
206
|
* #475: whether the last successful Archon apply patched the app with
|
|
206
207
|
* `custom_network_aliases` and `is_consistent_container_name_enabled: false`
|
|
@@ -217,13 +218,15 @@ export const PLATFORM_ARCHON_APPLIED_OPERATOR_SCOPE_KEY = 'archon_applied_bootst
|
|
|
217
218
|
*/
|
|
218
219
|
export const PLATFORM_ARCHON_APPLIED_ROLLING_UPDATE_SCOPE_KEY = 'archon_applied_rolling_update';
|
|
219
220
|
/**
|
|
220
|
-
* The
|
|
221
|
-
* {@link
|
|
222
|
-
*
|
|
221
|
+
* The sign-in org Archon accepts: the platform owner company's own
|
|
222
|
+
* ({@link PLATFORM_OWNER_ORG_SCOPE_KEY}), else the platform's `foundry` org for
|
|
223
|
+
* a platform with no owner company declared. Undefined when neither is recorded.
|
|
223
224
|
*/
|
|
224
|
-
export function
|
|
225
|
-
const
|
|
226
|
-
|
|
225
|
+
export function archonAuthOrganizationId(recorded) {
|
|
226
|
+
const owner = recorded[PLATFORM_OWNER_ORG_SCOPE_KEY];
|
|
227
|
+
if (owner && owner !== 'none')
|
|
228
|
+
return owner;
|
|
229
|
+
return recorded[PLATFORM_ZITADEL_ORG_SCOPE_KEY] || undefined;
|
|
227
230
|
}
|
|
228
231
|
/**
|
|
229
232
|
* #175: set to '1' before the step points the tunnel at `http_status:404`
|
|
@@ -244,6 +247,26 @@ export const PLATFORM_AUTH_SMTP_SCOPE_KEY = 'zitadel_platform_smtp_provider_id';
|
|
|
244
247
|
* requested, so the invite goes out once. `none` when no owner is declared.
|
|
245
248
|
*/
|
|
246
249
|
export const PLATFORM_AUTH_OWNER_INVITE_SCOPE_KEY = 'zitadel_platform_owner_invite_user_id';
|
|
250
|
+
/** The platform's own ZITADEL org (`foundry`, the one `provisionPlatformAuth` mints its admin user in). */
|
|
251
|
+
export const PLATFORM_ZITADEL_ORG_SCOPE_KEY = 'zitadel_platform_org';
|
|
252
|
+
/**
|
|
253
|
+
* The id of the platform owner company's own sign-in organisation, made by
|
|
254
|
+
* `platform:auth` with the same name and primary domain a company apply uses,
|
|
255
|
+
* so that apply finds this org and makes no second one. `none` when the owner
|
|
256
|
+
* company is not declared. Archon signs people in from this org; the
|
|
257
|
+
* `foundry` org ({@link PLATFORM_ZITADEL_ORG_SCOPE_KEY}) holds no people.
|
|
258
|
+
*/
|
|
259
|
+
export const PLATFORM_OWNER_ORG_SCOPE_KEY = 'zitadel_platform_owner_org';
|
|
260
|
+
/** The primary domain `platform:auth` registered on the owner company's sign-in org. */
|
|
261
|
+
export const PLATFORM_OWNER_ORG_DOMAIN_SCOPE_KEY = 'zitadel_platform_owner_org_domain';
|
|
262
|
+
/** The owner org's sign-in domain the sign-in server refused to make primary; set instead of failing, reported as blocked. */
|
|
263
|
+
export const PLATFORM_OWNER_ORG_DOMAIN_BLOCKED_SCOPE_KEY = 'zitadel_platform_owner_org_domain_blocked';
|
|
264
|
+
/**
|
|
265
|
+
* The sign-in org the recorded owner invite ({@link PLATFORM_AUTH_OWNER_INVITE_SCOPE_KEY})
|
|
266
|
+
* was made in. An invite recorded against another org (the `foundry` org, on a
|
|
267
|
+
* platform applied before the owner moved) plans the auth step again.
|
|
268
|
+
*/
|
|
269
|
+
export const PLATFORM_AUTH_OWNER_INVITE_ORG_SCOPE_KEY = 'zitadel_platform_owner_invite_org';
|
|
247
270
|
/**
|
|
248
271
|
* #394: the id of the role-less ZITADEL machine user that reserves the
|
|
249
272
|
* username `admin` in the platform's own org, so nobody can sign up under a
|
|
@@ -253,8 +276,6 @@ export const PLATFORM_AUTH_OWNER_INVITE_SCOPE_KEY = 'zitadel_platform_owner_invi
|
|
|
253
276
|
export const PLATFORM_AUTH_RESERVED_ADMIN_USERNAME_SCOPE_KEY = 'zitadel_platform_reserved_admin_username';
|
|
254
277
|
/** #394: recorded once the platform's own ZITADEL org has self-registration forced off. */
|
|
255
278
|
export const PLATFORM_AUTH_REGISTRATION_CLOSED_SCOPE_KEY = 'zitadel_platform_registration_closed';
|
|
256
|
-
/** The platform's own ZITADEL org (`foundry`, the one `provisionPlatformAuth` mints its admin user in). */
|
|
257
|
-
export const PLATFORM_ZITADEL_ORG_SCOPE_KEY = 'zitadel_platform_org';
|
|
258
279
|
export const PLATFORM_AUTH_ADMIN_USER_SCOPE_KEY = 'zitadel_platform_admin_user_id';
|
|
259
280
|
export const PLATFORM_AUTH_ADMIN_UNDELIVERED_SCOPE_KEY = 'zitadel_platform_admin_user_undelivered';
|
|
260
281
|
/** #283: the created instance's id, recorded once its owner token is delivered. */
|
|
@@ -1138,7 +1159,7 @@ export function planPlatform(platform, live, options = {}) {
|
|
|
1138
1159
|
// reconcile below can be planned in the *same* round hc first comes up,
|
|
1139
1160
|
// the same way files/mail/archon are planned in auth's own first round.
|
|
1140
1161
|
const hcReady = hc.step !== null || Boolean(recordedIds[resourceKey('coolify', 'app', PLATFORM_HC_KEY)]);
|
|
1141
|
-
const auth = planAuth(platform, recordedIds, blocked.auth ?? dnsBlocked?.('sign-in'), blocked.authExecutorMissing ?? false, drifted.auth ?? false, blocked.authOtherInputsMissing ?? []);
|
|
1162
|
+
const auth = planAuth(platform, recordedIds, blocked.auth ?? dnsBlocked?.('sign-in'), blocked.authExecutorMissing ?? false, drifted.auth ?? false, blocked.authOtherInputsMissing ?? [], blocked.authOwnerInvite);
|
|
1142
1163
|
if (auth.step)
|
|
1143
1164
|
plannedSteps.push(auth.step);
|
|
1144
1165
|
// #174: the integrations host. Planned after auth; neither step reads the
|
|
@@ -1243,6 +1264,12 @@ export function planPlatform(platform, live, options = {}) {
|
|
|
1243
1264
|
// A blocked jobs scheduler is reported here, not planned: a step that
|
|
1244
1265
|
// throws every apply, or that can never be seen live and so re-plans
|
|
1245
1266
|
// forever, is worse than none.
|
|
1267
|
+
if (!platform.ownerOrgId) {
|
|
1268
|
+
unmanaged.push({
|
|
1269
|
+
description: "platform.ownerOrgId is not declared, so no org is the platform's own: no peer password or bridge secret is minted for any Boule and Archon reads no people",
|
|
1270
|
+
key: 'owner-org',
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1246
1273
|
if (jobs.blocked)
|
|
1247
1274
|
unmanaged.push({ description: jobs.blocked, key: 'jobs' });
|
|
1248
1275
|
if (platform.sfu.enabled && sfuBlocked) {
|
|
@@ -1284,7 +1311,12 @@ export function planPlatform(platform, live, options = {}) {
|
|
|
1284
1311
|
unmanaged.push({ description: heartbeats.blocked, key: 'heartbeats' });
|
|
1285
1312
|
for (const description of uptime.blocked)
|
|
1286
1313
|
unmanaged.push({ description, key: 'uptime' });
|
|
1287
|
-
return {
|
|
1314
|
+
return {
|
|
1315
|
+
plannedSteps: plannedSteps.map(withStepSystem),
|
|
1316
|
+
unmanaged,
|
|
1317
|
+
versionChanges,
|
|
1318
|
+
notes: uptime.notes,
|
|
1319
|
+
};
|
|
1288
1320
|
}
|
|
1289
1321
|
/**
|
|
1290
1322
|
* The platform's own Cloudflare zone for its shared apex (`platform.ts`'s
|
|
@@ -1703,9 +1735,12 @@ function planSfu(platform, callsOrgSlugs, recordedIds) {
|
|
|
1703
1735
|
* promising "this apply re-mints" while one of those is still missing would
|
|
1704
1736
|
* be wrong the moment it is read.
|
|
1705
1737
|
*/
|
|
1706
|
-
function planAuth(platform, recordedIds, executorBlocked, executorMissing, authDrifted, otherInputsMissing = []) {
|
|
1738
|
+
function planAuth(platform, recordedIds, executorBlocked, executorMissing, authDrifted, otherInputsMissing = [], ownerInviteBlocked) {
|
|
1707
1739
|
if (!platform.auth.enabled)
|
|
1708
1740
|
return { step: null, blocked: null };
|
|
1741
|
+
// C3/S2: standing notes. The invite and the domain wait on a person; they hold nothing else back.
|
|
1742
|
+
const standing = [ownerInviteBlocked, ownerDomainBlockedText(recordedIds)].filter((t) => Boolean(t));
|
|
1743
|
+
const standingNote = standing.length > 0 ? standing.join('; ') : null;
|
|
1709
1744
|
const key = resourceKey('coolify', 'app', PLATFORM_AUTH_KEY);
|
|
1710
1745
|
const connectorApplied = Boolean(recordedIds[PLATFORM_AUTH_CONNECTOR_APP_SCOPE_KEY]);
|
|
1711
1746
|
// #211: a recorded app and connector with no recorded broker id is a
|
|
@@ -1739,11 +1774,18 @@ function planAuth(platform, recordedIds, executorBlocked, executorMissing, authD
|
|
|
1739
1774
|
// Mail and the owner's invite: a platform applied before they existed
|
|
1740
1775
|
// plans the step again, which only adds them.
|
|
1741
1776
|
Boolean(recordedIds[PLATFORM_AUTH_SMTP_SCOPE_KEY]) &&
|
|
1742
|
-
Boolean(recordedIds[PLATFORM_AUTH_OWNER_INVITE_SCOPE_KEY]) &&
|
|
1777
|
+
(Boolean(recordedIds[PLATFORM_AUTH_OWNER_INVITE_SCOPE_KEY]) || Boolean(ownerInviteBlocked)) &&
|
|
1778
|
+
// The owner company's own sign-in org, and an invite made in it: a
|
|
1779
|
+
// platform whose owner was invited into the `foundry` org plans the step again.
|
|
1780
|
+
Boolean(recordedIds[PLATFORM_OWNER_ORG_SCOPE_KEY]) &&
|
|
1781
|
+
(Boolean(ownerInviteBlocked) ||
|
|
1782
|
+
recordedIds[PLATFORM_AUTH_OWNER_INVITE_SCOPE_KEY] === 'none' ||
|
|
1783
|
+
recordedIds[PLATFORM_AUTH_OWNER_INVITE_ORG_SCOPE_KEY] ===
|
|
1784
|
+
recordedIds[PLATFORM_OWNER_ORG_SCOPE_KEY]) &&
|
|
1743
1785
|
// The ZITADEL run options reach the container only through the auth
|
|
1744
1786
|
// step's redeploy, so a platform recorded before them still plans it.
|
|
1745
1787
|
recordedIds[PLATFORM_AUTH_ZITADEL_RUN_OPTIONS_SCOPE_KEY] === AUTH_ZITADEL_RUN_OPTIONS) {
|
|
1746
|
-
return { step: null, blocked:
|
|
1788
|
+
return { step: null, blocked: standingNote };
|
|
1747
1789
|
}
|
|
1748
1790
|
// The admin key was minted but never reached the host. ZITADEL shows a
|
|
1749
1791
|
// token once, so it is lost: minting another would hide that, and skipping
|
|
@@ -1814,6 +1856,7 @@ function planAuth(platform, recordedIds, executorBlocked, executorMissing, authD
|
|
|
1814
1856
|
// 5: and only claim "this apply re-mints" when `otherInputsMissing` is
|
|
1815
1857
|
// actually empty -- see this function's own doc comment.
|
|
1816
1858
|
blocked: executorBlocked ??
|
|
1859
|
+
standingNote ??
|
|
1817
1860
|
loginClientNeedsMintNote(loginClientUndelivered, loginClientApplied, authDrifted, loginClientRecord, otherInputsMissing),
|
|
1818
1861
|
};
|
|
1819
1862
|
}
|
|
@@ -2487,9 +2530,9 @@ function planHeartbeats(platform, recordedIds, hcReady, executorMissing, apiKeyM
|
|
|
2487
2530
|
* destructive step removes whatever of it is recorded (edge removes its KV
|
|
2488
2531
|
* namespace with the script).
|
|
2489
2532
|
*
|
|
2490
|
-
* The returned `blocked` lines are reported in `unmanaged
|
|
2491
|
-
*
|
|
2492
|
-
*
|
|
2533
|
+
* The returned `blocked` lines are reported in `unmanaged`. A secret whose
|
|
2534
|
+
* source does not exist yet blocks nothing: the step still delivers
|
|
2535
|
+
* everything that exists, so it comes back in `notes`.
|
|
2493
2536
|
*/
|
|
2494
2537
|
function planUptime(platform, recordedIds, executorBlocked, heldOptional, archonApplied, uptimeHeld = {
|
|
2495
2538
|
token: true,
|
|
@@ -2507,9 +2550,9 @@ function planUptime(platform, recordedIds, executorBlocked, heldOptional, archon
|
|
|
2507
2550
|
});
|
|
2508
2551
|
if (!uptime.enabled) {
|
|
2509
2552
|
if (!uptimeRecorded(recordedIds))
|
|
2510
|
-
return { step: null, blocked: [] };
|
|
2553
|
+
return { step: null, blocked: [], notes: [] };
|
|
2511
2554
|
if (executorBlocked)
|
|
2512
|
-
return { step: null, blocked: [executorBlocked] };
|
|
2555
|
+
return { step: null, blocked: [executorBlocked], notes: [] };
|
|
2513
2556
|
return {
|
|
2514
2557
|
step: {
|
|
2515
2558
|
action: action({ remove: true }),
|
|
@@ -2520,6 +2563,7 @@ function planUptime(platform, recordedIds, executorBlocked, heldOptional, archon
|
|
|
2520
2563
|
},
|
|
2521
2564
|
},
|
|
2522
2565
|
blocked: [],
|
|
2566
|
+
notes: [],
|
|
2523
2567
|
};
|
|
2524
2568
|
}
|
|
2525
2569
|
if (!uptime.tag || !uptime.sha256) {
|
|
@@ -2528,6 +2572,7 @@ function planUptime(platform, recordedIds, executorBlocked, heldOptional, archon
|
|
|
2528
2572
|
blocked: [
|
|
2529
2573
|
'the uptime Worker is blocked, not planned: no artifact is pinned; declare uptime.tag (an Archon release tag) and uptime.sha256 (the digest of archon-uptime-worker.js at that tag)',
|
|
2530
2574
|
],
|
|
2575
|
+
notes: [],
|
|
2531
2576
|
};
|
|
2532
2577
|
}
|
|
2533
2578
|
if (!archonApplied) {
|
|
@@ -2536,16 +2581,25 @@ function planUptime(platform, recordedIds, executorBlocked, heldOptional, archon
|
|
|
2536
2581
|
blocked: [
|
|
2537
2582
|
'the uptime Worker is blocked, not planned: platform:archon has not been applied yet',
|
|
2538
2583
|
],
|
|
2584
|
+
notes: [],
|
|
2539
2585
|
};
|
|
2540
2586
|
}
|
|
2541
2587
|
if (executorBlocked)
|
|
2542
|
-
return { step: null, blocked: [executorBlocked] };
|
|
2543
|
-
const
|
|
2588
|
+
return { step: null, blocked: [executorBlocked], notes: [] };
|
|
2589
|
+
const notes = [];
|
|
2544
2590
|
if (!heldOptional.includes('CHAT_ACCESS_TOKEN')) {
|
|
2545
|
-
|
|
2591
|
+
notes.push({
|
|
2592
|
+
key: 'uptime:CHAT_ACCESS_TOKEN',
|
|
2593
|
+
service: 'uptime',
|
|
2594
|
+
description: `the uptime Worker has no chat credential (CHAT_ACCESS_TOKEN): hold one under ${PLATFORM_UPTIME_CHAT_TOKEN_REF} and it is set on the next apply; until then it sends no chat alerts`,
|
|
2595
|
+
});
|
|
2546
2596
|
}
|
|
2547
2597
|
if (!heldOptional.includes('MAIL_API_KEY')) {
|
|
2548
|
-
|
|
2598
|
+
notes.push({
|
|
2599
|
+
key: 'uptime:MAIL_API_KEY',
|
|
2600
|
+
service: 'uptime',
|
|
2601
|
+
description: `the uptime Worker has no mail API key (MAIL_API_KEY): hold one under ${PLATFORM_UPTIME_MAIL_KEY_REF} and it is set on the next apply; until then it sends no alert email`,
|
|
2602
|
+
});
|
|
2549
2603
|
}
|
|
2550
2604
|
const hostname = platform.archon.hostname;
|
|
2551
2605
|
// Applied only once a run got to its end and recorded these: a Worker that
|
|
@@ -2561,7 +2615,7 @@ function planUptime(platform, recordedIds, executorBlocked, heldOptional, archon
|
|
|
2561
2615
|
(recordedIds[PLATFORM_UPTIME_APPLIED_VARS_SCOPE_KEY] ?? '') === uptimeHeld.vars &&
|
|
2562
2616
|
recordedIds[PLATFORM_UPTIME_APPLIED_SECRETS_SCOPE_KEY] === uptimeSecretNames(heldOptional);
|
|
2563
2617
|
if (applied)
|
|
2564
|
-
return { step: null, blocked:
|
|
2618
|
+
return { step: null, blocked: [], notes };
|
|
2565
2619
|
return {
|
|
2566
2620
|
step: {
|
|
2567
2621
|
action: action({ hostname, gitRef: uptime.tag, sha256: uptime.sha256 }),
|
|
@@ -2571,7 +2625,8 @@ function planUptime(platform, recordedIds, executorBlocked, heldOptional, archon
|
|
|
2571
2625
|
migrates: false,
|
|
2572
2626
|
},
|
|
2573
2627
|
},
|
|
2574
|
-
blocked:
|
|
2628
|
+
blocked: [],
|
|
2629
|
+
notes,
|
|
2575
2630
|
};
|
|
2576
2631
|
}
|
|
2577
2632
|
/**
|
|
@@ -2709,8 +2764,8 @@ function planArchon(platform, recordedIds, executorBlocked, authReady, drifted,
|
|
|
2709
2764
|
Boolean(recordedIds[PLATFORM_ARCHON_APPLIED_BROKER_SCOPE_KEY]) &&
|
|
2710
2765
|
recordedIds[PLATFORM_ARCHON_APPLIED_BROKER_SCOPE_KEY] ===
|
|
2711
2766
|
recordedIds[PLATFORM_AUTH_BROKER_SCOPE_KEY] &&
|
|
2712
|
-
|
|
2713
|
-
(
|
|
2767
|
+
recordedIds[PLATFORM_ARCHON_APPLIED_AUTH_ORG_SCOPE_KEY] ===
|
|
2768
|
+
archonAuthOrganizationId(recordedIds) &&
|
|
2714
2769
|
// #475: a platform applied before the rolling-update fix keeps planning
|
|
2715
2770
|
// this step until a confirmed redeploy has cleared it. #480: this marker
|
|
2716
2771
|
// alone does not catch the live app's settings changing back afterward
|
|
@@ -2775,3 +2830,12 @@ function planArchon(platform, recordedIds, executorBlocked, authReady, drifted,
|
|
|
2775
2830
|
blocked: null,
|
|
2776
2831
|
};
|
|
2777
2832
|
}
|
|
2833
|
+
/** The blocked text for a refused owner-org sign-in domain, while it is recorded and not yet primary. */
|
|
2834
|
+
function ownerDomainBlockedText(recordedIds) {
|
|
2835
|
+
const blockedDomain = recordedIds[PLATFORM_OWNER_ORG_DOMAIN_BLOCKED_SCOPE_KEY];
|
|
2836
|
+
if (!blockedDomain)
|
|
2837
|
+
return null;
|
|
2838
|
+
if (recordedIds[PLATFORM_OWNER_ORG_DOMAIN_SCOPE_KEY] === blockedDomain)
|
|
2839
|
+
return null;
|
|
2840
|
+
return signInDomainBlockedText('the platform owner', blockedDomain).replace(ZITADEL_ORG_DOMAIN_BLOCKED_SCOPE_KEY, PLATFORM_OWNER_ORG_DOMAIN_BLOCKED_SCOPE_KEY);
|
|
2841
|
+
}
|
|
@@ -61,6 +61,8 @@ export interface OrgPlatformReadiness {
|
|
|
61
61
|
* while `MAIL_DOMAIN_SCOPE_KEY` was still recorded as the apex.
|
|
62
62
|
*/
|
|
63
63
|
platformApex: string | null;
|
|
64
|
+
/** `DeclaredPlatform.ownerOrgId`, or `null` when no platform is declared or it is empty. The one fact "this is the platform's own org" rests on. */
|
|
65
|
+
platformOwnerOrgId: string | null;
|
|
64
66
|
/** `DeclaredPlatform.mail.lettermintProjectId`, `null` when undeclared or when no platform is declared. See {@link platformApex}'s own doc comment for why this is unconditional too. */
|
|
65
67
|
platformLettermintProjectId: string | null;
|
|
66
68
|
/** The files host (#171). Files is always on for every org (#80), so `false` always blocks rather than only mattering when a flag is set. */
|
|
@@ -27,6 +27,7 @@ export const NO_DOMAIN_MAIL_APEX = 'oikos.host';
|
|
|
27
27
|
export const DEFAULT_ORG_PLATFORM_READINESS = {
|
|
28
28
|
mailHost: null,
|
|
29
29
|
platformApex: null,
|
|
30
|
+
platformOwnerOrgId: null,
|
|
30
31
|
platformLettermintProjectId: null,
|
|
31
32
|
filesReady: false,
|
|
32
33
|
aiReady: false,
|
|
@@ -124,6 +125,7 @@ edgePortPresent = false) {
|
|
|
124
125
|
// mail.lettermintProjectId are facts regardless of whether mail itself is
|
|
125
126
|
// enabled or applied.
|
|
126
127
|
platformApex: platform.apex,
|
|
128
|
+
platformOwnerOrgId: platform.ownerOrgId || null,
|
|
127
129
|
platformLettermintProjectId: platform.mail.lettermintProjectId ?? null,
|
|
128
130
|
filesReady: filesApplied && missingKeys.files === null,
|
|
129
131
|
filesUrl: filesApplied
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CloudflareClient } from '@wtfalch/providers/cloudflare';
|
|
2
|
-
import type
|
|
2
|
+
import { type DeclaredOrg } from '../org.js';
|
|
3
3
|
import type { DeclaredPlatform } from '../platform.js';
|
|
4
4
|
import type { DeclaredOrgStore, PlatformStore } from '../store.js';
|
|
5
5
|
import { type DeployHealthRuntime } from './deploy-health.js';
|
|
@@ -11,6 +11,7 @@ import type { CloudflarePort, CoolifyPort, FoundryStepExecutorPorts, ZitadelPort
|
|
|
11
11
|
import type { LiveResource, PlatformCloudflareReader, PlatformCoolifyReader } from './live.js';
|
|
12
12
|
import type { PlatformDriftedSteps, PlatformStepExecutionContext, PlatformStepExecutor } from './plan-apply.js';
|
|
13
13
|
import { type BrokerDeployRecord, PLATFORM_ZITADEL_ORG_SCOPE_KEY } from './platform-diff.js';
|
|
14
|
+
export { PLATFORM_ZITADEL_ORG_SCOPE_KEY };
|
|
14
15
|
import { type CallsSfuPlatformDeps } from './platform-sfu.js';
|
|
15
16
|
import { type PlatformUptimeDeps } from './uptime-worker.js';
|
|
16
17
|
/**
|
|
@@ -90,7 +91,14 @@ export interface PlatformAuthDeps {
|
|
|
90
91
|
tunnels: PlatformTunnelsFactory;
|
|
91
92
|
cloudflare: Pick<CloudflarePort, 'findZoneByApex'>;
|
|
92
93
|
/** Must target the platform's own new instance (its issuer), or `zitadelForInstance` must be set. */
|
|
93
|
-
zitadel: Pick<ZitadelPort, 'findOrCreateOrg' | 'mintAdminMachineUser' | 'mintLoginClientMachineUser' | 'listLoginClientPats' | 'reserveUserName' | 'closeSelfRegistration' | 'inviteOrgOwner'> & PlatformZitadelSmtp;
|
|
94
|
+
zitadel: Pick<ZitadelPort, 'findOrCreateOrg' | 'mintAdminMachineUser' | 'mintLoginClientMachineUser' | 'listLoginClientPats' | 'reserveUserName' | 'closeSelfRegistration' | 'inviteOrgOwner' | 'addOrgDomain' | 'setPrimaryOrgDomain' | 'setUserMetadata' | 'getUserMetadata'> & PlatformZitadelSmtp;
|
|
95
|
+
/**
|
|
96
|
+
* Mails the owner's first-sign-in link to their personal address (the same
|
|
97
|
+
* port as `FoundryStepExecutorPorts.ownerInviteMail`). The link carries the
|
|
98
|
+
* invite code, so `send` must not log it or put it in an error. Without it
|
|
99
|
+
* the owner invite cannot run and the step stops there with a fixed message.
|
|
100
|
+
*/
|
|
101
|
+
ownerInviteMail?: FoundryStepExecutorPorts['ownerInviteMail'];
|
|
94
102
|
/**
|
|
95
103
|
* Builds the ZITADEL port for the new instance from its issuer URL
|
|
96
104
|
* (`https://<auth.hostname>`). When set it is used instead of
|
|
@@ -315,6 +323,7 @@ export declare class FoundryPlatformStepExecutor implements PlatformStepExecutor
|
|
|
315
323
|
auth?: string;
|
|
316
324
|
authExecutorMissing?: boolean;
|
|
317
325
|
authOtherInputsMissing?: string[];
|
|
326
|
+
authOwnerInvite?: string;
|
|
318
327
|
files?: string;
|
|
319
328
|
integrations?: string;
|
|
320
329
|
ai?: string;
|
|
@@ -520,12 +529,51 @@ export interface PlatformMailRuntime {
|
|
|
520
529
|
/** Tries at handing the admin key to the host (default 3). */
|
|
521
530
|
deliverAttempts?: number;
|
|
522
531
|
}
|
|
532
|
+
/**
|
|
533
|
+
* #211: the broker cannot start without `ZITADEL_SERVICE_USER_TOKEN`/`_FILE`,
|
|
534
|
+
* `LETTERMINT_API_TOKEN` and `AUTH_APPS`. `provisionPlatformAuth` already
|
|
535
|
+
* skips deploying the broker while any is missing
|
|
536
|
+
* ({@link missingBrokerInputs}); this is the same check surfaced through
|
|
537
|
+
* `blockedSteps`, so a plan says why, by name, rather than the broker simply
|
|
538
|
+
* sitting undeployed with no explanation. `null` while there is no broker
|
|
539
|
+
* app id recorded yet (nothing to check) or every input is present.
|
|
540
|
+
*
|
|
541
|
+
* #211 round 3: wraps the live read the way {@link mailBlockedReason} wraps
|
|
542
|
+
* its own Coolify call -- a transient `listEnvs` failure must report a
|
|
543
|
+
* blocked reason naming the broker app id, never throw out of
|
|
544
|
+
* `blockedSteps` and take the rest of the plan down with it.
|
|
545
|
+
*
|
|
546
|
+
* #211 round 5 addendum: when `AUTH_APPS` is the reason, names which problem
|
|
547
|
+
* it actually is ({@link authAppsProblem}) instead of always saying "it has
|
|
548
|
+
* no ... AUTH_APPS yet" -- that wording is only true when nothing has been
|
|
549
|
+
* set; a present-but-invalid value is a different failure (a person needs to
|
|
550
|
+
* go fix an entry, not merely wait for one of #209/#210/Archon's own
|
|
551
|
+
* registration to supply one), and reporting it identically hid which one
|
|
552
|
+
* was true.
|
|
553
|
+
*
|
|
554
|
+
* #210: `LETTERMINT_API_TOKEN` joins `ZITADEL_SERVICE_USER_TOKEN` in being
|
|
555
|
+
* excluded from `otherInputsMissing` -- but only while `auth.heldKeys`
|
|
556
|
+
* actually resolves {@link PLATFORM_AUTH_BROKER_MAIL_KEY_REF} right now.
|
|
557
|
+
* `planAuth`'s own "loop fix" stops planning this step the moment every
|
|
558
|
+
* `otherInputsMissing` entry looks like something only another run can
|
|
559
|
+
* supply; excluding `LETTERMINT_API_TOKEN` unconditionally (the way
|
|
560
|
+
* `ZITADEL_SERVICE_USER_TOKEN` is, since foundry can always eventually mint
|
|
561
|
+
* that one) would keep the step planned, and `provisionPlatformAuth`
|
|
562
|
+
* running its full body, forever on a host that never wires `heldKeys` or
|
|
563
|
+
* whose operator has not put a Lettermint key there yet -- exactly the
|
|
564
|
+
* wasteful-replan bug #211 round 5 fixed for the broker deploy itself. Once
|
|
565
|
+
* the key *is* held, excluding it lets this run's `provisionPlatformAuth`
|
|
566
|
+
* push it (see that function's own `heldMailKey` read) and clears the gap
|
|
567
|
+
* for good.
|
|
568
|
+
*/
|
|
569
|
+
/** Why the platform owner cannot be invited yet, or `null`. Fixed text: names no address. */
|
|
570
|
+
export declare function ownerInviteBlockedReason(ownerCompany: DeclaredOrg | null, hasInviteMail: boolean): string | null;
|
|
523
571
|
/**
|
|
524
572
|
* #175: everything {@link provisionPlatformArchon} needs beyond
|
|
525
573
|
* {@link PlatformStepExecutionContext}, bundled like {@link PlatformAuthDeps}.
|
|
526
574
|
*/
|
|
527
575
|
export interface PlatformArchonDeps {
|
|
528
|
-
coolify: Pick<CoolifyPort, 'findProjectByName' | 'createProject' | 'findOrCreateEnvironment' | 'listServers' | 'findApplicationByName' | 'getApplication' | 'requireGithubApp' | 'createGithubAppApplication' | 'createDockerfileApplication' | 'listDatabases' | 'createPostgresDatabase' | 'getDatabase' | 'raw' | 'bulkUpsertEnvs' | 'listEnvs' | 'deleteEnv' | 'updateApplication' | 'deploy' | 'deployAndWait' | 'getDeployment'>;
|
|
576
|
+
coolify: Pick<CoolifyPort, 'findProjectByName' | 'listEnvironments' | 'createProject' | 'findOrCreateEnvironment' | 'listServers' | 'findApplicationByName' | 'getApplication' | 'requireGithubApp' | 'createGithubAppApplication' | 'createDockerfileApplication' | 'listDatabases' | 'createPostgresDatabase' | 'getDatabase' | 'raw' | 'bulkUpsertEnvs' | 'listEnvs' | 'deleteEnv' | 'updateApplication' | 'deploy' | 'deployAndWait' | 'getDeployment'>;
|
|
529
577
|
/** F4.dns: every DNS record call, through edge at its recorded address (see {@link PlatformDnsFactory}). */
|
|
530
578
|
dns: PlatformDnsFactory;
|
|
531
579
|
/** F4.tunnels: every tunnel call, through edge at its recorded address (see {@link PlatformTunnelsFactory}). */
|
|
@@ -604,7 +652,6 @@ export interface PlatformArchonRuntime {
|
|
|
604
652
|
* org (`foundry:<orgId>`), with the platform's step key in the org id's place.
|
|
605
653
|
*/
|
|
606
654
|
export declare const PLATFORM_ARCHON_ACCESS_APP_NAME = "foundry:platform:archon";
|
|
607
|
-
export { PLATFORM_ZITADEL_ORG_SCOPE_KEY };
|
|
608
655
|
/** Archon's OIDC client id: public, not a secret, so a plain scope id. */
|
|
609
656
|
export declare const PLATFORM_ARCHON_CLIENT_ID_SCOPE_KEY = "zitadel_platform_archon_client_id";
|
|
610
657
|
/**
|