typekro 0.38.2 → 0.39.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/dist/.tsbuildinfo +1 -1
- package/dist/factories/clickstack/compositions/clickstack-bootstrap.d.ts +29 -2
- package/dist/factories/clickstack/compositions/clickstack-bootstrap.d.ts.map +1 -1
- package/dist/factories/clickstack/compositions/clickstack-bootstrap.js +298 -46
- package/dist/factories/clickstack/compositions/clickstack-bootstrap.js.map +1 -1
- package/dist/factories/clickstack/hyperdx-oidc/index.d.ts +2 -2
- package/dist/factories/clickstack/hyperdx-oidc/index.d.ts.map +1 -1
- package/dist/factories/clickstack/hyperdx-oidc/index.js +25 -8
- package/dist/factories/clickstack/hyperdx-oidc/index.js.map +1 -1
- package/dist/factories/clickstack/hyperdx-oidc/plugin-bundle.generated.d.ts.map +1 -1
- package/dist/factories/clickstack/hyperdx-oidc/plugin-bundle.generated.js +4 -4
- package/dist/factories/clickstack/hyperdx-oidc/plugin-bundle.generated.js.map +1 -1
- package/dist/factories/clickstack/types.d.ts +106 -1
- package/dist/factories/clickstack/types.d.ts.map +1 -1
- package/dist/factories/clickstack/types.js +123 -1
- package/dist/factories/clickstack/types.js.map +1 -1
- package/dist/factories/clickstack/utils/helm-values-mapper.d.ts +71 -2
- package/dist/factories/clickstack/utils/helm-values-mapper.d.ts.map +1 -1
- package/dist/factories/clickstack/utils/helm-values-mapper.js +112 -111
- package/dist/factories/clickstack/utils/helm-values-mapper.js.map +1 -1
- package/dist/factories/clickstack/utils/team-defaults.d.ts +87 -0
- package/dist/factories/clickstack/utils/team-defaults.d.ts.map +1 -0
- package/dist/factories/clickstack/utils/team-defaults.js +462 -0
- package/dist/factories/clickstack/utils/team-defaults.js.map +1 -0
- package/package.json +2 -1
|
@@ -76,6 +76,28 @@
|
|
|
76
76
|
* ```
|
|
77
77
|
*/
|
|
78
78
|
import { type ClickStackInlineExternalMongoBuildOptions, type ClickStackInlineInternalMongoBuildOptions, type ClickStackSecretValuesExternalMongoBuildOptions, type ClickStackSecretValuesInternalMongoBuildOptions, type ResolvedClickStackInitialUser } from '../types.js';
|
|
79
|
+
/**
|
|
80
|
+
* Suffix of the `secretValues`-mode ConfigMap carrying HyperDX's default
|
|
81
|
+
* connection values (`<release>-default-connections`).
|
|
82
|
+
*/
|
|
83
|
+
export declare const CLICKSTACK_DEFAULT_CONNECTIONS_CONFIGMAP_SUFFIX = "-default-connections";
|
|
84
|
+
/** Build-time choices both Team-bootstrap scripts render in. */
|
|
85
|
+
export interface ClickStackTeamBootstrapScriptOptions {
|
|
86
|
+
/** Team name to reconcile; `undefined` leaves the name alone. */
|
|
87
|
+
teamName?: string;
|
|
88
|
+
/** Seed an empty Team's connection and sources (default `true`). */
|
|
89
|
+
teamDefaults?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Chart versions the seed checks the runtime version against (default: the
|
|
92
|
+
* audited list); `null` skips the check (`allowUnvalidatedChartVersion`).
|
|
93
|
+
*/
|
|
94
|
+
seedChartVersions?: readonly string[] | null;
|
|
95
|
+
/**
|
|
96
|
+
* @internal Hashes of legacy default names the degraded path may rename
|
|
97
|
+
* (default {@link CLICKSTACK_LEGACY_TEAM_NAME_SHA256}); for tests.
|
|
98
|
+
*/
|
|
99
|
+
legacyTeamNameHashes?: readonly string[];
|
|
100
|
+
}
|
|
79
101
|
/**
|
|
80
102
|
* Render the mongosh script the bootstrap CronJob runs.
|
|
81
103
|
*
|
|
@@ -91,7 +113,7 @@ import { type ClickStackInlineExternalMongoBuildOptions, type ClickStackInlineIn
|
|
|
91
113
|
* WHAT TYPEKRO USED TO DO TO IT. Creating the Team directly, to pre-seed the
|
|
92
114
|
* ingestion key, spends the registration without producing the account: one
|
|
93
115
|
* Team, zero users, a login page nobody can satisfy, and no connections or
|
|
94
|
-
* sources either (#227).
|
|
116
|
+
* sources either (#227). The degraded script is that
|
|
95
117
|
* behaviour, kept for compatibility and documented as degraded.
|
|
96
118
|
*
|
|
97
119
|
* WHAT IT DOES NOW, WITH `initialUser`. It spends the registration the way
|
|
@@ -136,11 +158,16 @@ import { type ClickStackInlineExternalMongoBuildOptions, type ClickStackInlineIn
|
|
|
136
158
|
* and the HyperDX API may still be starting, so a connection failure is
|
|
137
159
|
* reported as the transient it is, in those words, instead of as a stack
|
|
138
160
|
* trace that reads like a broken deployment.
|
|
161
|
+
* 6. TEAM NAME AND DEFAULTS, ON BOTH PATHS. `reconcileTeamName` and
|
|
162
|
+
* `seedTeamDefaults` (utils/team-defaults.ts) rename the Team unless a
|
|
163
|
+
* human renamed it after TypeKro did, and seed the connection and sources
|
|
164
|
+
* once into a Team that has neither. Neither ever overwrites a document.
|
|
139
165
|
*
|
|
140
166
|
* @param initialUser - The resolved build-time option, or `undefined`
|
|
167
|
+
* @param options - Team name and defaults (see {@link ClickStackTeamBootstrapScriptOptions})
|
|
141
168
|
* @returns The complete `--eval` script
|
|
142
169
|
*/
|
|
143
|
-
export declare function renderClickStackTeamBootstrapScript(initialUser?: ResolvedClickStackInitialUser): string;
|
|
170
|
+
export declare function renderClickStackTeamBootstrapScript(initialUser?: ResolvedClickStackInitialUser, options?: ClickStackTeamBootstrapScriptOptions): string;
|
|
144
171
|
declare function buildInternalInlineComposition(options: ClickStackInlineInternalMongoBuildOptions): import("../../../index.js").CallableComposition<{
|
|
145
172
|
apiKey: string;
|
|
146
173
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clickstack-bootstrap.d.ts","sourceRoot":"","sources":["../../../../src/factories/clickstack/compositions/clickstack-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AA4BH,OAAO,EASL,KAAK,yCAAyC,EAC9C,KAAK,yCAAyC,EAK9C,KAAK,+CAA+C,EAGpD,KAAK,+CAA+C,EACpD,KAAK,6BAA6B,
|
|
1
|
+
{"version":3,"file":"clickstack-bootstrap.d.ts","sourceRoot":"","sources":["../../../../src/factories/clickstack/compositions/clickstack-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AA4BH,OAAO,EASL,KAAK,yCAAyC,EAC9C,KAAK,yCAAyC,EAK9C,KAAK,+CAA+C,EAGpD,KAAK,+CAA+C,EACpD,KAAK,6BAA6B,EAiBnC,MAAM,aAAa,CAAC;AAgFrB;;;GAGG;AACH,eAAO,MAAM,+CAA+C,yBAAyB,CAAC;AA2GtF,gEAAgE;AAChE,MAAM,WAAW,oCAAoC;IACnD,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC7C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAqED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,wBAAgB,mCAAmC,CACjD,WAAW,CAAC,EAAE,6BAA6B,EAC3C,OAAO,GAAE,oCAAyC,GACjD,MAAM,CA8HR;AAy8BD,iBAAS,8BAA8B,CAAC,OAAO,EAAE,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAYzF;AAED,iBAAS,oCAAoC,CAC3C,OAAO,EAAE,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgBzD;AAED,iBAAS,8BAA8B,CAAC,OAAO,EAAE,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAYzF;AAED,iBAAS,oCAAoC,CAC3C,OAAO,EAAE,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgBzD;AAED,uDAAuD;AACvD,MAAM,MAAM,8BAA8B,GAAG,UAAU,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAE/F,qEAAqE;AACrE,MAAM,MAAM,0CAA0C,GAAG,UAAU,CACjE,OAAO,oCAAoC,CAC5C,CAAC;AAEF,uDAAuD;AACvD,MAAM,MAAM,2CAA2C,GAAG,UAAU,CAClE,OAAO,8BAA8B,CACtC,CAAC;AAEF,qEAAqE;AACrE,MAAM,MAAM,uDAAuD,GAAG,UAAU,CAC9E,OAAO,oCAAoC,CAC5C,CAAC;AAoBF;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,CAAC,EAAE,yCAAyC,GAClD,8BAA8B,CAAC;AAClC,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,+CAA+C,GACvD,0CAA0C,CAAC;AAC9C,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,yCAAyC,GACjD,2CAA2C,CAAC;AAC/C,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,+CAA+C,GACvD,uDAAuD,CAAC;AAkD3D;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA4B,CAAC"}
|
|
@@ -88,12 +88,18 @@ import { persistentVolumeClaim } from '../../kubernetes/storage/persistent-volum
|
|
|
88
88
|
import { cronJob } from '../../kubernetes/workloads/cron-job.js';
|
|
89
89
|
import { CLICKSTACK_API_PORT, CLICKSTACK_APP_PORT, CLICKSTACK_GATEWAY_NAME_SUFFIX, CLICKSTACK_OTLP_GRPC_PORT, CLICKSTACK_OTLP_HTTP_PORT, clickstackHelmRelease, DEFAULT_CLICKSTACK_REPO_NAME, DEFAULT_CLICKSTACK_REPO_URL, DEFAULT_CLICKSTACK_VERSION, } from '../resources/helm.js';
|
|
90
90
|
import { clickstackMongoService, clickstackMongoStatefulSet } from '../resources/mongo.js';
|
|
91
|
-
import { ClickStackBootstrapConfigSchema, ClickStackBootstrapStatusSchema, ClickStackExternalMongoBootstrapConfigSchema, ClickStackSecretValuesBootstrapConfigSchema, ClickStackSecretValuesExternalMongoBootstrapConfigSchema, assertClickStackReleaseName, CLICKSTACK_BOOTSTRAP_MARKER_COLLECTION, CLICKSTACK_CONTRACT_CONFIGMAP_SUFFIX, CLICKSTACK_INITIAL_USER_API_BASE_URL_ENV, CLICKSTACK_INITIAL_USER_MARKER_ID, CLICKSTACK_INITIAL_USER_VALIDATED_APP_VERSION, CLICKSTACK_INITIAL_USER_VALIDATED_CHART_VERSIONS, CLICKSTACK_RETENTION_NAME_SUFFIX, CLICKSTACK_TEAM_BOOTSTRAP_NAME_SUFFIX, clickStackInitialUserVersionValidationRule, isClickStackInitialUserValidatedChartVersion, resolveClickStackInitialUser, } from '../types.js';
|
|
92
|
-
import { DEFAULT_CLICKSTACK_NAMESPACE, mapClickStackConfigToHelmValues, } from '../utils/helm-values-mapper.js';
|
|
91
|
+
import { ClickStackBootstrapConfigSchema, ClickStackBootstrapStatusSchema, ClickStackExternalMongoBootstrapConfigSchema, ClickStackSecretValuesBootstrapConfigSchema, ClickStackSecretValuesExternalMongoBootstrapConfigSchema, assertClickStackReleaseName, CLICKSTACK_BOOTSTRAP_MARKER_COLLECTION, CLICKSTACK_CLICKHOUSE_HOST_VALIDATION_RULE, CLICKSTACK_CONTRACT_CONFIGMAP_SUFFIX, CLICKSTACK_INITIAL_USER_API_BASE_URL_ENV, CLICKSTACK_INITIAL_USER_MARKER_ID, CLICKSTACK_INITIAL_USER_VALIDATED_APP_VERSION, CLICKSTACK_INITIAL_USER_VALIDATED_CHART_VERSIONS, CLICKSTACK_RETENTION_NAME_SUFFIX, CLICKSTACK_TEAM_BOOTSTRAP_NAME_SUFFIX, clickStackInitialUserVersionValidationRule, DEFAULT_CLICKSTACK_TEAM_NAME, resolveClickStackTeamName, validateClickStackClickhouseHost, isClickStackInitialUserValidatedChartVersion, resolveClickStackInitialUser, } from '../types.js';
|
|
92
|
+
import { CLICKSTACK_DEFAULT_CONNECTIONS_VALUES_KEY, clickStackDefaultConnectionTarget, CLICKSTACK_SECRET_VALUES_DEFAULT_CONNECTIONS_DOCUMENT, DEFAULT_CLICKSTACK_NAMESPACE, mapClickStackConfigToHelmValues, } from '../utils/helm-values-mapper.js';
|
|
93
|
+
import { CLICKSTACK_APP_PASSWORD_SECRET_KEY, CLICKSTACK_CHART_VERSION_ENV, HYPERDX_DEFAULT_CONNECTION_HOST_ENV, HYPERDX_DEFAULT_CONNECTION_PASSWORD_ENV, HYPERDX_DEFAULT_CONNECTION_USERNAME_ENV, HYPERDX_DEFAULT_SOURCES_DATABASE_ENV, CLICKSTACK_LEGACY_TEAM_NAME_SHA256, renderTeamBootstrapHelpers, } from '../utils/team-defaults.js';
|
|
93
94
|
import { CLICKSTACK_CONFIG_MAP_NAME, CLICKSTACK_SECRET_NAME, assertQueueReplicaCompatible, clickStackQueueClaimName, renderPersistentQueueClaimSpec, renderRetentionScript, resolveClickStackStorage, } from '../utils/storage.js';
|
|
94
95
|
import { applyHyperdxOidcValues, CLICKSTACK_HYPERDX_OIDC_VALIDATED_APP_VERSION, CLICKSTACK_HYPERDX_OIDC_VALIDATED_CHART_VERSIONS, hyperdxOidcPluginConfigMapData, hyperdxOidcPluginConfigMapName, isClickStackHyperdxOidcValidatedChartVersion, resolveClickStackHyperdxOidc, } from '../hyperdx-oidc/index.js';
|
|
95
96
|
import { clickstackHelmRepositoryBootstrap } from './clickstack-helm-repository.js';
|
|
96
97
|
const CLICKSTACK_CHART_PLACEHOLDER_API_KEY = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
|
|
98
|
+
/**
|
|
99
|
+
* Suffix of the `secretValues`-mode ConfigMap carrying HyperDX's default
|
|
100
|
+
* connection values (`<release>-default-connections`).
|
|
101
|
+
*/
|
|
102
|
+
export const CLICKSTACK_DEFAULT_CONNECTIONS_CONFIGMAP_SUFFIX = '-default-connections';
|
|
97
103
|
/**
|
|
98
104
|
* Readiness for the collector queue's PersistentVolumeClaim.
|
|
99
105
|
*
|
|
@@ -173,9 +179,16 @@ const CLICKSTACK_HELM_RELEASE_RESOURCE_ID = 'clickstackHelmRelease';
|
|
|
173
179
|
* @see https://github.com/yehudacohen/typekro/issues/188
|
|
174
180
|
*/
|
|
175
181
|
const CLICKSTACK_CONTRACT_RESOURCE_ID = 'clickstackContract';
|
|
182
|
+
/** Every variant: the host the connection URLs are built from. */
|
|
183
|
+
const hostSchemaFieldValidations = {
|
|
184
|
+
'clickhouse.host': CLICKSTACK_CLICKHOUSE_HOST_VALIDATION_RULE,
|
|
185
|
+
};
|
|
176
186
|
const inlineSchemaFieldValidations = {
|
|
187
|
+
...hostSchemaFieldValidations,
|
|
177
188
|
apiKey: `self != "${CLICKSTACK_CHART_PLACEHOLDER_API_KEY}"`,
|
|
178
189
|
};
|
|
190
|
+
/** The Team the degraded script creates, and so the one it may rename and seed. */
|
|
191
|
+
const CLICKSTACK_MANAGED_TEAM_HOOK_ID = 'typekro-managed-ingestion';
|
|
179
192
|
/**
|
|
180
193
|
* The DEGRADED script: reconcile the ingestion key by creating the Team
|
|
181
194
|
* outright. Rendered only when `initialUser` is NOT configured.
|
|
@@ -189,33 +202,54 @@ const inlineSchemaFieldValidations = {
|
|
|
189
202
|
* (#227). This path exists because it is what shipped, and removing it would
|
|
190
203
|
* break deployments whose ingestion key is already converged; it is not the
|
|
191
204
|
* supported way to run the composition. Configure `initialUser`.
|
|
205
|
+
*
|
|
206
|
+
* A Team inserted here also skips HyperDX's `setupTeamDefaults`, so the script
|
|
207
|
+
* seeds its connection and sources itself (see `utils/team-defaults.ts`).
|
|
192
208
|
*/
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
'
|
|
218
|
-
|
|
209
|
+
function renderDegradedTeamBootstrapScript(teamName, teamDefaults, legacyTeamNameHashes, seedChartVersions) {
|
|
210
|
+
return [
|
|
211
|
+
"const database = db.getSiblingDB('hyperdx');",
|
|
212
|
+
`const bootstrapMarkers = database.${CLICKSTACK_BOOTSTRAP_MARKER_COLLECTION};`,
|
|
213
|
+
'const apiKey = process.env.HYPERDX_API_KEY;',
|
|
214
|
+
"if (typeof apiKey !== 'string' || apiKey.trim().length === 0) throw new Error('HYPERDX_API_KEY is required.');",
|
|
215
|
+
`if (apiKey === '${CLICKSTACK_CHART_PLACEHOLDER_API_KEY}') throw new Error('HYPERDX_API_KEY must override the published ClickStack chart placeholder.');`,
|
|
216
|
+
...renderTeamBootstrapHelpers({
|
|
217
|
+
seed: teamDefaults,
|
|
218
|
+
untouchedName: { sha256: legacyTeamNameHashes },
|
|
219
|
+
...(seedChartVersions !== undefined && { validatedChartVersions: seedChartVersions }),
|
|
220
|
+
}),
|
|
221
|
+
`const hookId = '${CLICKSTACK_MANAGED_TEAM_HOOK_ID}';`,
|
|
222
|
+
`const teamName = ${JSON.stringify(teamName)};`,
|
|
223
|
+
'const teams = database.teams.find({ hookId }).toArray();',
|
|
224
|
+
"if (teams.length > 1) throw new Error('Multiple TypeKro-managed ClickStack Teams exist.');",
|
|
225
|
+
'if (teams.length === 0) {',
|
|
226
|
+
' const now = new Date();',
|
|
227
|
+
// Ownership of the name is recorded BEFORE the Team exists, under the id
|
|
228
|
+
// it is about to get, never inferred later from the name. A crash in
|
|
229
|
+
// between leaves an orphan record for an id nothing uses.
|
|
230
|
+
' const teamId = new ObjectId();',
|
|
231
|
+
' recordTeamName(teamId, teamName);',
|
|
232
|
+
' database.teams.insertOne({',
|
|
233
|
+
' _id: teamId,',
|
|
234
|
+
' name: teamName,',
|
|
235
|
+
' allowedAuthMethods: [],',
|
|
236
|
+
' hookId,',
|
|
237
|
+
' apiKey,',
|
|
238
|
+
' collectorAuthenticationEnforced: true,',
|
|
239
|
+
' isMetricsSeriesTableEnabled: false,',
|
|
240
|
+
' createdAt: now,',
|
|
241
|
+
' updatedAt: now,',
|
|
242
|
+
' });',
|
|
243
|
+
'} else if (teams[0].apiKey !== apiKey || teams[0].collectorAuthenticationEnforced !== true) {',
|
|
244
|
+
' database.teams.updateOne({ _id: teams[0]._id }, {',
|
|
245
|
+
' $set: { apiKey, collectorAuthenticationEnforced: true, updatedAt: new Date() },',
|
|
246
|
+
' });',
|
|
247
|
+
'}',
|
|
248
|
+
'const team = database.teams.findOne({ hookId });',
|
|
249
|
+
'reconcileTeamName(team, teamName);',
|
|
250
|
+
'seedTeamDefaults(team, true);',
|
|
251
|
+
].join('\n');
|
|
252
|
+
}
|
|
219
253
|
/**
|
|
220
254
|
* Render the mongosh script the bootstrap CronJob runs.
|
|
221
255
|
*
|
|
@@ -231,7 +265,7 @@ const CLICKSTACK_TEAM_BOOTSTRAP_SCRIPT = [
|
|
|
231
265
|
* WHAT TYPEKRO USED TO DO TO IT. Creating the Team directly, to pre-seed the
|
|
232
266
|
* ingestion key, spends the registration without producing the account: one
|
|
233
267
|
* Team, zero users, a login page nobody can satisfy, and no connections or
|
|
234
|
-
* sources either (#227).
|
|
268
|
+
* sources either (#227). The degraded script is that
|
|
235
269
|
* behaviour, kept for compatibility and documented as degraded.
|
|
236
270
|
*
|
|
237
271
|
* WHAT IT DOES NOW, WITH `initialUser`. It spends the registration the way
|
|
@@ -276,13 +310,23 @@ const CLICKSTACK_TEAM_BOOTSTRAP_SCRIPT = [
|
|
|
276
310
|
* and the HyperDX API may still be starting, so a connection failure is
|
|
277
311
|
* reported as the transient it is, in those words, instead of as a stack
|
|
278
312
|
* trace that reads like a broken deployment.
|
|
313
|
+
* 6. TEAM NAME AND DEFAULTS, ON BOTH PATHS. `reconcileTeamName` and
|
|
314
|
+
* `seedTeamDefaults` (utils/team-defaults.ts) rename the Team unless a
|
|
315
|
+
* human renamed it after TypeKro did, and seed the connection and sources
|
|
316
|
+
* once into a Team that has neither. Neither ever overwrites a document.
|
|
279
317
|
*
|
|
280
318
|
* @param initialUser - The resolved build-time option, or `undefined`
|
|
319
|
+
* @param options - Team name and defaults (see {@link ClickStackTeamBootstrapScriptOptions})
|
|
281
320
|
* @returns The complete `--eval` script
|
|
282
321
|
*/
|
|
283
|
-
export function renderClickStackTeamBootstrapScript(initialUser) {
|
|
284
|
-
|
|
285
|
-
|
|
322
|
+
export function renderClickStackTeamBootstrapScript(initialUser, options = {}) {
|
|
323
|
+
const teamDefaults = options.teamDefaults ?? true;
|
|
324
|
+
const seedChartVersions = options.seedChartVersions === null
|
|
325
|
+
? undefined
|
|
326
|
+
: (options.seedChartVersions ?? CLICKSTACK_INITIAL_USER_VALIDATED_CHART_VERSIONS);
|
|
327
|
+
if (initialUser === undefined) {
|
|
328
|
+
return renderDegradedTeamBootstrapScript(options.teamName ?? DEFAULT_CLICKSTACK_TEAM_NAME, teamDefaults, options.legacyTeamNameHashes ?? [CLICKSTACK_LEGACY_TEAM_NAME_SHA256], seedChartVersions);
|
|
329
|
+
}
|
|
286
330
|
const passwordVar = initialUser.passwordEnvVarName;
|
|
287
331
|
// mongosh resolves a promise returned by the LAST expression of `--eval` and
|
|
288
332
|
// exits non-zero when it rejects, but it does NOT accept top-level `await`.
|
|
@@ -301,6 +345,18 @@ export function renderClickStackTeamBootstrapScript(initialUser) {
|
|
|
301
345
|
// TypeKro's OWN state, in TypeKro's OWN collection — not an extra field on
|
|
302
346
|
// an upstream-owned team or user document.
|
|
303
347
|
` const bootstrapMarkers = database.${CLICKSTACK_BOOTSTRAP_MARKER_COLLECTION};`,
|
|
348
|
+
// A Team HyperDX's registration created is named `<email>'s Team`, and
|
|
349
|
+
// one that still is has never been renamed by a human. So has a Team
|
|
350
|
+
// still carrying the legacy default, from a deployment that ran the
|
|
351
|
+
// degraded path before initialUser was configured.
|
|
352
|
+
...renderTeamBootstrapHelpers({
|
|
353
|
+
seed: teamDefaults,
|
|
354
|
+
untouchedName: {
|
|
355
|
+
exact: `${initialUser.email}'s Team`,
|
|
356
|
+
sha256: options.legacyTeamNameHashes ?? [CLICKSTACK_LEGACY_TEAM_NAME_SHA256],
|
|
357
|
+
},
|
|
358
|
+
...(seedChartVersions !== undefined && { validatedChartVersions: seedChartVersions }),
|
|
359
|
+
}).map((line) => ` ${line}`),
|
|
304
360
|
` const initialUserMarkerId = ${JSON.stringify(CLICKSTACK_INITIAL_USER_MARKER_ID)};`,
|
|
305
361
|
// Marker present => the instance was claimed under TypeKro's watch. Short
|
|
306
362
|
// -circuit BEFORE looking at teams, the password, or the network at all.
|
|
@@ -366,6 +422,17 @@ export function renderClickStackTeamBootstrapScript(initialUser) {
|
|
|
366
422
|
' $set: { apiKey, collectorAuthenticationEnforced: true, updatedAt: new Date() },',
|
|
367
423
|
' });',
|
|
368
424
|
' }',
|
|
425
|
+
// HyperDX named this Team at registration; rename it only when asked to.
|
|
426
|
+
...(options.teamName === undefined
|
|
427
|
+
? []
|
|
428
|
+
: [` reconcileTeamName(teams[0], ${JSON.stringify(options.teamName)});`]),
|
|
429
|
+
// Registration already ran setupTeamDefaults, so this normally finds the
|
|
430
|
+
// defaults in place and records that. It fills an empty Team: one from
|
|
431
|
+
// before initialUser was configured, or one whose defaults HyperDX failed
|
|
432
|
+
// to set up (it logs that and carries on).
|
|
433
|
+
// `false`: this path never creates the Team, so a new one is HyperDX's and
|
|
434
|
+
// gets the grace period (a Team from the degraded path is long past it).
|
|
435
|
+
' seedTeamDefaults(teams[0], false);',
|
|
369
436
|
" return 'clickstack-bootstrap-ok';",
|
|
370
437
|
'};',
|
|
371
438
|
'main();',
|
|
@@ -387,7 +454,8 @@ export function renderClickStackTeamBootstrapScript(initialUser) {
|
|
|
387
454
|
* WHY IT IS NOT THE WHOLE GUARD. `version` is a RUNTIME spec field, so in KRO
|
|
388
455
|
* mode it is a schema reference here and a value a consumer supplies to the CR
|
|
389
456
|
* at apply time — there is no build to fail. That half is covered by narrowing
|
|
390
|
-
* `spec.version` on the generated CRD
|
|
457
|
+
* `spec.version` on the generated CRD, on CRDs KRO creates fresh (see the KRO
|
|
458
|
+
* caveat on {@link CLICKSTACK_INITIAL_USER_VALIDATED_CHART_VERSIONS}); see
|
|
391
459
|
* {@link clickStackInitialUserVersionValidationRule}. This function therefore
|
|
392
460
|
* treats a non-string as "not mine to check", which is also what the analysis
|
|
393
461
|
* pass hands it.
|
|
@@ -405,7 +473,7 @@ function assertClickStackInitialUserChartVersion(version, initialUser) {
|
|
|
405
473
|
throw new Error('ClickStack initialUser is audited only against chart version(s) ' +
|
|
406
474
|
`${CLICKSTACK_INITIAL_USER_VALIDATED_CHART_VERSIONS.join(', ')} (appVersion ` +
|
|
407
475
|
`${CLICKSTACK_INITIAL_USER_VALIDATED_APP_VERSION}), but version ${JSON.stringify(version)} ` +
|
|
408
|
-
|
|
476
|
+
"was requested. Registration goes through HyperDX's own endpoint, but TypeKro still " +
|
|
409
477
|
"patches the Team's apiKey directly in HyperDX's schema — if that field moves the Job " +
|
|
410
478
|
'still succeeds and ingestion is silently unauthenticated. The list is exact on purpose: ' +
|
|
411
479
|
'a range such as ">=3.2.0" resolves to a chart nobody audited. Verify the registration ' +
|
|
@@ -436,27 +504,72 @@ function assertClickStackHyperdxOidcChartVersion(version, hyperdxOidc) {
|
|
|
436
504
|
'models. Verify them on that chart, then set hyperdxOidc.allowUnvalidatedChartVersion: true.');
|
|
437
505
|
}
|
|
438
506
|
}
|
|
507
|
+
/**
|
|
508
|
+
* Refuse a concrete `clickhouse.host` that would break the URLs it is built
|
|
509
|
+
* into (see {@link validateClickStackClickhouseHost}); the CRD carries the same
|
|
510
|
+
* rule for KRO mode.
|
|
511
|
+
*
|
|
512
|
+
* @throws Error naming the offending value and the rule it breaks
|
|
513
|
+
*/
|
|
514
|
+
function assertClickStackClickhouseHost(host) {
|
|
515
|
+
const reason = validateClickStackClickhouseHost(host);
|
|
516
|
+
if (reason !== undefined) {
|
|
517
|
+
throw new Error(`ClickStack clickhouse.host ${JSON.stringify(host)} ${reason}.`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Refuse the Team-defaults seed on a chart version nobody has audited — the
|
|
522
|
+
* build-time check. The CRD rule ({@link clickStackSchemaFieldValidations})
|
|
523
|
+
* covers KRO mode on fresh CRDs, and the CronJob's runtime check
|
|
524
|
+
* (`CLICKSTACK_CHART_VERSION`) covers every CRD, including ones KRO created
|
|
525
|
+
* before the rule existed.
|
|
526
|
+
*
|
|
527
|
+
* The seed writes documents in HyperDX 2.35.0's own `connections` / `sources`
|
|
528
|
+
* schema. On a chart whose HyperDX changed that schema, the CronJob would
|
|
529
|
+
* still succeed and the Team would look configured with documents HyperDX may
|
|
530
|
+
* misread, and the seed never runs twice.
|
|
531
|
+
*/
|
|
532
|
+
function assertClickStackTeamDefaultsChartVersion(version, teamDefaults) {
|
|
533
|
+
if (teamDefaults === undefined || teamDefaults.allowUnvalidatedChartVersion)
|
|
534
|
+
return;
|
|
535
|
+
if (typeof version !== 'string')
|
|
536
|
+
return;
|
|
537
|
+
if (!isClickStackInitialUserValidatedChartVersion(version)) {
|
|
538
|
+
throw new Error('ClickStack teamDefaults is audited only against chart version(s) ' +
|
|
539
|
+
`${CLICKSTACK_INITIAL_USER_VALIDATED_CHART_VERSIONS.join(', ')} (appVersion ` +
|
|
540
|
+
`${CLICKSTACK_INITIAL_USER_VALIDATED_APP_VERSION}), but version ${JSON.stringify(version)} ` +
|
|
541
|
+
"was requested. The Team-bootstrap CronJob seeds an empty Team's ClickHouse connection " +
|
|
542
|
+
"and sources in HyperDX's own MongoDB schema. Verify the connections and sources schema " +
|
|
543
|
+
'on that chart, then set teamDefaults: { allowUnvalidatedChartVersion: true }, or turn ' +
|
|
544
|
+
'the seed off with teamDefaults: false.');
|
|
545
|
+
}
|
|
546
|
+
}
|
|
439
547
|
/**
|
|
440
548
|
* Schema field validations for a composition, with the chart-version narrowing
|
|
441
|
-
* added when `initialUser` is
|
|
549
|
+
* added when `initialUser`, `hyperdxOidc` or the Team-defaults seed is on.
|
|
442
550
|
*
|
|
443
551
|
* This is the KRO-mode half of the version allowlist. `schemaFieldValidations`
|
|
444
552
|
* becomes `x-kubernetes-validations` on the generated CRD, so a consumer who
|
|
445
553
|
* sets an unaudited `spec.version` on the custom resource is refused by
|
|
446
554
|
* ADMISSION — the path a build-time throw structurally cannot reach. It is
|
|
447
555
|
* applied to the `secretValues` variants too, which previously carried no
|
|
448
|
-
* validations at all and so had no KRO-side guard of any kind.
|
|
556
|
+
* validations at all and so had no KRO-side guard of any kind. KRO 0.9.2 puts
|
|
557
|
+
* these rules only on CRDs it creates fresh (it compares no validations on an
|
|
558
|
+
* update), which is why the seed also checks the chart version and the host
|
|
559
|
+
* at runtime.
|
|
449
560
|
*
|
|
450
561
|
* @param base - The mode's own validations (inline mode pins `apiKey`)
|
|
451
|
-
* @param
|
|
562
|
+
* @param build - The resolved options that write into HyperDX's own schema
|
|
452
563
|
* @returns Composition options carrying the merged map, or `{}` when empty
|
|
453
564
|
*/
|
|
454
|
-
function clickStackSchemaFieldValidations(base,
|
|
565
|
+
function clickStackSchemaFieldValidations(base, build) {
|
|
566
|
+
const { initialUser, hyperdxOidc, teamDefaults } = build;
|
|
455
567
|
const merged = { ...base };
|
|
456
|
-
//
|
|
457
|
-
//
|
|
568
|
+
// All three are audited against the same chart series, so one rule covers
|
|
569
|
+
// any of them (see CLICKSTACK_HYPERDX_OIDC_VALIDATED_CHART_VERSIONS).
|
|
458
570
|
if ((initialUser !== undefined && !initialUser.allowUnvalidatedChartVersion) ||
|
|
459
|
-
(hyperdxOidc !== undefined && !hyperdxOidc.allowUnvalidatedChartVersion)
|
|
571
|
+
(hyperdxOidc !== undefined && !hyperdxOidc.allowUnvalidatedChartVersion) ||
|
|
572
|
+
(teamDefaults !== undefined && !teamDefaults.allowUnvalidatedChartVersion)) {
|
|
460
573
|
merged.version = clickStackInitialUserVersionValidationRule();
|
|
461
574
|
}
|
|
462
575
|
return Object.keys(merged).length > 0 ? { schemaFieldValidations: merged } : {};
|
|
@@ -487,6 +600,8 @@ function bootstrapBody(spec, build) {
|
|
|
487
600
|
assertClickStackInitialUserChartVersion(isKubernetesRef(spec.version) ? undefined : (spec.version ?? DEFAULT_CLICKSTACK_VERSION), build.initialUser);
|
|
488
601
|
// The OIDC plugin hooks HyperDX internals, so the same audited-chart rule applies.
|
|
489
602
|
assertClickStackHyperdxOidcChartVersion(isKubernetesRef(spec.version) ? undefined : (spec.version ?? DEFAULT_CLICKSTACK_VERSION), build.hyperdxOidc);
|
|
603
|
+
// The Team-defaults seed writes HyperDX's `connections` / `sources` schema.
|
|
604
|
+
assertClickStackTeamDefaultsChartVersion(isKubernetesRef(spec.version) ? undefined : (spec.version ?? DEFAULT_CLICKSTACK_VERSION), build.teamDefaults);
|
|
490
605
|
// The schema constrains `name` — DNS-label syntax and the derived length
|
|
491
606
|
// bound — for KRO admission and direct-mode `deploy`; direct-mode `toYaml`
|
|
492
607
|
// does not run `validateSpec`, so a concrete malformed or over-long name
|
|
@@ -495,6 +610,11 @@ function bootstrapBody(spec, build) {
|
|
|
495
610
|
// The guard runs the SAME schema, so the message cannot drift from it.
|
|
496
611
|
if (!isKubernetesRef(spec.name))
|
|
497
612
|
assertClickStackReleaseName(spec.name);
|
|
613
|
+
// The host becomes `http://<host>:<port>` and `tcp://<host>:<port>`, so a
|
|
614
|
+
// concrete one must not carry a scheme, port, path or userinfo.
|
|
615
|
+
if (!isKubernetesRef(spec.clickhouse) && !isKubernetesRef(spec.clickhouse.host)) {
|
|
616
|
+
assertClickStackClickhouseHost(spec.clickhouse.host);
|
|
617
|
+
}
|
|
498
618
|
if (build.credentialSource === 'inline') {
|
|
499
619
|
const inlineApiKey = spec.apiKey;
|
|
500
620
|
if (!isKubernetesRef(inlineApiKey) &&
|
|
@@ -628,6 +748,13 @@ function bootstrapBody(spec, build) {
|
|
|
628
748
|
...(build.credentialSource === 'secretValues'
|
|
629
749
|
? {
|
|
630
750
|
valuesFrom: [
|
|
751
|
+
// TypeKro's external ClickHouse connection FIRST, so the
|
|
752
|
+
// caller's fragment below can still override it.
|
|
753
|
+
{
|
|
754
|
+
kind: 'ConfigMap',
|
|
755
|
+
name: `${spec.name}${CLICKSTACK_DEFAULT_CONNECTIONS_CONFIGMAP_SUFFIX}`,
|
|
756
|
+
valuesKey: CLICKSTACK_DEFAULT_CONNECTIONS_VALUES_KEY,
|
|
757
|
+
},
|
|
631
758
|
{
|
|
632
759
|
kind: 'Secret',
|
|
633
760
|
// biome-ignore lint/style/noNonNullAssertion: the secretValues schema requires credentialsSecret
|
|
@@ -641,6 +768,31 @@ function bootstrapBody(spec, build) {
|
|
|
641
768
|
: {}),
|
|
642
769
|
id: CLICKSTACK_HELM_RELEASE_RESOURCE_ID,
|
|
643
770
|
});
|
|
771
|
+
// ── secretValues: HyperDX's default connection ───────────────────────
|
|
772
|
+
// Without it the chart falls back to its own "Local ClickHouse" at the
|
|
773
|
+
// bundled Service TypeKro disables, and HyperDX's registration provisions
|
|
774
|
+
// that. The password stays a chart template (see the mapper), so the
|
|
775
|
+
// ConfigMap carries no credential. The HelmRelease reads it through
|
|
776
|
+
// valuesFrom, so it has to exist first.
|
|
777
|
+
if (build.credentialSource === 'secretValues') {
|
|
778
|
+
const defaultConnections = configMap({
|
|
779
|
+
id: 'clickstackDefaultConnections',
|
|
780
|
+
metadata: {
|
|
781
|
+
name: `${spec.name}${CLICKSTACK_DEFAULT_CONNECTIONS_CONFIGMAP_SUFFIX}`,
|
|
782
|
+
namespace: resolvedNamespace,
|
|
783
|
+
labels: {
|
|
784
|
+
'app.kubernetes.io/name': 'clickstack',
|
|
785
|
+
'app.kubernetes.io/instance': spec.name,
|
|
786
|
+
'app.kubernetes.io/component': 'default-connections',
|
|
787
|
+
'app.kubernetes.io/managed-by': 'typekro',
|
|
788
|
+
},
|
|
789
|
+
},
|
|
790
|
+
data: {
|
|
791
|
+
[CLICKSTACK_DEFAULT_CONNECTIONS_VALUES_KEY]: CLICKSTACK_SECRET_VALUES_DEFAULT_CONNECTIONS_DOCUMENT,
|
|
792
|
+
},
|
|
793
|
+
});
|
|
794
|
+
_clickstackHelmRelease.dependsOn(defaultConnections);
|
|
795
|
+
}
|
|
644
796
|
// The collector Pod mounts the queue claim by name, so the claim has to
|
|
645
797
|
// exist before helm-controller creates the Deployment.
|
|
646
798
|
if (queueClaim !== undefined) {
|
|
@@ -681,6 +833,7 @@ function bootstrapBody(spec, build) {
|
|
|
681
833
|
const mongoUri = build.mongoMode === 'external'
|
|
682
834
|
? spec.mongoUri
|
|
683
835
|
: Cel.template('mongodb://%s-mongodb.%s.svc.cluster.local:27017/hyperdx', spec.name, resolvedNamespace);
|
|
836
|
+
const seedTarget = clickStackDefaultConnectionTarget(spec);
|
|
684
837
|
const _teamBootstrap = cronJob({
|
|
685
838
|
id: 'clickstackTeamBootstrap',
|
|
686
839
|
metadata: {
|
|
@@ -719,7 +872,13 @@ function bootstrapBody(spec, build) {
|
|
|
719
872
|
'--quiet',
|
|
720
873
|
mongoUri,
|
|
721
874
|
'--eval',
|
|
722
|
-
renderClickStackTeamBootstrapScript(build.initialUser
|
|
875
|
+
renderClickStackTeamBootstrapScript(build.initialUser, {
|
|
876
|
+
...(build.teamName !== undefined && { teamName: build.teamName }),
|
|
877
|
+
teamDefaults: build.teamDefaults !== undefined,
|
|
878
|
+
...(build.teamDefaults?.allowUnvalidatedChartVersion === true && {
|
|
879
|
+
seedChartVersions: null,
|
|
880
|
+
}),
|
|
881
|
+
}),
|
|
723
882
|
],
|
|
724
883
|
env: [
|
|
725
884
|
{
|
|
@@ -772,6 +931,41 @@ function bootstrapBody(spec, build) {
|
|
|
772
931
|
value: Cel.template(`http://%s.%s.svc.cluster.local:${CLICKSTACK_API_PORT}`, spec.name, resolvedNamespace),
|
|
773
932
|
},
|
|
774
933
|
]),
|
|
934
|
+
// The connection an empty Team is seeded with: the same
|
|
935
|
+
// host, user and database `defaultConnections` /
|
|
936
|
+
// `defaultSources` render, and the UI user's password by
|
|
937
|
+
// reference, never by value. `optional: true` so a
|
|
938
|
+
// missing key cannot stop ingestion-key reconciliation;
|
|
939
|
+
// the script then seeds nothing rather than ''.
|
|
940
|
+
...(build.teamDefaults !== undefined
|
|
941
|
+
? [
|
|
942
|
+
{ name: HYPERDX_DEFAULT_CONNECTION_HOST_ENV, value: seedTarget.host },
|
|
943
|
+
{
|
|
944
|
+
name: HYPERDX_DEFAULT_CONNECTION_USERNAME_ENV,
|
|
945
|
+
value: seedTarget.username,
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
name: HYPERDX_DEFAULT_CONNECTION_PASSWORD_ENV,
|
|
949
|
+
valueFrom: {
|
|
950
|
+
secretKeyRef: {
|
|
951
|
+
...build.teamDefaults.passwordSecretRef,
|
|
952
|
+
optional: true,
|
|
953
|
+
},
|
|
954
|
+
},
|
|
955
|
+
},
|
|
956
|
+
{
|
|
957
|
+
name: HYPERDX_DEFAULT_SOURCES_DATABASE_ENV,
|
|
958
|
+
value: seedTarget.database,
|
|
959
|
+
},
|
|
960
|
+
// For the seed's runtime version check: the one
|
|
961
|
+
// guard that holds on a KRO CRD created before
|
|
962
|
+
// the version rule existed.
|
|
963
|
+
{
|
|
964
|
+
name: CLICKSTACK_CHART_VERSION_ENV,
|
|
965
|
+
value: resolvedVersion,
|
|
966
|
+
},
|
|
967
|
+
]
|
|
968
|
+
: []),
|
|
775
969
|
],
|
|
776
970
|
},
|
|
777
971
|
],
|
|
@@ -990,11 +1184,66 @@ function resolveClickHouseStorageForBuild(options) {
|
|
|
990
1184
|
assertQueueReplicaCompatible('makeClickstackBootstrap', resolved, replicaCount);
|
|
991
1185
|
return resolved;
|
|
992
1186
|
}
|
|
1187
|
+
function withTeamDefaults(teamDefaults) {
|
|
1188
|
+
return teamDefaults === undefined ? {} : { teamDefaults };
|
|
1189
|
+
}
|
|
1190
|
+
/**
|
|
1191
|
+
* Whether, and how, the bootstrap seeds Team defaults.
|
|
1192
|
+
*
|
|
1193
|
+
* The seed must create the same connection HyperDX's own registration would,
|
|
1194
|
+
* with the same password, or the Team ends up looking configured with a
|
|
1195
|
+
* connection that cannot log in and is never seeded again. In both credential
|
|
1196
|
+
* modes HyperDX's `DEFAULT_CONNECTIONS` password is the chart value
|
|
1197
|
+
* `hyperdx.secrets.CLICKHOUSE_APP_PASSWORD`: inline mode renders it into
|
|
1198
|
+
* `defaultConnections` directly, and `secretValues` mode templates it there
|
|
1199
|
+
* (see `CLICKSTACK_SECRET_VALUES_DEFAULT_CONNECTIONS_DOCUMENT`). The chart renders
|
|
1200
|
+
* that same value into `clickstack-secret.CLICKHOUSE_APP_PASSWORD`, which is
|
|
1201
|
+
* what the seed reads. One value, one connection definition.
|
|
1202
|
+
*
|
|
1203
|
+
* DEFAULT: ON WITH INLINE CREDENTIALS, OFF WITH `secretValues`. Inline, TypeKro
|
|
1204
|
+
* owns the whole connection. With `secretValues`, the caller's values fragment
|
|
1205
|
+
* may replace `defaultConnections`, and the CronJob cannot see that: without
|
|
1206
|
+
* `initialUser` nothing runs `setupTeamDefaults`, so a default-on seed would
|
|
1207
|
+
* put TypeKro's connection into the empty Team instead of the caller's, once
|
|
1208
|
+
* and for good. There, `teamDefaults: true` (or an options object) asks for
|
|
1209
|
+
* TypeKro's typed topology explicitly. (With `initialUser`, HyperDX's own
|
|
1210
|
+
* registration seeds the Team from the fully merged values either way.)
|
|
1211
|
+
*
|
|
1212
|
+
* Off when build-time values replace the chart defaults (or point HyperDX at
|
|
1213
|
+
* an existing config Secret): what HyperDX would seed is the caller's then.
|
|
1214
|
+
*/
|
|
1215
|
+
function resolveTeamDefaults(options) {
|
|
1216
|
+
const requested = options.teamDefaults;
|
|
1217
|
+
if (requested === false)
|
|
1218
|
+
return undefined;
|
|
1219
|
+
if (requested === undefined && options.credentials?.source === 'secretValues')
|
|
1220
|
+
return undefined;
|
|
1221
|
+
const hyperdx = options.values?.hyperdx;
|
|
1222
|
+
const deployment = typeof hyperdx === 'object' && hyperdx !== null
|
|
1223
|
+
? hyperdx.deployment
|
|
1224
|
+
: undefined;
|
|
1225
|
+
if (typeof deployment === 'object' && deployment !== null) {
|
|
1226
|
+
const overrides = deployment;
|
|
1227
|
+
if (overrides.defaultConnections !== undefined ||
|
|
1228
|
+
overrides.defaultSources !== undefined ||
|
|
1229
|
+
(overrides.useExistingConfigSecret !== undefined &&
|
|
1230
|
+
overrides.useExistingConfigSecret !== false)) {
|
|
1231
|
+
return undefined;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
return {
|
|
1235
|
+
passwordSecretRef: { name: CLICKSTACK_SECRET_NAME, key: CLICKSTACK_APP_PASSWORD_SECRET_KEY },
|
|
1236
|
+
allowUnvalidatedChartVersion: typeof requested === 'object' && requested.allowUnvalidatedChartVersion === true,
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
993
1239
|
function resolveInternalBuild(options) {
|
|
994
1240
|
const initialUser = resolveClickStackInitialUser('makeClickstackBootstrap', CLICKSTACK_SECRET_NAME, options.initialUser);
|
|
995
1241
|
const hyperdxOidc = resolveClickStackHyperdxOidc('makeClickstackBootstrap', options.hyperdxOidc);
|
|
1242
|
+
const teamName = resolveClickStackTeamName('makeClickstackBootstrap', options.teamName, initialUser !== undefined);
|
|
996
1243
|
return {
|
|
997
1244
|
mongoMode: 'internal',
|
|
1245
|
+
...(teamName !== undefined && { teamName }),
|
|
1246
|
+
...withTeamDefaults(resolveTeamDefaults(options)),
|
|
998
1247
|
credentialSource: options.credentials?.source ?? 'inline',
|
|
999
1248
|
...(options.mongo?.storage !== undefined && { storage: options.mongo.storage }),
|
|
1000
1249
|
...(options.values !== undefined && { values: options.values }),
|
|
@@ -1007,8 +1256,11 @@ function resolveInternalBuild(options) {
|
|
|
1007
1256
|
function resolveExternalBuild(options) {
|
|
1008
1257
|
const initialUser = resolveClickStackInitialUser('makeClickstackBootstrap', CLICKSTACK_SECRET_NAME, options.initialUser);
|
|
1009
1258
|
const hyperdxOidc = resolveClickStackHyperdxOidc('makeClickstackBootstrap', options.hyperdxOidc);
|
|
1259
|
+
const teamName = resolveClickStackTeamName('makeClickstackBootstrap', options.teamName, initialUser !== undefined);
|
|
1010
1260
|
return {
|
|
1011
1261
|
mongoMode: 'external',
|
|
1262
|
+
...(teamName !== undefined && { teamName }),
|
|
1263
|
+
...withTeamDefaults(resolveTeamDefaults(options)),
|
|
1012
1264
|
credentialSource: options.credentials?.source ?? 'inline',
|
|
1013
1265
|
...(options.values !== undefined && { values: options.values }),
|
|
1014
1266
|
...(options.postRenderers !== undefined && { postRenderers: options.postRenderers }),
|
|
@@ -1024,7 +1276,7 @@ function buildInternalInlineComposition(options) {
|
|
|
1024
1276
|
kind: options.kind ?? 'ClickStackBootstrap',
|
|
1025
1277
|
spec: ClickStackBootstrapConfigSchema,
|
|
1026
1278
|
status: ClickStackBootstrapStatusSchema,
|
|
1027
|
-
}, (spec) => bootstrapBody(spec, build), clickStackSchemaFieldValidations(inlineSchemaFieldValidations, build
|
|
1279
|
+
}, (spec) => bootstrapBody(spec, build), clickStackSchemaFieldValidations(inlineSchemaFieldValidations, build));
|
|
1028
1280
|
}
|
|
1029
1281
|
function buildInternalSecretValuesComposition(options) {
|
|
1030
1282
|
const build = {
|
|
@@ -1036,7 +1288,7 @@ function buildInternalSecretValuesComposition(options) {
|
|
|
1036
1288
|
kind: options.kind ?? 'ClickStackBootstrap',
|
|
1037
1289
|
spec: ClickStackSecretValuesBootstrapConfigSchema,
|
|
1038
1290
|
status: ClickStackBootstrapStatusSchema,
|
|
1039
|
-
}, (spec) => bootstrapBody(spec, build), clickStackSchemaFieldValidations(
|
|
1291
|
+
}, (spec) => bootstrapBody(spec, build), clickStackSchemaFieldValidations(hostSchemaFieldValidations, build));
|
|
1040
1292
|
}
|
|
1041
1293
|
function buildExternalInlineComposition(options) {
|
|
1042
1294
|
const build = resolveExternalBuild(options);
|
|
@@ -1045,7 +1297,7 @@ function buildExternalInlineComposition(options) {
|
|
|
1045
1297
|
kind: options.kind ?? 'ClickStackExternalMongoBootstrap',
|
|
1046
1298
|
spec: ClickStackExternalMongoBootstrapConfigSchema,
|
|
1047
1299
|
status: ClickStackBootstrapStatusSchema,
|
|
1048
|
-
}, (spec) => bootstrapBody(spec, build), clickStackSchemaFieldValidations(inlineSchemaFieldValidations, build
|
|
1300
|
+
}, (spec) => bootstrapBody(spec, build), clickStackSchemaFieldValidations(inlineSchemaFieldValidations, build));
|
|
1049
1301
|
}
|
|
1050
1302
|
function buildExternalSecretValuesComposition(options) {
|
|
1051
1303
|
const build = {
|
|
@@ -1057,7 +1309,7 @@ function buildExternalSecretValuesComposition(options) {
|
|
|
1057
1309
|
kind: options.kind ?? 'ClickStackExternalMongoBootstrap',
|
|
1058
1310
|
spec: ClickStackSecretValuesExternalMongoBootstrapConfigSchema,
|
|
1059
1311
|
status: ClickStackBootstrapStatusSchema,
|
|
1060
|
-
}, (spec) => bootstrapBody(spec, build), clickStackSchemaFieldValidations(
|
|
1312
|
+
}, (spec) => bootstrapBody(spec, build), clickStackSchemaFieldValidations(hostSchemaFieldValidations, build));
|
|
1061
1313
|
}
|
|
1062
1314
|
function isSecretValuesExternalBuild(options) {
|
|
1063
1315
|
return options.mongo?.mode === 'external' && options.credentials?.source === 'secretValues';
|