feat: Utils | add public and internal ingress routes

This commit is contained in:
2025-11-22 23:18:56 +05:00
parent 35c3c70b08
commit 4f5fbcf83a
8 changed files with 149 additions and 27 deletions

View File

@@ -1,2 +1,2 @@
export { IngressRoute } from "./ingress";
export { IngressRouteTcp } from "./ingress-tcp";
export { PublicIngressRoute, InternalIngressRoute } from "./ingress";
export { IngressRouteTcp } from "./ingressTCP";

View File

@@ -0,0 +1,2 @@
export { PublicIngressRoute } from "./publicIngress";
export { InternalIngressRoute } from "./internalIngress";

View File

@@ -2,11 +2,12 @@ import { Construct } from "constructs";
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
import { CloudflareCertificate } from "../cert-manager";
import { CloudflareCertificate } from "../../cert-manager";
type IngressRouteOptions = {
export type IngressRouteOptions = {
provider: KubernetesProvider;
namespace: string;
name: string;
/** Hostname for this route (e.g. npm.dogar.dev) */
host: string;
@@ -26,9 +27,6 @@ type IngressRouteOptions = {
/** Extra middlewares (traefik format: namespace/name) */
middlewares?: string[];
/** Name override (otherwise auto) */
name?: string;
};
export class IngressRoute extends Construct {
@@ -37,7 +35,7 @@ export class IngressRoute extends Construct {
constructor(scope: Construct, id: string, opts: IngressRouteOptions) {
super(scope, id);
const name = opts.name ?? `route-${opts.host.replace(/\./g, "-")}`;
const name = opts.name;
const path = opts.path ?? "/";
const entryPoints = opts.entryPoints ?? ["websecure"];

View File

@@ -0,0 +1,63 @@
import { Construct } from "constructs";
import { IngressRoute, IngressRouteOptions } from "./ingress";
import { DataTerraformRemoteStateS3 } from "cdktf";
import { DataKubernetesNamespaceV1 } from "@cdktf/provider-kubernetes/lib/data-kubernetes-namespace-v1";
type InternalIngressRouteOptions = Omit<
IngressRouteOptions,
"entryPoints" | "tlsSecretName" | "middlewares"
>;
export class InternalIngressRoute extends Construct {
constructor(scope: Construct, id: string, opts: InternalIngressRouteOptions) {
super(scope, id);
const r2Endpoint = `${process.env.ACCOUNT_ID!}.r2.cloudflarestorage.com`;
const coreServicesState = new DataTerraformRemoteStateS3(
this,
"core-services-state",
{
usePathStyle: true,
skipRegionValidation: true,
skipCredentialsValidation: true,
skipRequestingAccountId: true,
skipS3Checksum: true,
encrypt: true,
bucket: "terraform-state",
key: "core-services/terraform.tfstate",
endpoints: {
s3: `https://${r2Endpoint}`,
},
region: "auto",
accessKey: process.env.ACCESS_KEY,
secretKey: process.env.SECRET_KEY,
},
);
const namespaceName = coreServicesState.getString("namespace-output");
const namespaceResource = new DataKubernetesNamespaceV1(
this,
"core-services-namespace",
{
provider: opts.provider,
metadata: {
name: namespaceName,
},
},
);
const namespace = namespaceResource.metadata.name;
new IngressRoute(this, opts.name, {
provider: opts.provider,
namespace: opts.namespace,
host: opts.host,
path: opts.path ?? "/",
serviceName: opts.serviceName,
servicePort: opts.servicePort,
entryPoints: ["websecure"],
tlsSecretName: `${opts.name}-tls`,
middlewares: [`${namespace}/ip-allow-list`],
name: opts.name,
});
}
}

View File

@@ -0,0 +1,63 @@
import { Construct } from "constructs";
import { IngressRoute, IngressRouteOptions } from "./ingress";
import { DataTerraformRemoteStateS3 } from "cdktf";
import { DataKubernetesNamespaceV1 } from "@cdktf/provider-kubernetes/lib/data-kubernetes-namespace-v1";
type PublicIngressRouteOptions = Omit<
IngressRouteOptions,
"entryPoints" | "tlsSecretName" | "middlewares"
>;
export class PublicIngressRoute extends Construct {
constructor(scope: Construct, id: string, opts: PublicIngressRouteOptions) {
super(scope, id);
const r2Endpoint = `${process.env.ACCOUNT_ID!}.r2.cloudflarestorage.com`;
const coreServicesState = new DataTerraformRemoteStateS3(
this,
"core-services-state",
{
usePathStyle: true,
skipRegionValidation: true,
skipCredentialsValidation: true,
skipRequestingAccountId: true,
skipS3Checksum: true,
encrypt: true,
bucket: "terraform-state",
key: "core-services/terraform.tfstate",
endpoints: {
s3: `https://${r2Endpoint}`,
},
region: "auto",
accessKey: process.env.ACCESS_KEY,
secretKey: process.env.SECRET_KEY,
},
);
const namespaceName = coreServicesState.getString("namespace-output");
const namespaceResource = new DataKubernetesNamespaceV1(
this,
"core-services-namespace",
{
provider: opts.provider,
metadata: {
name: namespaceName,
},
},
);
const namespace = namespaceResource.metadata.name;
new IngressRoute(this, opts.name, {
provider: opts.provider,
namespace: opts.namespace,
host: opts.host,
path: opts.path ?? "/",
serviceName: opts.serviceName,
servicePort: opts.servicePort,
entryPoints: ["websecure"],
tlsSecretName: `${opts.name}-tls`,
middlewares: [`${namespace}/rate-limit`],
name: opts.name,
});
}
}

View File

@@ -0,0 +1 @@
export { IngressRouteTcp } from "./ingress-tcp";

View File

@@ -4,6 +4,13 @@ import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
type IngressRouteTcpOptions = {
provider: KubernetesProvider;
name: string;
/**
* Match rule.
* Default is `HostSNI(\`*\`)` which is correct for most TCP services.
*/
match: string;
/** Namespace where the IngressRouteTCP will be created */
namespace: string;
@@ -16,15 +23,6 @@ type IngressRouteTcpOptions = {
/** Backend service port */
servicePort: number;
/**
* Match rule.
* Default is `HostSNI(\`*\`)` which is correct for most TCP services.
*/
match?: string;
/** Name override (CR name) */
name?: string;
};
export class IngressRouteTcp extends Construct {
@@ -33,14 +31,7 @@ export class IngressRouteTcp extends Construct {
constructor(scope: Construct, id: string, opts: IngressRouteTcpOptions) {
super(scope, id);
const name =
opts.name ??
`tcp-${opts.entryPoint}-${opts.serviceName}`.replace(
/[^a-zA-Z0-9-]/g,
"",
);
const matchRule = opts.match ?? "HostSNI(`*`)";
const { name, match } = opts;
this.manifest = new Manifest(this, name, {
provider: opts.provider,
@@ -55,7 +46,7 @@ export class IngressRouteTcp extends Construct {
entryPoints: [opts.entryPoint],
routes: [
{
match: matchRule,
match,
services: [
{
name: opts.serviceName,