10import * as _ from 'lodash-es' 13export const k8sK3sIngress = async ({ingressNginxVersion}: {ingressNginxVersion: string}) => { 17 if (action !== 'apply') { 18 console.log('skipping ingress-nginx setup for action:', action) 29 // Patch ingress-nginx controller with both publish-status-address and default-ssl-certificate 30 await patchIngressController({cluster_name, serverIp, wcCertName}) 31 await patchIngressCacheConfig({cluster_name}) 33 console.log('ingress-nginx installed for k3s') 34 return {nodePorts, serverIp} 37const patchIngressController = async ({cluster_name, serverIp, wcCertName}: {cluster_name: string, serverIp: string, wcCertName: string}) => { 41 apiVersion: 'apps/v1', 43 metadata: { name: 'ingress-nginx-controller', namespace: 'ingress-nginx' }, 49 const podSpec = resource.spec.template.spec 50 const container = podSpec.containers[0] 51 const publishStatusArg = `--publish-status-address=${serverIp}` 52 const defaultSslArg = `--default-ssl-certificate=default/${wcCertName}` 56 // Enable hostNetwork so ingress-nginx binds to ports 80/443 directly 57 if (!podSpec.hostNetwork) { 58 podSpec.hostNetwork = true 59 podSpec.dnsPolicy = 'ClusterFirstWithHostNet' 60 console.log('enabling hostNetwork mode') 64 // Add/update --publish-status-address 65 const publishI = _.findIndex(container.args, (argS: string) => _.startsWith(argS, '--publish-status-address')) 66 if (publishI === -1) { 67 container.args.push(publishStatusArg) 68 console.log(`adding ${publishStatusArg}`) 70 } else if (container.args[publishI] !== publishStatusArg) { 71 container.args[publishI] = publishStatusArg 72 console.log(`updating to ${publishStatusArg}`) 76 // Add/update --default-ssl-certificate 77 const sslI = _.findIndex(container.args, (argS: string) => _.startsWith(argS, '--default-ssl-certificate')) 79 container.args.push(defaultSslArg) 80 console.log(`adding ${defaultSslArg}`) 82 } else if (container.args[sslI] !== defaultSslArg) { 83 container.args[sslI] = defaultSslArg 84 console.log(`updating to ${defaultSslArg}`) 89 console.log('ingress-nginx controller already configured') 96const ingressCacheHttpSnippet = 'proxy_cache_path /tmp/nginx-cache levels=1:2 keys_zone=nginx-cache:10m max_size=500m inactive=60m use_temp_path=off;' 98const patchIngressCacheConfig = async ({cluster_name}: {cluster_name: string}) => { 104 metadata: { name: 'ingress-nginx-controller', namespace: 'ingress-nginx' }, 109 const checksum = calcHash(ingressCacheHttpSnippet + '|true|Critical') 110 const cmReady = cm.data?.['http-snippet']?.includes('nginx-cache') && cm.data?.['allow-snippet-annotations'] === 'true' 115 apiVersion: 'apps/v1', 117 metadata: { name: 'ingress-nginx-controller', namespace: 'ingress-nginx' }, 121 deploy.spec.template.metadata.annotations = deploy.spec.template.metadata.annotations || {} 122 const currentChecksum = deploy.spec.template.metadata.annotations['checksum/config'] 124 if (cmReady && currentChecksum === checksum) return 127 cm.data = cm.data || {} 128 cm.data['http-snippet'] = ingressCacheHttpSnippet 129 cm.data['allow-snippet-annotations'] = 'true' 130 cm.data['annotation-risk-level'] = 'Critical' 131 console.log('patching ingress-nginx ConfigMap with proxy_cache_path + snippet annotations') 135 deploy.spec.template.metadata.annotations['checksum/config'] = checksum 136 console.log('restarting ingress-nginx controller to pick up ConfigMap changes') 142 apiVersion: 'admissionregistration.k8s.io/v1', 143 kind: 'ValidatingWebhookConfiguration', 144 metadata: { name: 'ingress-nginx-admission' }, 148 console.log('removing ingress-nginx admission webhook (blocks configuration-snippet annotations)')