2023-12-06 15:24:02 +01:00
|
|
|
package generator
|
|
|
|
|
|
|
|
import (
|
2024-11-18 17:12:12 +01:00
|
|
|
"katenary/generator/labels"
|
|
|
|
"katenary/generator/labels/labelStructs"
|
2024-11-08 13:11:14 +01:00
|
|
|
"katenary/utils"
|
2023-12-06 15:24:02 +01:00
|
|
|
"log"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/compose-spec/compose-go/types"
|
|
|
|
networkv1 "k8s.io/api/networking/v1"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ Yaml = (*Ingress)(nil)
|
|
|
|
|
|
|
|
type Ingress struct {
|
|
|
|
*networkv1.Ingress
|
|
|
|
service *types.ServiceConfig `yaml:"-"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewIngress creates a new Ingress from a compose service.
|
|
|
|
func NewIngress(service types.ServiceConfig, Chart *HelmChart) *Ingress {
|
|
|
|
appName := Chart.Name
|
|
|
|
|
|
|
|
if service.Labels == nil {
|
|
|
|
service.Labels = make(map[string]string)
|
|
|
|
}
|
|
|
|
var label string
|
|
|
|
var ok bool
|
2024-11-18 17:12:12 +01:00
|
|
|
if label, ok = service.Labels[labels.LabelIngress]; !ok {
|
2023-12-06 15:24:02 +01:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-04-24 23:06:45 +02:00
|
|
|
mapping, err := labelStructs.IngressFrom(label)
|
|
|
|
if err != nil {
|
2023-12-06 15:24:02 +01:00
|
|
|
log.Fatalf("Failed to parse ingress label: %s\n", err)
|
|
|
|
}
|
2024-04-24 23:06:45 +02:00
|
|
|
if mapping.Hostname == "" {
|
|
|
|
mapping.Hostname = service.Name + ".tld"
|
|
|
|
}
|
2023-12-06 15:24:02 +01:00
|
|
|
|
|
|
|
// create the ingress
|
|
|
|
pathType := networkv1.PathTypeImplementationSpecific
|
|
|
|
serviceName := `{{ include "` + appName + `.fullname" . }}-` + service.Name
|
|
|
|
|
|
|
|
// Add the ingress host to the values.yaml
|
|
|
|
if Chart.Values[service.Name] == nil {
|
|
|
|
Chart.Values[service.Name] = &Value{}
|
|
|
|
}
|
2024-04-03 22:44:41 +02:00
|
|
|
|
2023-12-06 15:24:02 +01:00
|
|
|
Chart.Values[service.Name].(*Value).Ingress = &IngressValue{
|
2024-04-24 23:06:45 +02:00
|
|
|
Enabled: mapping.Enabled,
|
|
|
|
Path: mapping.Path,
|
|
|
|
Host: mapping.Hostname,
|
|
|
|
Class: mapping.Class,
|
|
|
|
Annotations: mapping.Annotations,
|
2024-11-08 16:55:18 +01:00
|
|
|
TLS: TLS{Enabled: mapping.TLS.Enabled},
|
2023-12-06 15:24:02 +01:00
|
|
|
}
|
|
|
|
|
2024-04-05 07:56:27 +02:00
|
|
|
// ingressClassName := `{{ .Values.` + service.Name + `.ingress.class }}`
|
2023-12-06 15:24:02 +01:00
|
|
|
ingressClassName := utils.TplValue(service.Name, "ingress.class")
|
|
|
|
|
2024-04-24 23:06:45 +02:00
|
|
|
servicePortName := utils.GetServiceNameByPort(int(*mapping.Port))
|
2023-12-06 15:24:02 +01:00
|
|
|
ingressService := &networkv1.IngressServiceBackend{
|
|
|
|
Name: serviceName,
|
|
|
|
Port: networkv1.ServiceBackendPort{},
|
|
|
|
}
|
|
|
|
if servicePortName != "" {
|
|
|
|
ingressService.Port.Name = servicePortName
|
|
|
|
} else {
|
2024-04-24 23:06:45 +02:00
|
|
|
ingressService.Port.Number = *mapping.Port
|
2023-12-06 15:24:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ing := &Ingress{
|
|
|
|
service: &service,
|
|
|
|
Ingress: &networkv1.Ingress{
|
|
|
|
TypeMeta: metav1.TypeMeta{
|
|
|
|
Kind: "Ingress",
|
|
|
|
APIVersion: "networking.k8s.io/v1",
|
|
|
|
},
|
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
|
Name: utils.TplName(service.Name, appName),
|
|
|
|
Labels: GetLabels(service.Name, appName),
|
|
|
|
Annotations: Annotations,
|
|
|
|
},
|
|
|
|
Spec: networkv1.IngressSpec{
|
|
|
|
IngressClassName: &ingressClassName,
|
|
|
|
Rules: []networkv1.IngressRule{
|
|
|
|
{
|
|
|
|
Host: utils.TplValue(service.Name, "ingress.host"),
|
|
|
|
IngressRuleValue: networkv1.IngressRuleValue{
|
|
|
|
HTTP: &networkv1.HTTPIngressRuleValue{
|
|
|
|
Paths: []networkv1.HTTPIngressPath{
|
|
|
|
{
|
|
|
|
Path: utils.TplValue(service.Name, "ingress.path"),
|
|
|
|
PathType: &pathType,
|
|
|
|
Backend: networkv1.IngressBackend{
|
|
|
|
Service: ingressService,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
TLS: []networkv1.IngressTLS{
|
|
|
|
{
|
|
|
|
Hosts: []string{
|
|
|
|
`{{ tpl .Values.` + service.Name + `.ingress.host . }}`,
|
|
|
|
},
|
|
|
|
SecretName: `{{ include "` + appName + `.fullname" . }}-` + service.Name + `-tls`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
return ing
|
|
|
|
}
|
|
|
|
|
2024-10-17 17:08:42 +02:00
|
|
|
func (ingress *Ingress) Filename() string {
|
|
|
|
return ingress.service.Name + ".ingress.yaml"
|
|
|
|
}
|
|
|
|
|
2023-12-06 15:24:02 +01:00
|
|
|
func (ingress *Ingress) Yaml() ([]byte, error) {
|
2024-11-09 14:18:27 +01:00
|
|
|
var ret []byte
|
|
|
|
var err error
|
|
|
|
if ret, err = ToK8SYaml(ingress); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-12-06 15:24:02 +01:00
|
|
|
serviceName := ingress.service.Name
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-11-08 13:11:14 +01:00
|
|
|
ret = UnWrapTPL(ret)
|
2023-12-06 15:24:02 +01:00
|
|
|
|
|
|
|
lines := strings.Split(string(ret), "\n")
|
2024-11-08 15:51:36 +01:00
|
|
|
|
|
|
|
// first pass, wrap the tls part with `{{- if .Values.serviceName.ingress.tlsEnabled -}}`
|
|
|
|
// and `{{- end -}}`
|
|
|
|
|
|
|
|
from := -1
|
|
|
|
to := -1
|
|
|
|
spaces := -1
|
|
|
|
for i, line := range lines {
|
|
|
|
if strings.Contains(line, "tls:") {
|
|
|
|
from = i
|
|
|
|
spaces = utils.CountStartingSpaces(line)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if from > -1 {
|
|
|
|
if utils.CountStartingSpaces(line) >= spaces {
|
|
|
|
to = i
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if from > -1 && to > -1 {
|
|
|
|
lines[from] = strings.Repeat(" ", spaces) +
|
|
|
|
`{{- if .Values.` + serviceName + `.ingress.tls.enabled }}` +
|
|
|
|
"\n" +
|
|
|
|
lines[from]
|
|
|
|
lines[to] = strings.Repeat(" ", spaces) + `{{ end -}}`
|
|
|
|
}
|
|
|
|
|
2023-12-06 15:24:02 +01:00
|
|
|
out := []string{
|
|
|
|
`{{- if .Values.` + serviceName + `.ingress.enabled -}}`,
|
|
|
|
}
|
|
|
|
for _, line := range lines {
|
|
|
|
if strings.Contains(line, "loadBalancer: ") {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if strings.Contains(line, "labels:") {
|
|
|
|
// add annotations above labels from values.yaml
|
|
|
|
content := `` +
|
|
|
|
` {{- if .Values.` + serviceName + `.ingress.annotations -}}` + "\n" +
|
|
|
|
` {{- toYaml .Values.` + serviceName + `.ingress.annotations | nindent 4 }}` + "\n" +
|
|
|
|
` {{- end }}` + "\n" +
|
|
|
|
line
|
|
|
|
|
|
|
|
out = append(out, content)
|
|
|
|
} else if strings.Contains(line, "ingressClassName: ") {
|
|
|
|
content := utils.Wrap(
|
|
|
|
line,
|
|
|
|
`{{- if ne .Values.`+serviceName+`.ingress.class "-" }}`,
|
|
|
|
`{{- end }}`,
|
|
|
|
)
|
|
|
|
out = append(out, content)
|
|
|
|
} else {
|
|
|
|
out = append(out, line)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out = append(out, `{{- end -}}`)
|
|
|
|
ret = []byte(strings.Join(out, "\n"))
|
|
|
|
return ret, nil
|
|
|
|
}
|