|
1 | 1 | import sha256 from "sha256";
|
2 | 2 | import * as k8s from '@kubernetes/client-node';
|
| 3 | +import { execSync } from "child_process"; |
| 4 | +import { json } from "express"; |
3 | 5 |
|
4 | 6 | export function generatePassword(length = 16): string {
|
5 | 7 | const chars =
|
@@ -87,24 +89,57 @@ export async function provisionEVault(w3id: string, eVaultId: string) {
|
87 | 89 |
|
88 | 90 | await appsApi.createNamespacedDeployment({ body: deployment, namespace: namespaceName });
|
89 | 91 |
|
90 |
| - const serviceSpec = { |
91 |
| - metadata: { name: 'evault-service', namespace: namespaceName }, |
92 |
| - spec: { |
93 |
| - type: 'NodePort', |
94 |
| - selector: { app: 'evault' }, |
95 |
| - ports: [ |
96 |
| - { |
97 |
| - port: 80, |
98 |
| - targetPort: containerPort, |
99 |
| - protocol: 'TCP' |
100 |
| - // No nodePort → let Kubernetes assign one dynamically |
101 |
| - } |
102 |
| - ] |
| 92 | + await coreApi.createNamespacedService({ |
| 93 | + namespace: namespaceName, |
| 94 | + body: { |
| 95 | + apiVersion: 'v1', |
| 96 | + kind: 'Service', |
| 97 | + metadata: { name: 'evault-service' }, |
| 98 | + spec: { |
| 99 | + type: 'LoadBalancer', |
| 100 | + selector: { app: 'evault' }, |
| 101 | + ports: [ |
| 102 | + { |
| 103 | + port: 4000, |
| 104 | + targetPort: 4000 |
| 105 | + } |
| 106 | + ] |
| 107 | + } |
103 | 108 | }
|
104 |
| - }; |
| 109 | + }); |
| 110 | + |
| 111 | + const svc = await coreApi.readNamespacedService({ name: 'evault-service', namespace: namespaceName }); |
| 112 | + const spec = svc.spec; |
| 113 | + const status = svc.status; |
105 | 114 |
|
106 |
| - await coreApi.createNamespacedService({ body: serviceSpec, namespace: namespaceName }); |
| 115 | + // Check LoadBalancer first (cloud clusters) |
| 116 | + const ingress = status?.loadBalancer?.ingress?.[0]; |
| 117 | + if (ingress?.ip || ingress?.hostname) { |
| 118 | + const host = ingress.ip || ingress.hostname; |
| 119 | + const port = spec?.ports?.[0]?.port; |
| 120 | + return `http://${host}:${port}`; |
| 121 | + } |
| 122 | + |
| 123 | + // Fallback: NodePort + Node IP (local clusters or bare-metal) |
| 124 | + const nodePort = spec?.ports?.[0]?.nodePort; |
| 125 | + if (!nodePort) throw new Error('No LoadBalancer or NodePort found.'); |
| 126 | + |
| 127 | + // Try getting an external IP from the cluster nodes |
| 128 | + const nodes = await coreApi.listNode(); |
| 129 | + console.log(JSON.stringify(nodes)) |
| 130 | + const address = nodes?.items[0].status.addresses.find( |
| 131 | + (a) => a.type === 'ExternalIP' || a.type === 'InternalIP' |
| 132 | + )?.address; |
107 | 133 |
|
108 |
| - const res = await coreApi.readNamespacedService({ name: 'evault-service', namespace: namespaceName }); |
109 |
| - console.log(JSON.stringify(res)) |
| 134 | + if (address) { |
| 135 | + return `http://${address}:${nodePort}`; |
| 136 | + } |
| 137 | + |
| 138 | + // Local fallback: use minikube IP if available |
| 139 | + try { |
| 140 | + const minikubeIP = execSync('minikube ip').toString().trim(); |
| 141 | + return `http://${minikubeIP}:${nodePort}` |
| 142 | + } catch (e) { |
| 143 | + throw new Error('Unable to determine service IP (no LoadBalancer, Node IP, or Minikube IP)'); |
| 144 | + } |
110 | 145 | }
|
0 commit comments