@crossdelta/infrastructure 0.2.27 → 0.3.0-beta.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/README.md +519 -301
- package/bin/generate-env.ts +4 -7
- package/dist/core/compat.d.ts +72 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/runtime-detection.d.ts +15 -0
- package/dist/core/runtime.d.ts +221 -0
- package/dist/core/types.d.ts +419 -0
- package/dist/env.cjs +11 -17
- package/dist/env.d.ts +16 -2
- package/dist/env.js +12 -16
- package/dist/helpers/discover-services.d.ts +62 -5
- package/dist/helpers/docker-hub-image.d.ts +2 -3
- package/dist/helpers/index.d.ts +0 -7
- package/dist/index.cjs +32730 -29321
- package/dist/index.d.ts +28 -1
- package/dist/index.js +34170 -30761
- package/dist/runtimes/doks/types.d.ts +45 -3
- package/dist/runtimes/doks/workloads.d.ts +6 -6
- package/dist/runtimes/local/docker-compose.d.ts +38 -0
- package/dist/runtimes/local/index.d.ts +9 -0
- package/dist/runtimes/local/k3d.d.ts +58 -0
- package/dist/runtimes/local/types.d.ts +118 -0
- package/dist/types/index.d.ts +12 -146
- package/dist/types/service-names.d.ts +1 -1
- package/package.json +3 -2
- package/dist/helpers/config.d.ts +0 -29
- package/dist/helpers/droplet-builder.d.ts +0 -44
- package/dist/helpers/image.d.ts +0 -30
- package/dist/helpers/otel.d.ts +0 -62
- package/dist/helpers/service-builder.d.ts +0 -39
- package/dist/helpers/service-runtime.d.ts +0 -22
- package/dist/helpers/service-urls.d.ts +0 -27
package/bin/generate-env.ts
CHANGED
|
@@ -37,8 +37,7 @@ const resolveNumber = (value: string, fileContent: string): number | undefined =
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
const extract = {
|
|
40
|
-
string: (content: string, pattern: RegExp): string | undefined =>
|
|
41
|
-
content.match(pattern)?.[1],
|
|
40
|
+
string: (content: string, pattern: RegExp): string | undefined => content.match(pattern)?.[1],
|
|
42
41
|
|
|
43
42
|
number: (content: string, pattern: RegExp): number | undefined => {
|
|
44
43
|
const match = content.match(pattern)?.[1]
|
|
@@ -72,7 +71,7 @@ const loadPulumiConfig = async (infraDir: string, stack: string): Promise<string
|
|
|
72
71
|
try {
|
|
73
72
|
const result = Bun.spawnSync(['pulumi', 'config', '--show-secrets', '--json', '--stack', stack, '--cwd', infraDir])
|
|
74
73
|
if (result.exitCode !== 0) return []
|
|
75
|
-
|
|
74
|
+
|
|
76
75
|
const config = JSON.parse(result.stdout.toString()) as Record<string, PulumiConfigEntry>
|
|
77
76
|
|
|
78
77
|
return Object.entries(config)
|
|
@@ -89,10 +88,8 @@ const loadPulumiConfig = async (infraDir: string, stack: string): Promise<string
|
|
|
89
88
|
|
|
90
89
|
const discoverServices = (servicesDir: string): MinimalServiceConfig[] => {
|
|
91
90
|
if (!existsSync(servicesDir)) return []
|
|
92
|
-
|
|
93
|
-
const files = readdirSync(servicesDir).filter(
|
|
94
|
-
(file) => file.endsWith('.ts') && file !== 'index.ts'
|
|
95
|
-
)
|
|
91
|
+
|
|
92
|
+
const files = readdirSync(servicesDir).filter((file) => file.endsWith('.ts') && file !== 'index.ts')
|
|
96
93
|
|
|
97
94
|
return files.map((file) => {
|
|
98
95
|
const content = readFileSync(join(servicesDir, file), 'utf-8')
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility helpers for migrating from old port models to unified port config.
|
|
3
|
+
*
|
|
4
|
+
* These helpers allow gradual migration from the inconsistent
|
|
5
|
+
* httpPort/internalPorts/containerPort model to the unified ServicePorts model.
|
|
6
|
+
*/
|
|
7
|
+
import type { ServicePorts } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* Legacy port configuration (App Platform style).
|
|
10
|
+
*/
|
|
11
|
+
export interface LegacyAppPlatformPorts {
|
|
12
|
+
/** Public HTTP port */
|
|
13
|
+
httpPort?: number;
|
|
14
|
+
/** Internal-only ports */
|
|
15
|
+
internalPorts?: number[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Legacy port configuration (Kubernetes style).
|
|
19
|
+
*/
|
|
20
|
+
export interface LegacyK8sPorts {
|
|
21
|
+
/** Container port */
|
|
22
|
+
containerPort: number;
|
|
23
|
+
/** Additional ports */
|
|
24
|
+
additionalPorts?: Array<{
|
|
25
|
+
name: string;
|
|
26
|
+
port: number;
|
|
27
|
+
targetPort?: number;
|
|
28
|
+
protocol?: 'TCP' | 'UDP';
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Convert legacy App Platform port config to unified model.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Old style
|
|
37
|
+
* { httpPort: 3000 }
|
|
38
|
+
*
|
|
39
|
+
* // Converts to
|
|
40
|
+
* { primary: { port: 3000, name: 'http', public: true } }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function fromAppPlatformPorts(config: LegacyAppPlatformPorts): ServicePorts;
|
|
44
|
+
/**
|
|
45
|
+
* Convert legacy Kubernetes port config to unified model.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* // Old style
|
|
50
|
+
* { containerPort: 4001 }
|
|
51
|
+
*
|
|
52
|
+
* // Converts to
|
|
53
|
+
* { primary: { port: 4001, name: 'http' } }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function fromK8sPorts(config: LegacyK8sPorts): ServicePorts;
|
|
57
|
+
/**
|
|
58
|
+
* Extract primary port number from ServicePorts (for backward compatibility).
|
|
59
|
+
*/
|
|
60
|
+
export declare function getPrimaryPort(ports: ServicePorts): number;
|
|
61
|
+
/**
|
|
62
|
+
* Get all port numbers from ServicePorts.
|
|
63
|
+
*/
|
|
64
|
+
export declare function getAllPorts(ports: ServicePorts): number[];
|
|
65
|
+
/**
|
|
66
|
+
* Get public ports from ServicePorts.
|
|
67
|
+
*/
|
|
68
|
+
export declare function getPublicPorts(ports: ServicePorts): number[];
|
|
69
|
+
/**
|
|
70
|
+
* Check if any port is public.
|
|
71
|
+
*/
|
|
72
|
+
export declare function hasPublicPort(ports: ServicePorts): boolean;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime detection utilities
|
|
3
|
+
*
|
|
4
|
+
* Separate from main runtime.ts to avoid Pulumi imports in tests
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Detect runtime from environment or configuration.
|
|
8
|
+
*
|
|
9
|
+
* Priority:
|
|
10
|
+
* 1. INFRASTRUCTURE_PROVIDER env var
|
|
11
|
+
* 2. Default to 'doks'
|
|
12
|
+
*
|
|
13
|
+
* Note: Pulumi config detection is handled in the main runtime.ts file
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectRuntimeProvider(): string;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime adapter interfaces for provider-agnostic infrastructure management.
|
|
3
|
+
*
|
|
4
|
+
* Each cloud provider (DOKS, EKS, AKS, GKE) implements these interfaces
|
|
5
|
+
* to provide a consistent API across different platforms.
|
|
6
|
+
*/
|
|
7
|
+
import * as pulumi from '@pulumi/pulumi';
|
|
8
|
+
import type { ClusterDeploymentResult, CoreClusterConfig, CoreNetworkConfig, CoreServiceConfig, ServiceDeploymentResult } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Runtime adapter for a specific cloud provider.
|
|
11
|
+
*
|
|
12
|
+
* Each provider implements this interface to translate core configurations
|
|
13
|
+
* into provider-specific resources.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // Create DOKS adapter
|
|
18
|
+
* const runtime = createDOKSRuntime()
|
|
19
|
+
*
|
|
20
|
+
* // Deploy cluster
|
|
21
|
+
* const cluster = await runtime.createCluster(clusterConfig)
|
|
22
|
+
*
|
|
23
|
+
* // Deploy services
|
|
24
|
+
* const service = await runtime.deployService(serviceConfig, cluster.provider)
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export interface RuntimeAdapter {
|
|
28
|
+
/** Provider identifier */
|
|
29
|
+
readonly provider: string;
|
|
30
|
+
/**
|
|
31
|
+
* Create a VPC/network.
|
|
32
|
+
*/
|
|
33
|
+
createNetwork(config: CoreNetworkConfig): Promise<NetworkResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Create a Kubernetes cluster.
|
|
36
|
+
*/
|
|
37
|
+
createCluster(config: CoreClusterConfig, networkId?: pulumi.Input<string>): Promise<ClusterResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Deploy a service to the cluster.
|
|
40
|
+
*/
|
|
41
|
+
deployService(config: CoreServiceConfig, options: DeployServiceOptions): Promise<ServiceDeploymentResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Deploy multiple services to the cluster.
|
|
44
|
+
*/
|
|
45
|
+
deployServices(configs: CoreServiceConfig[], options: DeployServicesOptions): Promise<ServiceDeploymentResult[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Configure ingress controller for the cluster.
|
|
48
|
+
*/
|
|
49
|
+
configureIngress?(options: ConfigureIngressOptions): Promise<IngressResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Configure certificate management (e.g., cert-manager, AWS ACM).
|
|
52
|
+
*/
|
|
53
|
+
configureCertManager?(options: ConfigureCertManagerOptions): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Network creation result.
|
|
57
|
+
*/
|
|
58
|
+
export interface NetworkResult {
|
|
59
|
+
/** Network ID */
|
|
60
|
+
id: pulumi.Output<string>;
|
|
61
|
+
/** Network name */
|
|
62
|
+
name: string;
|
|
63
|
+
/** CIDR block */
|
|
64
|
+
cidrBlock?: pulumi.Output<string>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Cluster creation result.
|
|
68
|
+
*/
|
|
69
|
+
export interface ClusterResult extends ClusterDeploymentResult {
|
|
70
|
+
/** Cluster ID */
|
|
71
|
+
id: pulumi.Output<string>;
|
|
72
|
+
/** Kubernetes provider (for deploying resources) */
|
|
73
|
+
provider: any;
|
|
74
|
+
/** VPC/Network ID */
|
|
75
|
+
networkId?: pulumi.Output<string>;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Ingress controller result.
|
|
79
|
+
*/
|
|
80
|
+
export interface IngressResult {
|
|
81
|
+
/** Ingress controller name */
|
|
82
|
+
name: string;
|
|
83
|
+
/** Public IP/hostname */
|
|
84
|
+
endpoint?: pulumi.Output<string>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Options for deploying a single service.
|
|
88
|
+
*/
|
|
89
|
+
export interface DeployServiceOptions {
|
|
90
|
+
/** Kubernetes provider */
|
|
91
|
+
provider: any;
|
|
92
|
+
/** Namespace to deploy to */
|
|
93
|
+
namespace: string;
|
|
94
|
+
/** Image pull secret name */
|
|
95
|
+
imagePullSecretName?: string;
|
|
96
|
+
/** Additional environment variables to inject */
|
|
97
|
+
additionalEnv?: Record<string, pulumi.Input<string>>;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Options for deploying multiple services.
|
|
101
|
+
*/
|
|
102
|
+
export interface DeployServicesOptions extends DeployServiceOptions {
|
|
103
|
+
/** Filter services by name (regex) */
|
|
104
|
+
filter?: RegExp;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Options for configuring ingress.
|
|
108
|
+
*/
|
|
109
|
+
export interface ConfigureIngressOptions {
|
|
110
|
+
/** Kubernetes provider */
|
|
111
|
+
provider: any;
|
|
112
|
+
/** Namespace */
|
|
113
|
+
namespace: string;
|
|
114
|
+
/** Ingress class name */
|
|
115
|
+
ingressClassName?: string;
|
|
116
|
+
/** Load balancer IP (optional, for static IP) */
|
|
117
|
+
loadBalancerIp?: string;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Options for configuring cert manager.
|
|
121
|
+
*/
|
|
122
|
+
export interface ConfigureCertManagerOptions {
|
|
123
|
+
/** Kubernetes provider */
|
|
124
|
+
provider: any;
|
|
125
|
+
/** Namespace */
|
|
126
|
+
namespace?: string;
|
|
127
|
+
/** Email for Let's Encrypt notifications */
|
|
128
|
+
email: string;
|
|
129
|
+
/** Staging mode (for testing) */
|
|
130
|
+
staging?: boolean;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Runtime factory function signature.
|
|
134
|
+
*/
|
|
135
|
+
export type RuntimeFactory = () => RuntimeAdapter;
|
|
136
|
+
/**
|
|
137
|
+
* Register a runtime adapter for a provider.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* registerRuntime('doks', createDOKSRuntime)
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
export declare function registerRuntime(provider: string, factory: RuntimeFactory): void;
|
|
145
|
+
/**
|
|
146
|
+
* Get a runtime adapter for a provider.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* const runtime = getRuntime('doks')
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
export declare function getRuntime(provider: string): RuntimeAdapter;
|
|
154
|
+
/**
|
|
155
|
+
* Detect runtime from environment or configuration.
|
|
156
|
+
*
|
|
157
|
+
* Priority:
|
|
158
|
+
* 1. INFRASTRUCTURE_PROVIDER env var
|
|
159
|
+
* 2. Pulumi config (infrastructure:provider)
|
|
160
|
+
* 3. Default to 'doks'
|
|
161
|
+
*/
|
|
162
|
+
export declare function detectRuntime(): string;
|
|
163
|
+
/**
|
|
164
|
+
* Runtime component configuration
|
|
165
|
+
*
|
|
166
|
+
* Configures which runtime components to deploy and their settings.
|
|
167
|
+
*/
|
|
168
|
+
export interface RuntimeDeploymentConfig {
|
|
169
|
+
/** NATS configuration */
|
|
170
|
+
nats?: {
|
|
171
|
+
enabled: boolean;
|
|
172
|
+
config?: any;
|
|
173
|
+
};
|
|
174
|
+
/** Ingress configuration */
|
|
175
|
+
ingress?: {
|
|
176
|
+
enabled: boolean;
|
|
177
|
+
config?: any;
|
|
178
|
+
};
|
|
179
|
+
/** Certificate manager configuration */
|
|
180
|
+
certManager?: {
|
|
181
|
+
enabled: boolean;
|
|
182
|
+
config?: any;
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Runtime deployment result
|
|
187
|
+
*/
|
|
188
|
+
export interface RuntimeDeploymentResult {
|
|
189
|
+
/** NATS internal URL */
|
|
190
|
+
natsUrl?: pulumi.Output<string>;
|
|
191
|
+
/** LoadBalancer IP (if ingress enabled) */
|
|
192
|
+
loadBalancerIp?: pulumi.Output<string>;
|
|
193
|
+
/** Cert manager ready */
|
|
194
|
+
certManagerReady?: boolean;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Deploy runtime components using the detected or specified runtime adapter.
|
|
198
|
+
*
|
|
199
|
+
* This is a convenience function that:
|
|
200
|
+
* 1. Detects or uses the specified runtime provider
|
|
201
|
+
* 2. Deploys optional runtime components (NATS, Ingress, Cert-Manager)
|
|
202
|
+
* 3. Returns URLs and metadata for the deployed components
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* const runtime = deployRuntime(provider, 'default', {
|
|
207
|
+
* nats: {
|
|
208
|
+
* enabled: true,
|
|
209
|
+
* config: { jetstream: { enabled: true, storageSize: '1Gi' } }
|
|
210
|
+
* },
|
|
211
|
+
* ingress: {
|
|
212
|
+
* enabled: true,
|
|
213
|
+
* config: { replicas: 1 }
|
|
214
|
+
* }
|
|
215
|
+
* })
|
|
216
|
+
*
|
|
217
|
+
* console.log('NATS URL:', runtime.natsUrl)
|
|
218
|
+
* console.log('LoadBalancer IP:', runtime.loadBalancerIp)
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
export declare function deployRuntime(provider: any, namespace: string, config: RuntimeDeploymentConfig, runtimeProvider?: string): RuntimeDeploymentResult;
|