// K8s Ingress schema + YAML generator for ConfTemplate // Generated: 2026-07-18 export const k8sIngressSchema = { id: 'k8s-ingress', name: 'K8s Ingress', icon: 'Globe', category: '云原生', description: 'Kubernetes Ingress 网络入口资源', format: 'yaml', fileName: 'ingress.yaml', groups: [ { title: '基础信息', fields: [ { key: 'name', label: 'Ingress 名称', type: 'text', placeholder: 'my-ingress', default: 'my-ingress', required: true, tip: '将用作 Ingress 资源名称', }, { key: 'namespace', label: '命名空间', type: 'text', placeholder: 'default', default: 'default', }, { key: 'ingressClassName', label: 'Ingress Class', type: 'select', options: [ { label: 'nginx', value: 'nginx' }, { label: 'traefik', value: 'traefik' }, { label: '(不指定)', value: '' }, ], default: 'nginx', tip: '选择 Ingress 控制器类型', }, ], }, { title: '路由规则', fields: [ { key: 'host', label: '域名', type: 'text', placeholder: 'example.com', default: 'example.com', required: true, tip: '匹配的主机名', }, { key: 'path', label: '路径', type: 'text', placeholder: '/', default: '/', }, { key: 'pathType', label: '路径类型', type: 'select', options: [ { label: 'Prefix', value: 'Prefix' }, { label: 'Exact', value: 'Exact' }, { label: 'ImplementationSpecific', value: 'ImplementationSpecific' }, ], default: 'Prefix', }, { key: 'backendServiceName', label: '后端 Service 名称', type: 'text', placeholder: 'my-service', default: '', required: true, tip: '流量转发到的 Service 名称', }, { key: 'backendServicePort', label: '后端 Service 端口', type: 'number', min: 1, max: 65535, default: 80, required: true, }, ], }, { title: 'TLS 配置', fields: [ { key: 'enableTls', label: '启用 TLS', type: 'switch', default: false, tip: '开启 HTTPS 终止', }, { key: 'tlsSecretName', label: 'TLS Secret 名称', type: 'text', placeholder: 'my-tls-secret', default: '', dependsOn: 'enableTls', tip: '包含 TLS 证书的 Secret 名称', }, ], }, { title: 'Annotations', fields: [ { key: 'enableCors', label: '启用 CORS', type: 'switch', default: false, tip: '添加 nginx.ingress.kubernetes.io/enable-cors 注解', }, { key: 'rewriteTarget', label: '启用路径重写', type: 'switch', default: false, tip: '添加 nginx.ingress.kubernetes.io/rewrite-target 注解', }, ], }, ], } function yamlScalar(v) { if (v === null || v === undefined) return '' if (typeof v === 'number' || typeof v === 'boolean') return String(v) const s = String(v) if (/[:#\n"'`]|^[\s\-]|[\s]$/.test(s) || /^(true|false|null|yes|no|on|off|~)$/i.test(s)) { return JSON.stringify(s) } return s } function isEmptyMapping(o) { if (!o || typeof o !== 'object' || Array.isArray(o)) return false return Object.values(o).every(v => v === null || v === undefined || v === '' || (typeof v === 'object' && isEmptyMapping(v))) } function toYaml(obj, baseIndent = '') { const lines = [] for (const [key, value] of Object.entries(obj)) { if (value === null || value === undefined || value === '') continue if (Array.isArray(value)) { const items = value.filter(v => v !== null && v !== undefined && v !== '') if (!items.length) continue lines.push(`${baseIndent}${key}:`) for (const item of items) { if (item && typeof item === 'object' && !Array.isArray(item)) { if (isEmptyMapping(item)) continue const entries = Object.entries(item).filter(([, v]) => v !== null && v !== undefined && v !== '') if (!entries.length) continue const childIndent = baseIndent + ' ' const subAllIndent = childIndent + ' ' const subObj = {} for (const [k, v] of entries) subObj[k] = v const subRendered = toYaml(subObj, subAllIndent) const subLines = subRendered.split('\n') if (subLines[0].startsWith(subAllIndent)) { subLines[0] = childIndent + '- ' + subLines[0].slice(subAllIndent.length) } else { subLines[0] = childIndent + '- ' + subLines[0].trimStart() } lines.push(...subLines) } else { lines.push(`${baseIndent} - ${yamlScalar(item)}`) } } } else if (typeof value === 'object') { if (isEmptyMapping(value)) { lines.push(`${baseIndent}${key}: {}`) continue } lines.push(`${baseIndent}${key}:`) const childIndent = baseIndent + ' ' lines.push(toYaml(value, childIndent)) } else { lines.push(`${baseIndent}${key}: ${yamlScalar(value)}`) } } return lines.join('\n') } export function generateK8sIngressYaml(config) { const annotations = {} if (config.enableCors) { annotations['nginx.ingress.kubernetes.io/enable-cors'] = 'true' } if (config.rewriteTarget) { annotations['nginx.ingress.kubernetes.io/rewrite-target'] = '/' } const ingress = { apiVersion: 'networking.k8s.io/v1', kind: 'Ingress', metadata: { name: config.name, namespace: config.namespace, annotations: Object.keys(annotations).length > 0 ? annotations : undefined, }, spec: { ingressClassName: config.ingressClassName || undefined, rules: [ { host: config.host, http: { paths: [ { path: config.path, pathType: config.pathType, backend: { service: { name: config.backendServiceName, port: { number: Number(config.backendServicePort), }, }, }, }, ], }, }, ], }, } if (config.enableTls && config.tlsSecretName) { ingress.spec.tls = [ { hosts: [config.host], secretName: config.tlsSecretName, }, ] } const header = `# K8s Ingress - 由 ConfTemplate 生成 # 生成时间: ${new Date().toLocaleString('zh-CN')} # 部署命令: kubectl apply -f ${config.fileName || 'ingress.yaml'} ` return header + '\n' + toYaml(ingress) }