diff --git a/src/server/adapter/kubernetes-api.adapter.ts b/src/server/adapter/kubernetes-api.adapter.ts index cb64edd..4987847 100644 --- a/src/server/adapter/kubernetes-api.adapter.ts +++ b/src/server/adapter/kubernetes-api.adapter.ts @@ -37,11 +37,21 @@ const getK8sLogApiClient = () => { const k8sLogClient = globalThis.k8sLogGlobal ?? getK8sLogApiClient() if (process.env.NODE_ENV !== 'production') globalThis.k8sLogGlobal = k8sLogClient +const getK8sNetworkApiClient = () => { + const kc = new k8s.KubeConfig(); + kc.loadFromFile('/workspace/kube-config.config'); // todo update --> use security role + const networkClient = kc.makeApiClient(k8s.NetworkingV1Api); + return networkClient; +} +const k8sNetworkClient = globalThis.k8sNetworkGlobal ?? getK8sNetworkApiClient() +if (process.env.NODE_ENV !== 'production') globalThis.k8sNetworkGlobal = k8sNetworkClient + declare const globalThis: { k8sCoreGlobal: ReturnType; k8sAppsGlobal: ReturnType; k8sJobGlobal: ReturnType; k8sLogGlobal: ReturnType; + k8sNetworkGlobal: ReturnType; } & typeof global; @@ -53,6 +63,7 @@ class K3sApiAdapter { apps = k8sAppsClient; batch = k8sJobClient; log = k8sLogClient; + network = k8sNetworkClient; } const k3s = new K3sApiAdapter(); diff --git a/src/server/services/deployment.service.ts b/src/server/services/deployment.service.ts index b8ab499..7635300 100644 --- a/src/server/services/deployment.service.ts +++ b/src/server/services/deployment.service.ts @@ -1,12 +1,16 @@ import { AppExtendedModel } from "@/model/app-extended.model"; import k3s from "../adapter/kubernetes-api.adapter"; -import { V1Deployment } from "@kubernetes/client-node"; +import { V1Deployment, V1Ingress } from "@kubernetes/client-node"; +import { NetworkingV1Api } from "@kubernetes/client-node"; import buildService from "./build.service"; import { ListUtils } from "../utils/list.utils"; import { DeploymentInfoModel, DeplyomentStatus } from "@/model/deployment-info.model"; import { BuildJobStatus } from "@/model/build-job"; import { ServiceException } from "@/model/service.exception.model"; import { PodsInfoModel } from "@/model/pods-info.model"; +import { spec } from "node:test/reporters"; +import { rule } from "postcss"; +import path from "node:path"; class DeploymentService { @@ -85,6 +89,8 @@ class DeploymentService { } else { await k3s.core.createNamespacedService(app.projectId, body); } + await this.createOrUpdateIngress(app); + } async createDeployment(app: AppExtendedModel, buildJobName?: string) { @@ -186,6 +192,62 @@ class DeploymentService { } as PodsInfoModel; } + async getIngress(projectId: string, appId: string) { + const res = await k3s.network.listIngressClass(projectId); + return res.body.items.find((item) => item.metadata?.name === `ingress-${appId}`); + } + + async createOrUpdateIngress(app: AppExtendedModel) { + //const existingIngress = await this.getIngress(app.projectId, app.id); + const ingressDefinition: V1Ingress = { + apiVersion: 'networking.k8s.io/v1', + kind: 'Ingress', + metadata: { + name: `ingress-${app.id}`, + namespace: app.projectId, + annotations: { + 'cert-manager.io/cluster-issuer': 'letsencrypt-staging', + }, + }, + spec: { + ingressClassName: 'traefik', + rules: [ + { + host: `shelby.meyer-net.ch`, + http: { + paths: [ + { + path: '/', + pathType: 'Prefix', + backend: { + service: { + name: this.getServiceName(app.id), + port: { + number: app.defaultPort, + }, + }, + }, + }, + ], + }, + }, + ], + tls: [ + { + hosts: [`shelby.meyer-net.ch`], + secretName: `secret-tls-${app.id}`, + }, + ], + }, + }; + + await k3s.network.createNamespacedIngress(app.projectId, ingressDefinition); + /*if (existingIngress) { + await k3s.network.replaceNamespacedIngress(`ingress-${app.id}`, app.projectId, ingressDefinition); + } else { + await k3s.network.createNamespacedIngress(app.projectId, ingressDefinition); + }*/ + } /** * Searches for Build Jobs (only for Git Projects) and ReplicaSets (for all projects) and returns a list of DeploymentModel @@ -259,6 +321,9 @@ class DeploymentService { }); return ListUtils.sortByDate(revisions, (i) => i.createdAt!, true); } + + + } const deploymentService = new DeploymentService();