Now, use traefik
Ingress-nginx is now deprecated, so we changed ingress management: - traefik is now the default ingress class to use - we add traefik ingressroute management too
This commit is contained in:
186
internal/generator/ingressroute.go
Normal file
186
internal/generator/ingressroute.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package generator
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"katenary.io/internal/generator/labels/labelstructs"
|
||||
"katenary.io/internal/utils"
|
||||
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
var _ Yaml = (*IngressRoute)(nil)
|
||||
|
||||
// IngressRoute represents a Traefik IngressRoute CRD
|
||||
type IngressRoute struct {
|
||||
metav1.TypeMeta `yaml:",inline"`
|
||||
metav1.ObjectMeta `yaml:"metadata"`
|
||||
Spec IngressRouteSpec `yaml:"spec"`
|
||||
service *types.ServiceConfig `yaml:"-"`
|
||||
appName string `yaml:"-"`
|
||||
serviceName string `yaml:"-"`
|
||||
}
|
||||
|
||||
// IngressRouteSpec defines the spec for Traefik IngressRoute
|
||||
type IngressRouteSpec struct {
|
||||
EntryPoints []string `json:"entryPoints,omitempty" yaml:"entryPoints,omitempty"`
|
||||
Routes []IngressRouteRoute `json:"routes" yaml:"routes"`
|
||||
TLS *IngressRouteTLS `json:"tls,omitempty" yaml:"tls,omitempty"`
|
||||
}
|
||||
|
||||
// IngressRouteRoute defines a route in the IngressRoute
|
||||
type IngressRouteRoute struct {
|
||||
Match string `json:"match" yaml:"match"`
|
||||
Kind string `json:"kind" yaml:"kind"`
|
||||
Services []IngressRouteService `json:"services" yaml:"services"`
|
||||
}
|
||||
|
||||
// IngressRouteService defines a service backend in IngressRoute
|
||||
type IngressRouteService struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Port int `json:"port" yaml:"port"`
|
||||
}
|
||||
|
||||
// IngressRouteTLS defines TLS configuration for IngressRoute
|
||||
type IngressRouteTLS struct {
|
||||
SecretName string `json:"secretName,omitempty" yaml:"secretName,omitempty"`
|
||||
Domains []IngressRouteTLSDomain `json:"domains,omitempty" yaml:"domains,omitempty"`
|
||||
}
|
||||
|
||||
// IngressRouteTLSDomain defines a domain for TLS
|
||||
type IngressRouteTLSDomain struct {
|
||||
Main string `json:"main" yaml:"main"`
|
||||
}
|
||||
|
||||
// NewIngressRoute creates a new Traefik IngressRoute from a compose service.
|
||||
func NewIngressRoute(service types.ServiceConfig, Chart *HelmChart, mapping *labelstructs.Ingress, serviceName, appName string) *IngressRoute {
|
||||
fullName := `{{ $fullname }}-` + serviceName
|
||||
|
||||
// Build the route match rule
|
||||
match := `Host("{{ tpl .Values.` + serviceName + `.ingress.host . }}")`
|
||||
path := utils.TplValue(serviceName, "ingress.path")
|
||||
if path != "/" && path != "" {
|
||||
match += ` && PathPrefix("` + path + `")`
|
||||
}
|
||||
|
||||
ir := &IngressRoute{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "IngressRoute",
|
||||
APIVersion: "traefik.io/v1alpha1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fullName,
|
||||
Labels: GetLabels(serviceName, appName),
|
||||
Annotations: Annotations,
|
||||
},
|
||||
Spec: IngressRouteSpec{
|
||||
EntryPoints: []string{"web", "websecure"},
|
||||
Routes: []IngressRouteRoute{
|
||||
{
|
||||
Match: match,
|
||||
Kind: "Rule",
|
||||
Services: []IngressRouteService{
|
||||
{
|
||||
Name: fullName,
|
||||
Port: int(*mapping.Port),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
service: &service,
|
||||
appName: appName,
|
||||
serviceName: serviceName,
|
||||
}
|
||||
|
||||
// Add TLS configuration if enabled
|
||||
if mapping.TLS != nil && mapping.TLS.Enabled {
|
||||
tlsSecretName := `{{ .Values.` + serviceName + `.ingress.tls.secretName | default $tlsname }}`
|
||||
ir.Spec.TLS = &IngressRouteTLS{
|
||||
SecretName: tlsSecretName,
|
||||
Domains: []IngressRouteTLSDomain{
|
||||
{
|
||||
Main: `{{ tpl .Values.` + serviceName + `.ingress.host . }}`,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return ir
|
||||
}
|
||||
|
||||
func (ir *IngressRoute) Filename() string {
|
||||
return ir.serviceName + ".ingressroute.yaml"
|
||||
}
|
||||
|
||||
func (ir *IngressRoute) Yaml() ([]byte, error) {
|
||||
var ret []byte
|
||||
var err error
|
||||
|
||||
// Manually construct YAML - sigs.k8s.io/yaml doesn't handle metav1.ObjectMeta
|
||||
// with yaml:"metadata" correctly unless embedded in a standard K8s type with JSON tags.
|
||||
// We build the YAML as a string to ensure proper nesting.
|
||||
|
||||
// Build metadata block
|
||||
metadata, err := yaml.Marshal(map[string]interface{}{
|
||||
"name": ir.Name,
|
||||
"labels": ir.Labels,
|
||||
"annotations": ir.Annotations,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Build spec block
|
||||
spec, err := yaml.Marshal(ir.Spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Build final YAML with proper structure
|
||||
ret = []byte("apiVersion: " + ir.APIVersion + "\n")
|
||||
ret = append(ret, "kind: "+ir.Kind+"\n"...)
|
||||
ret = append(ret, "metadata:\n"...)
|
||||
// Indent metadata content by 2 spaces
|
||||
for _, line := range strings.Split(strings.TrimRight(string(metadata), "\n"), "\n") {
|
||||
ret = append(ret, " "+line+"\n"...)
|
||||
}
|
||||
ret = append(ret, "spec:\n"...)
|
||||
// Indent spec content by 2 spaces
|
||||
for _, line := range strings.Split(strings.TrimRight(string(spec), "\n"), "\n") {
|
||||
ret = append(ret, " "+line+"\n"...)
|
||||
}
|
||||
|
||||
ret = UnWrapTPL(ret)
|
||||
|
||||
lines := strings.Split(string(ret), "\n")
|
||||
|
||||
out := []string{
|
||||
`{{- if .Values.` + ir.serviceName + `.ingress.ingressRouteEnabled -}}`,
|
||||
`{{- $fullname := include "` + ir.appName + `.fullname" . -}}`,
|
||||
`{{- $tlsname := printf "%s-%s-tls" $fullname "` + ir.serviceName + `" -}}`,
|
||||
}
|
||||
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, "labels:") {
|
||||
// add annotations above labels from values.yaml (inside metadata block)
|
||||
indent := strings.Repeat(" ", utils.CountStartingSpaces(line))
|
||||
content := `` +
|
||||
indent + `{{- if .Values.` + ir.serviceName + `.ingress.annotations -}}` + "\n" +
|
||||
indent + ` {{- toYaml .Values.` + ir.serviceName + `.ingress.annotations | nindent __indent__ }}` + "\n" +
|
||||
indent + ` {{- end }}` + "\n" +
|
||||
line
|
||||
|
||||
out = append(out, content)
|
||||
} else {
|
||||
out = append(out, line)
|
||||
}
|
||||
}
|
||||
out = append(out, `{{- end -}}`)
|
||||
ret = []byte(strings.Join(out, "\n"))
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user