As explained in #102, the compose-go package changes types and needs massive changes. This branches is OK for now, but needs some tests. It MUST be quickly fixed to be integrated in main branch.
204 lines
5.2 KiB
Go
204 lines
5.2 KiB
Go
package generator
|
|
|
|
import (
|
|
"katenary/generator/labels"
|
|
"katenary/generator/labels/labelStructs"
|
|
"katenary/utils"
|
|
"log"
|
|
"strings"
|
|
|
|
"github.com/compose-spec/compose-go/v2/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:"-"`
|
|
appName string `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
|
|
if label, ok = service.Labels[labels.LabelIngress]; !ok {
|
|
return nil
|
|
}
|
|
|
|
mapping, err := labelStructs.IngressFrom(label)
|
|
if err != nil {
|
|
log.Fatalf("Failed to parse ingress label: %s\n", err)
|
|
}
|
|
if mapping.Hostname == "" {
|
|
mapping.Hostname = service.Name + ".tld"
|
|
}
|
|
|
|
// create the ingress
|
|
pathType := networkv1.PathTypeImplementationSpecific
|
|
|
|
// fix the service name, and create the full name from variable name
|
|
// which is injected in the YAML() method
|
|
serviceName := strings.ReplaceAll(service.Name, "_", "-")
|
|
fullName := `{{ $fullname }}-` + serviceName
|
|
|
|
// Add the ingress host to the values.yaml
|
|
if Chart.Values[service.Name] == nil {
|
|
Chart.Values[service.Name] = &Value{}
|
|
}
|
|
|
|
Chart.Values[service.Name].(*Value).Ingress = &IngressValue{
|
|
Enabled: mapping.Enabled,
|
|
Path: *mapping.Path,
|
|
Host: mapping.Hostname,
|
|
Class: *mapping.Class,
|
|
Annotations: mapping.Annotations,
|
|
TLS: TLS{Enabled: mapping.TLS.Enabled},
|
|
}
|
|
|
|
// ingressClassName := `{{ .Values.` + service.Name + `.ingress.class }}`
|
|
ingressClassName := utils.TplValue(service.Name, "ingress.class")
|
|
|
|
servicePortName := utils.GetServiceNameByPort(int(*mapping.Port))
|
|
ingressService := &networkv1.IngressServiceBackend{
|
|
Name: fullName,
|
|
Port: networkv1.ServiceBackendPort{},
|
|
}
|
|
if servicePortName != "" {
|
|
ingressService.Port.Name = servicePortName
|
|
} else {
|
|
ingressService.Port.Number = *mapping.Port
|
|
}
|
|
|
|
ing := &Ingress{
|
|
service: &service,
|
|
appName: appName,
|
|
Ingress: &networkv1.Ingress{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "Ingress",
|
|
APIVersion: "networking.k8s.io/v1",
|
|
},
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: fullName,
|
|
Labels: GetLabels(serviceName, appName),
|
|
Annotations: Annotations,
|
|
},
|
|
Spec: networkv1.IngressSpec{
|
|
IngressClassName: &ingressClassName,
|
|
Rules: []networkv1.IngressRule{
|
|
{
|
|
Host: utils.TplValue(serviceName, "ingress.host"),
|
|
IngressRuleValue: networkv1.IngressRuleValue{
|
|
HTTP: &networkv1.HTTPIngressRuleValue{
|
|
Paths: []networkv1.HTTPIngressPath{
|
|
{
|
|
Path: utils.TplValue(serviceName, "ingress.path"),
|
|
PathType: &pathType,
|
|
Backend: networkv1.IngressBackend{
|
|
Service: ingressService,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
TLS: []networkv1.IngressTLS{
|
|
{
|
|
Hosts: []string{
|
|
`{{ tpl .Values.` + serviceName + `.ingress.host . }}`,
|
|
},
|
|
SecretName: `{{ .Values.` + serviceName + `.ingress.tls.secretName | default $tlsname }}`,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
return ing
|
|
}
|
|
|
|
func (ingress *Ingress) Filename() string {
|
|
return ingress.service.Name + ".ingress.yaml"
|
|
}
|
|
|
|
func (ingress *Ingress) Yaml() ([]byte, error) {
|
|
var ret []byte
|
|
var err error
|
|
if ret, err = ToK8SYaml(ingress); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
serviceName := ingress.service.Name
|
|
|
|
ret = UnWrapTPL(ret)
|
|
|
|
lines := strings.Split(string(ret), "\n")
|
|
|
|
// first pass, wrap the tls part with `{{- if .Values.serviceName.ingress.tlsEnabled -}}`
|
|
// and `{{- end -}}`
|
|
|
|
from, to, spaces := -1, -1, -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 -}}`
|
|
}
|
|
|
|
out := []string{
|
|
`{{- if .Values.` + serviceName + `.ingress.enabled -}}`,
|
|
`{{- $fullname := include "` + ingress.appName + `.fullname" . -}}`,
|
|
`{{- $tlsname := printf "%s-%s-tls" $fullname "` + ingress.service.Name + `" -}}`,
|
|
}
|
|
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
|
|
}
|