@crossdelta/infrastructure 0.8.0 → 0.8.2
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/core/runtime.d.ts +2 -0
- package/dist/helpers/stream-job.d.ts +5 -3
- package/dist/index.cjs +26 -3
- package/dist/index.js +26 -3
- package/dist/runtimes/doks/types.d.ts +12 -0
- package/package.json +2 -2
package/dist/core/runtime.d.ts
CHANGED
|
@@ -188,6 +188,8 @@ export interface RuntimeDeploymentConfig {
|
|
|
188
188
|
export interface RuntimeDeploymentResult {
|
|
189
189
|
/** NATS internal URL */
|
|
190
190
|
natsUrl?: pulumi.Output<string>;
|
|
191
|
+
/** NATS Helm release resource (for dependsOn in downstream jobs) */
|
|
192
|
+
natsRelease?: pulumi.Resource;
|
|
191
193
|
/** LoadBalancer IP (if ingress enabled) */
|
|
192
194
|
loadBalancerIp?: pulumi.Output<string>;
|
|
193
195
|
/** Cert manager ready */
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import type { Provider } from '@pulumi/kubernetes';
|
|
16
16
|
import * as k8s from '@pulumi/kubernetes';
|
|
17
|
-
import type { Output } from '@pulumi/pulumi';
|
|
17
|
+
import type { Output, Resource } from '@pulumi/pulumi';
|
|
18
18
|
import type { StreamPolicy } from './deploy-streams';
|
|
19
19
|
import { type ResolvedStream } from './stream-setup';
|
|
20
|
-
export type { ResolvedStream };
|
|
21
20
|
export { computeConfigHash, generateSetupScript, msToNatsDuration, resolveStreams } from './stream-setup';
|
|
21
|
+
export type { ResolvedStream };
|
|
22
22
|
export interface MaterializeStreamsConfig {
|
|
23
23
|
/** NATS connection URL (cluster-internal) */
|
|
24
24
|
natsUrl: Output<string>;
|
|
@@ -37,8 +37,10 @@ export interface MaterializeStreamsConfig {
|
|
|
37
37
|
image?: string;
|
|
38
38
|
/** Job TTL after completion in seconds (default: 300) */
|
|
39
39
|
ttlAfterFinished?: number;
|
|
40
|
-
/** Max retry attempts (default:
|
|
40
|
+
/** Max retry attempts (default: 6) */
|
|
41
41
|
backoffLimit?: number;
|
|
42
|
+
/** Pulumi resources the Job depends on (e.g., NATS Helm release) */
|
|
43
|
+
dependsOn?: Resource[];
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
46
|
* Materialize NATS JetStream streams via a K8s Job.
|
package/dist/index.cjs
CHANGED
|
@@ -352,7 +352,7 @@ function deployNginxIngress(provider, config = {}) {
|
|
|
352
352
|
var k8s3 = __toESM(require("@pulumi/kubernetes"));
|
|
353
353
|
var pulumi2 = __toESM(require("@pulumi/pulumi"));
|
|
354
354
|
var NATS_DEFAULTS = {
|
|
355
|
-
replicas:
|
|
355
|
+
replicas: 1,
|
|
356
356
|
jetstream: {
|
|
357
357
|
enabled: true,
|
|
358
358
|
storageSize: "20Gi",
|
|
@@ -537,6 +537,7 @@ function deployRuntime(provider, namespace, config, runtimeProvider) {
|
|
|
537
537
|
if (config.nats?.enabled && providerName === "doks") {
|
|
538
538
|
const nats = deployNats(provider, namespace, config.nats.config || {});
|
|
539
539
|
result.natsUrl = pulumi3.output(nats.internalUrl);
|
|
540
|
+
result.natsRelease = nats.release;
|
|
540
541
|
}
|
|
541
542
|
if (config.ingress?.enabled && providerName === "doks") {
|
|
542
543
|
const ingress = deployNginxIngress(provider, config.ingress.config || {});
|
|
@@ -1011,6 +1012,20 @@ var generateSetupScript = (streams) => {
|
|
|
1011
1012
|
` NATS_OPTS="$NATS_OPTS --user $NATS_USER --password $NATS_PASSWORD"`,
|
|
1012
1013
|
`fi`,
|
|
1013
1014
|
``,
|
|
1015
|
+
`echo "⏳ Waiting for NATS to become available..."`,
|
|
1016
|
+
`RETRIES=0`,
|
|
1017
|
+
`MAX_RETRIES=30`,
|
|
1018
|
+
`until nats $NATS_OPTS server ping --count 1 > /dev/null 2>&1; do`,
|
|
1019
|
+
` RETRIES=$((RETRIES + 1))`,
|
|
1020
|
+
` if [ "$RETRIES" -ge "$MAX_RETRIES" ]; then`,
|
|
1021
|
+
` echo "❌ NATS not available after $MAX_RETRIES attempts"`,
|
|
1022
|
+
` exit 1`,
|
|
1023
|
+
` fi`,
|
|
1024
|
+
` echo " NATS not ready (attempt $RETRIES/$MAX_RETRIES), retrying in 2s..."`,
|
|
1025
|
+
` sleep 2`,
|
|
1026
|
+
`done`,
|
|
1027
|
+
`echo "✅ NATS is available"`,
|
|
1028
|
+
``,
|
|
1014
1029
|
`echo "\uD83D\uDE80 Materializing ${streams.length} stream(s)..."`,
|
|
1015
1030
|
`echo ""`,
|
|
1016
1031
|
``,
|
|
@@ -1045,7 +1060,8 @@ var materializeStreams = (provider, namespace, config) => {
|
|
|
1045
1060
|
defaults = DEFAULT_POLICY2,
|
|
1046
1061
|
image = NATS_BOX_IMAGE,
|
|
1047
1062
|
ttlAfterFinished = 300,
|
|
1048
|
-
backoffLimit =
|
|
1063
|
+
backoffLimit = 6,
|
|
1064
|
+
dependsOn: externalDeps = []
|
|
1049
1065
|
} = config;
|
|
1050
1066
|
validateStreamDefinitions(contracts);
|
|
1051
1067
|
const definitions = collectStreamDefinitions(contracts);
|
|
@@ -1110,7 +1126,7 @@ var materializeStreams = (provider, namespace, config) => {
|
|
|
1110
1126
|
}
|
|
1111
1127
|
}, {
|
|
1112
1128
|
provider,
|
|
1113
|
-
dependsOn: [configMap],
|
|
1129
|
+
dependsOn: [configMap, ...externalDeps],
|
|
1114
1130
|
deleteBeforeReplace: true
|
|
1115
1131
|
});
|
|
1116
1132
|
return job;
|
|
@@ -1435,6 +1451,13 @@ var deployK8sService = (provider, namespace, config) => {
|
|
|
1435
1451
|
},
|
|
1436
1452
|
spec: {
|
|
1437
1453
|
replicas,
|
|
1454
|
+
strategy: {
|
|
1455
|
+
type: "RollingUpdate",
|
|
1456
|
+
rollingUpdate: {
|
|
1457
|
+
maxSurge: normalizedConfig.strategy?.maxSurge ?? 0,
|
|
1458
|
+
maxUnavailable: normalizedConfig.strategy?.maxUnavailable ?? 1
|
|
1459
|
+
}
|
|
1460
|
+
},
|
|
1438
1461
|
selector: {
|
|
1439
1462
|
matchLabels: { app: normalizedConfig.name }
|
|
1440
1463
|
},
|
package/dist/index.js
CHANGED
|
@@ -258,7 +258,7 @@ function deployNginxIngress(provider, config = {}) {
|
|
|
258
258
|
import * as k8s3 from "@pulumi/kubernetes";
|
|
259
259
|
import * as pulumi2 from "@pulumi/pulumi";
|
|
260
260
|
var NATS_DEFAULTS = {
|
|
261
|
-
replicas:
|
|
261
|
+
replicas: 1,
|
|
262
262
|
jetstream: {
|
|
263
263
|
enabled: true,
|
|
264
264
|
storageSize: "20Gi",
|
|
@@ -443,6 +443,7 @@ function deployRuntime(provider, namespace, config, runtimeProvider) {
|
|
|
443
443
|
if (config.nats?.enabled && providerName === "doks") {
|
|
444
444
|
const nats = deployNats(provider, namespace, config.nats.config || {});
|
|
445
445
|
result.natsUrl = pulumi3.output(nats.internalUrl);
|
|
446
|
+
result.natsRelease = nats.release;
|
|
446
447
|
}
|
|
447
448
|
if (config.ingress?.enabled && providerName === "doks") {
|
|
448
449
|
const ingress = deployNginxIngress(provider, config.ingress.config || {});
|
|
@@ -917,6 +918,20 @@ var generateSetupScript = (streams) => {
|
|
|
917
918
|
` NATS_OPTS="$NATS_OPTS --user $NATS_USER --password $NATS_PASSWORD"`,
|
|
918
919
|
`fi`,
|
|
919
920
|
``,
|
|
921
|
+
`echo "⏳ Waiting for NATS to become available..."`,
|
|
922
|
+
`RETRIES=0`,
|
|
923
|
+
`MAX_RETRIES=30`,
|
|
924
|
+
`until nats $NATS_OPTS server ping --count 1 > /dev/null 2>&1; do`,
|
|
925
|
+
` RETRIES=$((RETRIES + 1))`,
|
|
926
|
+
` if [ "$RETRIES" -ge "$MAX_RETRIES" ]; then`,
|
|
927
|
+
` echo "❌ NATS not available after $MAX_RETRIES attempts"`,
|
|
928
|
+
` exit 1`,
|
|
929
|
+
` fi`,
|
|
930
|
+
` echo " NATS not ready (attempt $RETRIES/$MAX_RETRIES), retrying in 2s..."`,
|
|
931
|
+
` sleep 2`,
|
|
932
|
+
`done`,
|
|
933
|
+
`echo "✅ NATS is available"`,
|
|
934
|
+
``,
|
|
920
935
|
`echo "\uD83D\uDE80 Materializing ${streams.length} stream(s)..."`,
|
|
921
936
|
`echo ""`,
|
|
922
937
|
``,
|
|
@@ -951,7 +966,8 @@ var materializeStreams = (provider, namespace, config) => {
|
|
|
951
966
|
defaults = DEFAULT_POLICY2,
|
|
952
967
|
image = NATS_BOX_IMAGE,
|
|
953
968
|
ttlAfterFinished = 300,
|
|
954
|
-
backoffLimit =
|
|
969
|
+
backoffLimit = 6,
|
|
970
|
+
dependsOn: externalDeps = []
|
|
955
971
|
} = config;
|
|
956
972
|
validateStreamDefinitions(contracts);
|
|
957
973
|
const definitions = collectStreamDefinitions(contracts);
|
|
@@ -1016,7 +1032,7 @@ var materializeStreams = (provider, namespace, config) => {
|
|
|
1016
1032
|
}
|
|
1017
1033
|
}, {
|
|
1018
1034
|
provider,
|
|
1019
|
-
dependsOn: [configMap],
|
|
1035
|
+
dependsOn: [configMap, ...externalDeps],
|
|
1020
1036
|
deleteBeforeReplace: true
|
|
1021
1037
|
});
|
|
1022
1038
|
return job;
|
|
@@ -1341,6 +1357,13 @@ var deployK8sService = (provider, namespace, config) => {
|
|
|
1341
1357
|
},
|
|
1342
1358
|
spec: {
|
|
1343
1359
|
replicas,
|
|
1360
|
+
strategy: {
|
|
1361
|
+
type: "RollingUpdate",
|
|
1362
|
+
rollingUpdate: {
|
|
1363
|
+
maxSurge: normalizedConfig.strategy?.maxSurge ?? 0,
|
|
1364
|
+
maxUnavailable: normalizedConfig.strategy?.maxUnavailable ?? 1
|
|
1365
|
+
}
|
|
1366
|
+
},
|
|
1344
1367
|
selector: {
|
|
1345
1368
|
matchLabels: { app: normalizedConfig.name }
|
|
1346
1369
|
},
|
|
@@ -256,6 +256,18 @@ export interface K8sServiceConfig {
|
|
|
256
256
|
healthCheck?: K8sHealthCheck;
|
|
257
257
|
/** Resource requests and limits */
|
|
258
258
|
resources?: K8sResourceConfig;
|
|
259
|
+
/**
|
|
260
|
+
* Deployment strategy for rolling updates.
|
|
261
|
+
*
|
|
262
|
+
* Defaults to `maxSurge: 0, maxUnavailable: 1` which avoids memory spikes
|
|
263
|
+
* during rollouts by replacing pods one-at-a-time without surge.
|
|
264
|
+
*/
|
|
265
|
+
strategy?: {
|
|
266
|
+
/** Max extra pods during rollout (default: 0) */
|
|
267
|
+
maxSurge?: number;
|
|
268
|
+
/** Max unavailable pods during rollout (default: 1) */
|
|
269
|
+
maxUnavailable?: number;
|
|
270
|
+
};
|
|
259
271
|
/** Volume mounts for persistent storage */
|
|
260
272
|
volumes?: K8sVolumeMount[];
|
|
261
273
|
/** Command to run (overrides container entrypoint) */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crossdelta/infrastructure",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@crossdelta/cloudevents": "^0.7.
|
|
38
|
+
"@crossdelta/cloudevents": "^0.7.18"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@pulumi/digitalocean": "^4.0.0",
|