123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- import * as k8s from '@pulumi/kubernetes'
- import * as pulumi from '@pulumi/pulumi'
- import * as dns from 'dns'
- /**
- * ServiceDeployment is an example abstraction that uses a class to fold together the common pattern of a
- * Kubernetes Deployment and its associated Service object.
- */
- export class CaddyServiceDeployment extends pulumi.ComponentResource {
- public readonly deployment: k8s.apps.v1.Deployment
- public readonly service: k8s.core.v1.Service
- public readonly hostname?: pulumi.Output<string>
- public readonly primaryEndpoint?: pulumi.Output<string>
- public readonly secondaryEndpoint?: pulumi.Output<string>
- constructor(name: string, args: ServiceDeploymentArgs, opts?: pulumi.ComponentResourceOptions) {
- super('caddy:service:CaddyServiceDeployment', name, {}, opts)
- const labels = { app: name }
- let volumes: pulumi.Input<pulumi.Input<k8s.types.input.core.v1.Volume>[]> = []
- let caddyVolumeMounts: pulumi.Input<pulumi.Input<k8s.types.input.core.v1.VolumeMount>[]> = []
- async function lookupPromise(url: string): Promise<dns.LookupAddress[]> {
- return new Promise((resolve, reject) => {
- dns.lookup(url, { all: true }, (err: any, addresses: dns.LookupAddress[]) => {
- if (err) reject(err)
- resolve(addresses)
- })
- })
- }
- this.service = new k8s.core.v1.Service(
- name,
- {
- metadata: {
- name: name,
- namespace: args.namespaceName,
- labels: labels,
- },
- spec: {
- type: args.isMinikube ? 'NodePort' : 'LoadBalancer',
- ports: [
- { name: 'http', port: 80 },
- { name: 'https', port: 443 },
- ],
- selector: labels,
- },
- },
- { parent: this }
- )
- this.hostname = this.service.status.loadBalancer.ingress[0].hostname
- if (args.lbReady) {
- let caddyConfig: pulumi.Output<string>
- const lbIps: pulumi.Output<dns.LookupAddress[]> = this.hostname.apply((dnsName) => {
- return lookupPromise(dnsName)
- })
- function getProxyString(ipAddress: pulumi.Output<string>) {
- let result: pulumi.Output<string> = pulumi.interpolate``
- for (const endpoint of args.caddyEndpoints) {
- result = pulumi.interpolate`${ipAddress}.nip.io${endpoint}\n${result}`
- }
- return result
- }
- caddyConfig = pulumi.interpolate`${getProxyString(lbIps[0].address)}
- ${getProxyString(lbIps[1].address)}`
- this.primaryEndpoint = pulumi.interpolate`${lbIps[0].address}.nip.io`
- this.secondaryEndpoint = pulumi.interpolate`${lbIps[1].address}.nip.io`
- const keyConfig = new k8s.core.v1.ConfigMap(
- name,
- {
- metadata: { namespace: args.namespaceName, labels: labels },
- data: { 'fileData': caddyConfig },
- },
- { parent: this }
- )
- const keyConfigName = keyConfig.metadata.apply((m) => m.name)
- caddyVolumeMounts.push({
- mountPath: '/etc/caddy/Caddyfile',
- name: 'caddy-volume',
- subPath: 'fileData',
- })
- volumes.push({
- name: 'caddy-volume',
- configMap: {
- name: keyConfigName,
- },
- })
- }
- this.deployment = new k8s.apps.v1.Deployment(
- name,
- {
- metadata: { namespace: args.namespaceName, labels: labels },
- spec: {
- selector: { matchLabels: labels },
- replicas: 1,
- template: {
- metadata: { labels: labels },
- spec: {
- containers: [
- {
- name: 'caddy',
- image: 'caddy',
- ports: [
- { name: 'caddy-http', containerPort: 80 },
- { name: 'caddy-https', containerPort: 443 },
- ],
- volumeMounts: caddyVolumeMounts,
- },
- ],
- volumes,
- },
- },
- },
- },
- { parent: this }
- )
- }
- }
- export interface ServiceDeploymentArgs {
- namespaceName: pulumi.Output<string>
- // Endpoints are caddyConfig strings concatenated after IP.nip.io
- caddyEndpoints: string[]
- lbReady?: boolean
- isMinikube?: boolean
- }
|