typekro 0.24.1 → 0.26.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/core/composition/context.d.ts +4 -0
- package/dist/core/composition/context.d.ts.map +1 -1
- package/dist/core/composition/context.js +1 -0
- package/dist/core/composition/context.js.map +1 -1
- package/dist/core/composition/imperative.d.ts.map +1 -1
- package/dist/core/composition/imperative.js +24 -3
- package/dist/core/composition/imperative.js.map +1 -1
- package/dist/core/deployment/direct-factory.d.ts +8 -1
- package/dist/core/deployment/direct-factory.d.ts.map +1 -1
- package/dist/core/deployment/direct-factory.js +80 -61
- package/dist/core/deployment/direct-factory.js.map +1 -1
- package/dist/core/deployment/engine.d.ts +2 -0
- package/dist/core/deployment/engine.d.ts.map +1 -1
- package/dist/core/deployment/engine.js +22 -1
- package/dist/core/deployment/engine.js.map +1 -1
- package/dist/core/deployment/kro-factory.d.ts +2 -0
- package/dist/core/deployment/kro-factory.d.ts.map +1 -1
- package/dist/core/deployment/kro-factory.js +47 -11
- package/dist/core/deployment/kro-factory.js.map +1 -1
- package/dist/core/deployment/kro-instance-safety.d.ts +24 -0
- package/dist/core/deployment/kro-instance-safety.d.ts.map +1 -0
- package/dist/core/deployment/kro-instance-safety.js +157 -0
- package/dist/core/deployment/kro-instance-safety.js.map +1 -0
- package/dist/core/deployment/readiness-waiter.d.ts.map +1 -1
- package/dist/core/deployment/readiness-waiter.js +17 -2
- package/dist/core/deployment/readiness-waiter.js.map +1 -1
- package/dist/core/deployment/rollback-manager.d.ts +1 -1
- package/dist/core/deployment/rollback-manager.d.ts.map +1 -1
- package/dist/core/deployment/rollback-manager.js +16 -9
- package/dist/core/deployment/rollback-manager.js.map +1 -1
- package/dist/core/deployment/schema-cel-evaluator.d.ts +5 -0
- package/dist/core/deployment/schema-cel-evaluator.d.ts.map +1 -0
- package/dist/core/deployment/schema-cel-evaluator.js +36 -0
- package/dist/core/deployment/schema-cel-evaluator.js.map +1 -0
- package/dist/core/deployment/singleton-gitops.d.ts.map +1 -1
- package/dist/core/deployment/singleton-gitops.js +9 -2
- package/dist/core/deployment/singleton-gitops.js.map +1 -1
- package/dist/core/serialization/core.d.ts.map +1 -1
- package/dist/core/serialization/core.js +17 -4
- package/dist/core/serialization/core.js.map +1 -1
- package/dist/core/serialization/schema.d.ts.map +1 -1
- package/dist/core/serialization/schema.js +19 -4
- package/dist/core/serialization/schema.js.map +1 -1
- package/dist/core/serialization/yaml.d.ts.map +1 -1
- package/dist/core/serialization/yaml.js +15 -1
- package/dist/core/serialization/yaml.js.map +1 -1
- package/dist/core/types/kubernetes.d.ts +9 -0
- package/dist/core/types/kubernetes.d.ts.map +1 -1
- package/dist/core/types/serialization.d.ts +9 -0
- package/dist/core/types/serialization.d.ts.map +1 -1
- package/dist/factories/clickhouse/compositions/clickhouse-operator-bootstrap.d.ts +1 -1
- package/dist/factories/clickhouse/compositions/clickhouse-operator-bootstrap.js +1 -1
- package/dist/factories/clickhouse/index.d.ts +4 -1
- package/dist/factories/clickhouse/index.d.ts.map +1 -1
- package/dist/factories/clickhouse/index.js +4 -1
- package/dist/factories/clickhouse/index.js.map +1 -1
- package/dist/factories/clickstack/compositions/clickstack-bootstrap.d.ts +1 -1
- package/dist/factories/clickstack/compositions/clickstack-bootstrap.js +1 -1
- package/dist/factories/clickstack/compositions/k8s-telemetry.d.ts +1 -1
- package/dist/factories/clickstack/compositions/k8s-telemetry.js +1 -1
- package/dist/factories/clickstack/index.d.ts +1 -1
- package/dist/factories/clickstack/index.js +1 -1
- package/dist/factories/cnpg/compositions/cnpg-bootstrap.d.ts +1 -1
- package/dist/factories/cnpg/compositions/cnpg-bootstrap.js +1 -1
- package/dist/factories/cnpg/index.d.ts +1 -1
- package/dist/factories/cnpg/index.js +1 -1
- package/dist/factories/dagster/index.d.ts +1 -1
- package/dist/factories/dagster/index.js +1 -1
- package/dist/factories/index.d.ts +2 -0
- package/dist/factories/index.d.ts.map +1 -1
- package/dist/factories/index.js +8 -0
- package/dist/factories/index.js.map +1 -1
- package/dist/factories/inngest/compositions/inngest-bootstrap.d.ts +1 -1
- package/dist/factories/inngest/compositions/inngest-bootstrap.js +1 -1
- package/dist/factories/inngest/index.d.ts +1 -1
- package/dist/factories/inngest/index.js +1 -1
- package/dist/factories/kro/resource-graph-definition.d.ts.map +1 -1
- package/dist/factories/kro/resource-graph-definition.js +17 -1
- package/dist/factories/kro/resource-graph-definition.js.map +1 -1
- package/dist/factories/nats/compositions/index.d.ts +2 -0
- package/dist/factories/nats/compositions/index.d.ts.map +1 -0
- package/dist/factories/nats/compositions/index.js +2 -0
- package/dist/factories/nats/compositions/index.js.map +1 -0
- package/dist/factories/nats/compositions/nats-bootstrap.d.ts +49 -0
- package/dist/factories/nats/compositions/nats-bootstrap.d.ts.map +1 -0
- package/dist/factories/nats/compositions/nats-bootstrap.js +135 -0
- package/dist/factories/nats/compositions/nats-bootstrap.js.map +1 -0
- package/dist/factories/nats/index.d.ts +5 -0
- package/dist/factories/nats/index.d.ts.map +1 -0
- package/dist/factories/nats/index.js +5 -0
- package/dist/factories/nats/index.js.map +1 -0
- package/dist/factories/nats/resources/helm.d.ts +28 -0
- package/dist/factories/nats/resources/helm.d.ts.map +1 -0
- package/dist/factories/nats/resources/helm.js +39 -0
- package/dist/factories/nats/resources/helm.js.map +1 -0
- package/dist/factories/nats/resources/index.d.ts +3 -0
- package/dist/factories/nats/resources/index.d.ts.map +1 -0
- package/dist/factories/nats/resources/index.js +3 -0
- package/dist/factories/nats/resources/index.js.map +1 -0
- package/dist/factories/nats/resources/jetstream.d.ts +13 -0
- package/dist/factories/nats/resources/jetstream.d.ts.map +1 -0
- package/dist/factories/nats/resources/jetstream.js +105 -0
- package/dist/factories/nats/resources/jetstream.js.map +1 -0
- package/dist/factories/nats/types.d.ts +91 -0
- package/dist/factories/nats/types.d.ts.map +1 -0
- package/dist/factories/nats/types.js +72 -0
- package/dist/factories/nats/types.js.map +1 -0
- package/dist/factories/ory/compositions/ory-identity-stack.d.ts +1 -1
- package/dist/factories/ory/types.d.ts +2 -2
- package/dist/factories/rook/compositions/index.d.ts +4 -0
- package/dist/factories/rook/compositions/index.d.ts.map +1 -0
- package/dist/factories/rook/compositions/index.js +4 -0
- package/dist/factories/rook/compositions/index.js.map +1 -0
- package/dist/factories/rook/compositions/object-storage-claim.d.ts +32 -0
- package/dist/factories/rook/compositions/object-storage-claim.d.ts.map +1 -0
- package/dist/factories/rook/compositions/object-storage-claim.js +63 -0
- package/dist/factories/rook/compositions/object-storage-claim.js.map +1 -0
- package/dist/factories/rook/compositions/rook-ceph-helm-repository.d.ts +12 -0
- package/dist/factories/rook/compositions/rook-ceph-helm-repository.d.ts.map +1 -0
- package/dist/factories/rook/compositions/rook-ceph-helm-repository.js +25 -0
- package/dist/factories/rook/compositions/rook-ceph-helm-repository.js.map +1 -0
- package/dist/factories/rook/compositions/rook-ceph-operator-bootstrap.d.ts +2 -0
- package/dist/factories/rook/compositions/rook-ceph-operator-bootstrap.d.ts.map +1 -0
- package/dist/factories/rook/compositions/rook-ceph-operator-bootstrap.js +2 -0
- package/dist/factories/rook/compositions/rook-ceph-operator-bootstrap.js.map +1 -0
- package/dist/factories/rook/compositions/rook-ceph-operator-installation.d.ts +67 -0
- package/dist/factories/rook/compositions/rook-ceph-operator-installation.d.ts.map +1 -0
- package/dist/factories/rook/compositions/rook-ceph-operator-installation.js +71 -0
- package/dist/factories/rook/compositions/rook-ceph-operator-installation.js.map +1 -0
- package/dist/factories/rook/index.d.ts +15 -0
- package/dist/factories/rook/index.d.ts.map +1 -0
- package/dist/factories/rook/index.js +15 -0
- package/dist/factories/rook/index.js.map +1 -0
- package/dist/factories/rook/resources/bucket-storage-class.d.ts +12 -0
- package/dist/factories/rook/resources/bucket-storage-class.d.ts.map +1 -0
- package/dist/factories/rook/resources/bucket-storage-class.js +29 -0
- package/dist/factories/rook/resources/bucket-storage-class.js.map +1 -0
- package/dist/factories/rook/resources/ceph-object-store-user.d.ts +14 -0
- package/dist/factories/rook/resources/ceph-object-store-user.d.ts.map +1 -0
- package/dist/factories/rook/resources/ceph-object-store-user.js +42 -0
- package/dist/factories/rook/resources/ceph-object-store-user.js.map +1 -0
- package/dist/factories/rook/resources/ceph-object-store.d.ts +27 -0
- package/dist/factories/rook/resources/ceph-object-store.d.ts.map +1 -0
- package/dist/factories/rook/resources/ceph-object-store.js +56 -0
- package/dist/factories/rook/resources/ceph-object-store.js.map +1 -0
- package/dist/factories/rook/resources/helm.d.ts +18 -0
- package/dist/factories/rook/resources/helm.d.ts.map +1 -0
- package/dist/factories/rook/resources/helm.js +45 -0
- package/dist/factories/rook/resources/helm.js.map +1 -0
- package/dist/factories/rook/resources/index.d.ts +6 -0
- package/dist/factories/rook/resources/index.d.ts.map +1 -0
- package/dist/factories/rook/resources/index.js +6 -0
- package/dist/factories/rook/resources/index.js.map +1 -0
- package/dist/factories/rook/resources/object-bucket-claim.d.ts +15 -0
- package/dist/factories/rook/resources/object-bucket-claim.d.ts.map +1 -0
- package/dist/factories/rook/resources/object-bucket-claim.js +52 -0
- package/dist/factories/rook/resources/object-bucket-claim.js.map +1 -0
- package/dist/factories/rook/types.d.ts +307 -0
- package/dist/factories/rook/types.d.ts.map +1 -0
- package/dist/factories/rook/types.js +239 -0
- package/dist/factories/rook/types.js.map +1 -0
- package/dist/factories/rook/utils/helm-values-mapper.d.ts +33 -0
- package/dist/factories/rook/utils/helm-values-mapper.d.ts.map +1 -0
- package/dist/factories/rook/utils/helm-values-mapper.js +60 -0
- package/dist/factories/rook/utils/helm-values-mapper.js.map +1 -0
- package/dist/factories/rook/utils/index.d.ts +2 -0
- package/dist/factories/rook/utils/index.d.ts.map +1 -0
- package/dist/factories/rook/utils/index.js +2 -0
- package/dist/factories/rook/utils/index.js.map +1 -0
- package/dist/factories/valkey/compositions/index.d.ts +2 -1
- package/dist/factories/valkey/compositions/index.d.ts.map +1 -1
- package/dist/factories/valkey/compositions/index.js +2 -1
- package/dist/factories/valkey/compositions/index.js.map +1 -1
- package/dist/factories/valkey/compositions/valkey-bootstrap.d.ts +21 -2
- package/dist/factories/valkey/compositions/valkey-bootstrap.d.ts.map +1 -1
- package/dist/factories/valkey/compositions/valkey-bootstrap.js +26 -136
- package/dist/factories/valkey/compositions/valkey-bootstrap.js.map +1 -1
- package/dist/factories/valkey/compositions/valkey-helm-repository.d.ts +16 -0
- package/dist/factories/valkey/compositions/valkey-helm-repository.d.ts.map +1 -0
- package/dist/factories/valkey/compositions/valkey-helm-repository.js +29 -0
- package/dist/factories/valkey/compositions/valkey-helm-repository.js.map +1 -0
- package/dist/factories/valkey/index.d.ts +6 -3
- package/dist/factories/valkey/index.d.ts.map +1 -1
- package/dist/factories/valkey/index.js +6 -3
- package/dist/factories/valkey/index.js.map +1 -1
- package/dist/factories/valkey/resources/helm.d.ts.map +1 -1
- package/dist/factories/valkey/resources/helm.js +13 -11
- package/dist/factories/valkey/resources/helm.js.map +1 -1
- package/dist/factories/valkey/types.d.ts +29 -16
- package/dist/factories/valkey/types.d.ts.map +1 -1
- package/dist/factories/valkey/types.js +34 -22
- package/dist/factories/valkey/types.js.map +1 -1
- package/dist/factories/valkey/utils/helm-values-mapper.d.ts +6 -1
- package/dist/factories/valkey/utils/helm-values-mapper.d.ts.map +1 -1
- package/dist/factories/valkey/utils/helm-values-mapper.js +52 -19
- package/dist/factories/valkey/utils/helm-values-mapper.js.map +1 -1
- package/dist/factories/webapp/compositions/index.d.ts +1 -1
- package/dist/factories/webapp/compositions/index.d.ts.map +1 -1
- package/dist/factories/webapp/compositions/index.js +1 -1
- package/dist/factories/webapp/compositions/index.js.map +1 -1
- package/dist/factories/webapp/compositions/web-app-with-processing.d.ts +9 -13
- package/dist/factories/webapp/compositions/web-app-with-processing.d.ts.map +1 -1
- package/dist/factories/webapp/compositions/web-app-with-processing.js +290 -278
- package/dist/factories/webapp/compositions/web-app-with-processing.js.map +1 -1
- package/dist/factories/webapp/types.d.ts +26 -7
- package/dist/factories/webapp/types.d.ts.map +1 -1
- package/dist/factories/webapp/types.js +0 -9
- package/dist/factories/webapp/types.js.map +1 -1
- package/package.json +9 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { kubernetesComposition } from '../../../core/composition/imperative.js';
|
|
2
2
|
import { singleton } from '../../../core/singleton/singleton.js';
|
|
3
|
-
import { isKubernetesRef } from '../../../utils/type-guards.js';
|
|
3
|
+
import { containsKubernetesRefs, isKubernetesRef } from '../../../utils/type-guards.js';
|
|
4
4
|
import { cnpgBootstrap } from '../../cnpg/compositions/cnpg-bootstrap.js';
|
|
5
5
|
import { cluster } from '../../cnpg/resources/cluster.js';
|
|
6
6
|
import { secret } from '../../kubernetes/config/secret.js';
|
|
@@ -47,11 +47,10 @@ import { WebAppWithProcessingConfigSchema, WebAppWithProcessingStatusSchema, } f
|
|
|
47
47
|
* - Inngest references `database.status.writeService` for the postgres URI → deploys after CNPG
|
|
48
48
|
* - App references service names derived from resource names → deploys after all infra
|
|
49
49
|
*
|
|
50
|
-
*
|
|
51
|
-
* `spec.cnpgOperator
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* system namespace.
|
|
50
|
+
* CNPG operator install settings can be overridden per deployment via
|
|
51
|
+
* `spec.cnpgOperator`. Valkey settings are graph-authoring-time options on
|
|
52
|
+
* `makeWebAppWithProcessing(...)` because singleton ownership cannot safely
|
|
53
|
+
* depend on a per-instance KRO schema value.
|
|
55
54
|
*
|
|
56
55
|
* @example
|
|
57
56
|
* ```typescript
|
|
@@ -91,290 +90,303 @@ import { WebAppWithProcessingConfigSchema, WebAppWithProcessingStatusSchema, } f
|
|
|
91
90
|
* });
|
|
92
91
|
* ```
|
|
93
92
|
*/
|
|
94
|
-
export
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
spec
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
spec: {
|
|
158
|
-
instances: spec.database.instances,
|
|
159
|
-
storage: {
|
|
160
|
-
size: spec.database.storageSize,
|
|
161
|
-
...(spec.database.storageClass ? { storageClass: spec.database.storageClass } : {}),
|
|
93
|
+
export function makeWebAppWithProcessing(options = {}) {
|
|
94
|
+
if (containsKubernetesRefs(options)) {
|
|
95
|
+
throw new Error('makeWebAppWithProcessing: valkeyOperator is a build-time option and must be concrete. ' +
|
|
96
|
+
'Move schema/resource references into the per-instance webapp spec instead.');
|
|
97
|
+
}
|
|
98
|
+
if (options.valkeyOperator?.shared === false) {
|
|
99
|
+
throw new Error('makeWebAppWithProcessing: valkeyOperator.shared=false is no longer supported because the webapp consumes one cluster singleton. ' +
|
|
100
|
+
'Install a dedicated valkeyBootstrap separately if you need an independently owned operator.');
|
|
101
|
+
}
|
|
102
|
+
const { shared: _deprecatedShared, ...valkeyOperatorOptions } = options.valkeyOperator ?? {};
|
|
103
|
+
const valkeyOperator = {
|
|
104
|
+
...valkeyOperatorOptions,
|
|
105
|
+
name: valkeyOperatorOptions.name ?? 'valkey-operator',
|
|
106
|
+
namespace: valkeyOperatorOptions.namespace ?? 'valkey-operator-system',
|
|
107
|
+
};
|
|
108
|
+
return kubernetesComposition({
|
|
109
|
+
name: 'web-app-with-processing',
|
|
110
|
+
kind: 'WebAppWithProcessing',
|
|
111
|
+
spec: WebAppWithProcessingConfigSchema,
|
|
112
|
+
status: WebAppWithProcessingStatusSchema,
|
|
113
|
+
}, (spec) => {
|
|
114
|
+
const ns = spec.namespace ?? 'default';
|
|
115
|
+
const appPort = spec.app.port ?? 3000;
|
|
116
|
+
const appReplicas = spec.app.replicas ?? 1;
|
|
117
|
+
const inngestReplicas = spec.processing.replicas ?? 1;
|
|
118
|
+
// Defaults for optional DB fields. These literals are picked up by
|
|
119
|
+
// `extractNullishDefaults` and propagated to the outer KRO schema as
|
|
120
|
+
// `| default="..."` annotations (see schema.ts). Using schema-ref
|
|
121
|
+
// fallbacks (e.g., `spec.name`) does NOT work in KRO mode because
|
|
122
|
+
// the schema proxy is truthy and `??` never fires — KRO also has
|
|
123
|
+
// no way to express a cross-field schema default statically.
|
|
124
|
+
const dbName = spec.database.database ?? 'app';
|
|
125
|
+
const dbOwner = spec.database.owner ?? 'app';
|
|
126
|
+
// ── Operator bootstraps ────────────────────────────────────────────
|
|
127
|
+
//
|
|
128
|
+
// Install the CNPG and Valkey operators as part of the composition
|
|
129
|
+
// so consumers get a fully self-contained stack. The bootstraps run
|
|
130
|
+
// in their own system namespaces (not the app namespace) and install
|
|
131
|
+
// cluster-scoped operators; the later `cluster()`/`valkey()` calls
|
|
132
|
+
// create instances in the app namespace managed by those operators.
|
|
133
|
+
//
|
|
134
|
+
// Operators are cluster-scoped infrastructure — one install per
|
|
135
|
+
// cluster serves every consumer. Use singleton(...) so KRO-mode
|
|
136
|
+
// consumers reference the shared operator boundary instead of
|
|
137
|
+
// inlining the operator bootstrap resources into every app graph.
|
|
138
|
+
//
|
|
139
|
+
// Users who need a dedicated per-instance operator (multi-tenancy,
|
|
140
|
+
// version testing, isolated failure domains) can override any
|
|
141
|
+
// combination of CNPG fields via `spec.cnpgOperator`.
|
|
142
|
+
// The spread puts user overrides AFTER the defaults so they win.
|
|
143
|
+
// Operator bootstrap config: merge user overrides AFTER defaults.
|
|
144
|
+
// Use explicit ?? fallbacks for name/namespace instead of relying on
|
|
145
|
+
// object-literal-before-spread ordering — the spread of an optional
|
|
146
|
+
// spec field produces schema refs that get wrapped with omit(), but
|
|
147
|
+
// metadata.name is required and cannot be omitted. The ?? ensures
|
|
148
|
+
// the default is expressed as a KRO orValue/default, not omit().
|
|
149
|
+
const _cnpg = singleton(cnpgBootstrap, {
|
|
150
|
+
id: 'cnpg-operator',
|
|
151
|
+
spec: {
|
|
152
|
+
...spec.cnpgOperator,
|
|
153
|
+
name: spec.cnpgOperator?.name ?? 'cnpg-operator',
|
|
154
|
+
namespace: spec.cnpgOperator?.namespace ?? 'cnpg-system',
|
|
155
|
+
installCRDs: spec.cnpgOperator?.installCRDs ?? true,
|
|
162
156
|
},
|
|
163
|
-
|
|
164
|
-
|
|
157
|
+
});
|
|
158
|
+
const _valkeyOp = singleton(valkeyBootstrap, {
|
|
159
|
+
id: 'valkey-operator',
|
|
160
|
+
spec: valkeyOperator,
|
|
161
|
+
});
|
|
162
|
+
// ── PostgreSQL (CNPG) ──────────────────────────────────────────────
|
|
163
|
+
const database = cluster({
|
|
164
|
+
name: `${spec.name}-db`,
|
|
165
|
+
namespace: ns,
|
|
166
|
+
spec: {
|
|
167
|
+
instances: spec.database.instances,
|
|
168
|
+
storage: {
|
|
169
|
+
size: spec.database.storageSize,
|
|
170
|
+
...(spec.database.storageClass ? { storageClass: spec.database.storageClass } : {}),
|
|
171
|
+
},
|
|
172
|
+
bootstrap: {
|
|
173
|
+
initdb: { database: dbName, owner: dbOwner },
|
|
174
|
+
},
|
|
165
175
|
},
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
176
|
+
id: 'database',
|
|
177
|
+
});
|
|
178
|
+
const dbPooler = pooler({
|
|
179
|
+
name: `${spec.name}-db-pooler`,
|
|
180
|
+
namespace: ns,
|
|
181
|
+
spec: {
|
|
182
|
+
cluster: { name: `${spec.name}-db` },
|
|
183
|
+
type: 'rw',
|
|
184
|
+
pgbouncer: { poolMode: 'transaction' },
|
|
185
|
+
},
|
|
186
|
+
id: 'dbPooler',
|
|
187
|
+
});
|
|
188
|
+
// ── Valkey Cache ────────────────────────────────────────────────────
|
|
189
|
+
const cache = valkey({
|
|
190
|
+
name: `${spec.name}-cache`,
|
|
191
|
+
namespace: ns,
|
|
192
|
+
spec: {
|
|
193
|
+
volumePermissions: spec.cache?.volumePermissions ?? true,
|
|
194
|
+
anonymousAuth: true,
|
|
195
|
+
...(spec.cache?.shards != null ? { shards: spec.cache.shards } : {}),
|
|
196
|
+
...(spec.cache?.replicas != null ? { replicas: spec.cache.replicas } : {}),
|
|
197
|
+
storage: {
|
|
198
|
+
spec: {
|
|
199
|
+
accessModes: ['ReadWriteOnce'],
|
|
200
|
+
resources: { requests: { storage: spec.cache?.storageSize ?? '1Gi' } },
|
|
201
|
+
},
|
|
192
202
|
},
|
|
193
203
|
},
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
repositoryName: inngestRepositoryName,
|
|
248
|
-
inngest: {
|
|
249
|
-
eventKey: spec.processing.eventKey,
|
|
250
|
-
signingKey: spec.processing.signingKey,
|
|
251
|
-
postgres: { uri: `postgresql://${dbOwner}@${dbPooler.metadata.name}:5432/${dbName}` },
|
|
252
|
-
redis: { uri: `redis://${cache.metadata.name}:6379` },
|
|
253
|
-
sdkUrl: spec.processing.sdkUrl,
|
|
254
|
-
},
|
|
255
|
-
postgresql: { enabled: false },
|
|
256
|
-
redis: { enabled: false },
|
|
257
|
-
replicaCount: inngestReplicas,
|
|
258
|
-
...(spec.processing.resources ? { resources: spec.processing.resources } : {}),
|
|
259
|
-
// Deploy Inngest pods in the same namespace as CNPG (for Secret access)
|
|
260
|
-
// and inject the real postgres URI from the CNPG Secret via secretKeyRef.
|
|
261
|
-
customValues: {
|
|
262
|
-
namespace: { create: false, name: ns },
|
|
204
|
+
id: 'cache',
|
|
205
|
+
});
|
|
206
|
+
// KRO applyset pruning workaround (upstream: kubernetes-sigs/kro#1153).
|
|
207
|
+
//
|
|
208
|
+
// The Hyperspike Valkey operator copies ALL parent labels to child
|
|
209
|
+
// resources. KRO stamps applyset labels on the Valkey CR, so the
|
|
210
|
+
// operator propagates them to children (ConfigMap, headless Service,
|
|
211
|
+
// etc.). KRO's pruner then treats those children as applyset members
|
|
212
|
+
// and deletes any whose GK is already in `contains-group-kinds` but
|
|
213
|
+
// whose UID isn't in `keepUIDs` — creating an infinite create/delete
|
|
214
|
+
// loop. KRO closed this as "expected behavior"; the fix belongs on
|
|
215
|
+
// the operator side, but Hyperspike has no label-propagation opt-out.
|
|
216
|
+
//
|
|
217
|
+
// Workaround: pre-declare the operator-created resources as typekro
|
|
218
|
+
// graph nodes so KRO claims them with their own `kro.run/node-id`
|
|
219
|
+
// label. The operator's upsert then patches the existing resource
|
|
220
|
+
// instead of creating a new one with inherited applyset labels.
|
|
221
|
+
//
|
|
222
|
+
// TODO: remove when migrating to valkey-io/valkey-operator, which
|
|
223
|
+
// is unlikely to have this label-copying behavior.
|
|
224
|
+
simple.Service({
|
|
225
|
+
name: `${spec.name}-cache`,
|
|
226
|
+
namespace: ns,
|
|
227
|
+
selector: {
|
|
228
|
+
'app.kubernetes.io/name': 'valkey',
|
|
229
|
+
'app.kubernetes.io/instance': `${spec.name}-cache`,
|
|
230
|
+
},
|
|
231
|
+
ports: [{ port: 6379, targetPort: 6379 }],
|
|
232
|
+
id: 'cacheService',
|
|
233
|
+
});
|
|
234
|
+
simple.ConfigMap({
|
|
235
|
+
name: `${spec.name}-cache`,
|
|
236
|
+
namespace: ns,
|
|
237
|
+
data: {},
|
|
238
|
+
id: 'cacheConfigMap',
|
|
239
|
+
});
|
|
240
|
+
// ── Database credentials ──────────────────────────────────────────────
|
|
241
|
+
// CNPG auto-generates a Secret named {cluster}-{owner} during bootstrap.
|
|
242
|
+
// Validated against CNPG v1.25 (cloudnative-pg chart 0.23.0).
|
|
243
|
+
// The name is deterministic — no need for an externalRef which would block
|
|
244
|
+
// KRO reconciliation (KRO waits for external refs to exist before creating
|
|
245
|
+
// dependent resources, but the Secret only exists after CNPG bootstraps).
|
|
246
|
+
const dbSecretName = `${spec.name}-db-${dbOwner}`;
|
|
247
|
+
const inngestRepositoryName = `${spec.name}-${ns}-inngest-repo`;
|
|
248
|
+
// ── Inngest (with external DB + cache) ──────────────────────────────
|
|
249
|
+
// The actual postgres credentials are injected via the CNPG Secret
|
|
250
|
+
// (secretKeyRef below). Use the deterministic pooler host here instead of
|
|
251
|
+
// database.status.writeService so nested compositions do not leak an inner
|
|
252
|
+
// resource status marker into the parent deployment graph.
|
|
253
|
+
const inngestBootstrapApp = inngestBootstrap({
|
|
254
|
+
name: `${spec.name}-inngest`,
|
|
255
|
+
namespace: ns,
|
|
256
|
+
repositoryName: inngestRepositoryName,
|
|
263
257
|
inngest: {
|
|
264
|
-
eventKey:
|
|
265
|
-
signingKey:
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
258
|
+
eventKey: spec.processing.eventKey,
|
|
259
|
+
signingKey: spec.processing.signingKey,
|
|
260
|
+
postgres: { uri: `postgresql://${dbOwner}@${dbPooler.metadata.name}:5432/${dbName}` },
|
|
261
|
+
redis: { uri: `redis://${cache.metadata.name}:6379` },
|
|
262
|
+
sdkUrl: spec.processing.sdkUrl,
|
|
263
|
+
},
|
|
264
|
+
postgresql: { enabled: false },
|
|
265
|
+
redis: { enabled: false },
|
|
266
|
+
replicaCount: inngestReplicas,
|
|
267
|
+
...(spec.processing.resources ? { resources: spec.processing.resources } : {}),
|
|
268
|
+
// Deploy Inngest pods in the same namespace as CNPG (for Secret access)
|
|
269
|
+
// and inject the real postgres URI from the CNPG Secret via secretKeyRef.
|
|
270
|
+
customValues: {
|
|
271
|
+
namespace: { create: false, name: ns },
|
|
272
|
+
inngest: {
|
|
273
|
+
eventKey: undefined,
|
|
274
|
+
signingKey: undefined,
|
|
275
|
+
extraEnv: [
|
|
276
|
+
{
|
|
277
|
+
name: 'INNGEST_EVENT_KEY',
|
|
278
|
+
valueFrom: {
|
|
279
|
+
secretKeyRef: {
|
|
280
|
+
name: `${spec.name}-inngest-credentials`,
|
|
281
|
+
key: 'INNGEST_EVENT_KEY',
|
|
282
|
+
},
|
|
273
283
|
},
|
|
274
284
|
},
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
285
|
+
{
|
|
286
|
+
name: 'INNGEST_SIGNING_KEY',
|
|
287
|
+
valueFrom: {
|
|
288
|
+
secretKeyRef: {
|
|
289
|
+
name: `${spec.name}-inngest-credentials`,
|
|
290
|
+
key: 'INNGEST_SIGNING_KEY',
|
|
291
|
+
},
|
|
282
292
|
},
|
|
283
293
|
},
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
294
|
+
{
|
|
295
|
+
name: 'INNGEST_POSTGRES_URI',
|
|
296
|
+
valueFrom: {
|
|
297
|
+
secretKeyRef: {
|
|
298
|
+
name: dbSecretName,
|
|
299
|
+
key: 'uri',
|
|
300
|
+
},
|
|
291
301
|
},
|
|
292
302
|
},
|
|
293
|
-
|
|
294
|
-
|
|
303
|
+
],
|
|
304
|
+
},
|
|
295
305
|
},
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
306
|
+
});
|
|
307
|
+
// Inngest needs cache to be ready before it can connect to Redis.
|
|
308
|
+
// cache.metadata.name is deterministic and gets inlined to a schema
|
|
309
|
+
// ref, so KRO sees no implicit dependency. dependsOn creates an
|
|
310
|
+
// explicit readyWhen on inngest's leaf resource.
|
|
311
|
+
inngestBootstrapApp.dependsOn?.(cache);
|
|
312
|
+
inngestBootstrapApp.dependsOn?.(database);
|
|
313
|
+
inngestBootstrapApp.dependsOn?.(dbPooler);
|
|
314
|
+
// ── Inngest credentials Secret ──────────────────────────────────────
|
|
315
|
+
//
|
|
316
|
+
// The Inngest event key and signing key are sensitive — store them
|
|
317
|
+
// in a K8s Secret rather than plaintext in the Deployment env.
|
|
318
|
+
// Both the app and the Inngest server need these: the app sends
|
|
319
|
+
// events with the event key and validates webhooks with the signing
|
|
320
|
+
// key; the Inngest server uses them to authenticate SDK connections.
|
|
321
|
+
const inngestSecretName = `${spec.name}-inngest-credentials`;
|
|
322
|
+
secret({
|
|
323
|
+
metadata: {
|
|
324
|
+
name: inngestSecretName,
|
|
325
|
+
namespace: ns,
|
|
326
|
+
},
|
|
327
|
+
stringData: {
|
|
328
|
+
INNGEST_EVENT_KEY: spec.processing.eventKey,
|
|
329
|
+
INNGEST_SIGNING_KEY: spec.processing.signingKey,
|
|
330
|
+
},
|
|
331
|
+
id: 'inngestCredentials',
|
|
332
|
+
});
|
|
333
|
+
// ── Application ─────────────────────────────────────────────────────
|
|
334
|
+
const appEnv = {
|
|
335
|
+
DATABASE_URL: `postgresql://${dbOwner}@${dbPooler.metadata.name}:5432/${dbName}`,
|
|
336
|
+
VALKEY_URL: `redis://${cache.metadata.name}:6379`,
|
|
337
|
+
REDIS_URL: `redis://${cache.metadata.name}:6379`,
|
|
338
|
+
INNGEST_BASE_URL: `http://${spec.name}-inngest:8288`,
|
|
339
|
+
// INNGEST_EVENT_KEY and INNGEST_SIGNING_KEY injected via the
|
|
340
|
+
// inngest credentials Secret (envFrom below) — not plaintext.
|
|
341
|
+
...spec.app.env,
|
|
342
|
+
};
|
|
343
|
+
// The inngest Secret is listed FIRST so user-provided envFrom sources can
|
|
344
|
+
// override INNGEST_EVENT_KEY / INNGEST_SIGNING_KEY if they provide their
|
|
345
|
+
// own Secret containing those keys (last-write-wins in K8s envFrom ordering).
|
|
346
|
+
const userAppEnvFrom = spec.app.envFrom;
|
|
347
|
+
const appEnvFrom = isKubernetesRef(userAppEnvFrom)
|
|
348
|
+
? [{ secretRef: { name: inngestSecretName } }]
|
|
349
|
+
: [{ secretRef: { name: inngestSecretName } }, ...(userAppEnvFrom ?? [])];
|
|
350
|
+
const app = simple.Deployment({
|
|
351
|
+
name: spec.name,
|
|
316
352
|
namespace: ns,
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
//
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
name: spec.name,
|
|
353
|
-
namespace: ns,
|
|
354
|
-
selector: { app: spec.name },
|
|
355
|
-
ports: [{ port: appPort, targetPort: appPort }],
|
|
356
|
-
id: 'appService',
|
|
353
|
+
image: spec.app.image,
|
|
354
|
+
replicas: appReplicas,
|
|
355
|
+
ports: [{ containerPort: appPort }],
|
|
356
|
+
env: appEnv,
|
|
357
|
+
envFrom: appEnvFrom,
|
|
358
|
+
id: 'app',
|
|
359
|
+
});
|
|
360
|
+
simple.Service({
|
|
361
|
+
name: spec.name,
|
|
362
|
+
namespace: ns,
|
|
363
|
+
selector: { app: spec.name },
|
|
364
|
+
ports: [{ port: appPort, targetPort: appPort }],
|
|
365
|
+
id: 'appService',
|
|
366
|
+
});
|
|
367
|
+
// ── Status ──────────────────────────────────────────────────────────
|
|
368
|
+
return {
|
|
369
|
+
ready: app.status.readyReplicas >= appReplicas &&
|
|
370
|
+
database.status.readyInstances >= (spec.database.instances ?? 1) &&
|
|
371
|
+
cache.status.ready &&
|
|
372
|
+
inngestBootstrapApp.status.ready,
|
|
373
|
+
databaseUrl: `postgresql://${dbOwner}@${dbPooler.metadata.name}:5432/${dbName}`,
|
|
374
|
+
databaseHost: `${dbPooler.metadata.name}`,
|
|
375
|
+
databasePort: 5432,
|
|
376
|
+
cacheUrl: `redis://${cache.metadata.name}:6379`,
|
|
377
|
+
cacheHost: `${cache.metadata.name}`,
|
|
378
|
+
cachePort: 6379,
|
|
379
|
+
inngestUrl: `http://${spec.name}-inngest:8288`,
|
|
380
|
+
appUrl: `http://${spec.name}:${appPort}`,
|
|
381
|
+
components: {
|
|
382
|
+
app: app.status.readyReplicas >= appReplicas,
|
|
383
|
+
database: database.status.readyInstances >= (spec.database.instances ?? 1),
|
|
384
|
+
cache: cache.status.ready,
|
|
385
|
+
inngest: inngestBootstrapApp.status.ready,
|
|
386
|
+
},
|
|
387
|
+
};
|
|
357
388
|
});
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
database.status.readyInstances >= (spec.database.instances ?? 1) &&
|
|
362
|
-
cache.status.ready &&
|
|
363
|
-
inngestBootstrapApp.status.ready,
|
|
364
|
-
databaseUrl: `postgresql://${dbOwner}@${dbPooler.metadata.name}:5432/${dbName}`,
|
|
365
|
-
databaseHost: `${dbPooler.metadata.name}`,
|
|
366
|
-
databasePort: 5432,
|
|
367
|
-
cacheUrl: `redis://${cache.metadata.name}:6379`,
|
|
368
|
-
cacheHost: `${cache.metadata.name}`,
|
|
369
|
-
cachePort: 6379,
|
|
370
|
-
inngestUrl: `http://${spec.name}-inngest:8288`,
|
|
371
|
-
appUrl: `http://${spec.name}:${appPort}`,
|
|
372
|
-
components: {
|
|
373
|
-
app: app.status.readyReplicas >= appReplicas,
|
|
374
|
-
database: database.status.readyInstances >= (spec.database.instances ?? 1),
|
|
375
|
-
cache: cache.status.ready,
|
|
376
|
-
inngest: inngestBootstrapApp.status.ready,
|
|
377
|
-
},
|
|
378
|
-
};
|
|
379
|
-
});
|
|
389
|
+
}
|
|
390
|
+
/** Default webapp graph with the pinned Valkey operator installation. */
|
|
391
|
+
export const webAppWithProcessing = makeWebAppWithProcessing();
|
|
380
392
|
//# sourceMappingURL=web-app-with-processing.js.map
|