/
traefik_ingressroute.go
96 lines (80 loc) · 2.74 KB
/
traefik_ingressroute.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package workspace
import (
"fmt"
"strings"
traefikv1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
ctrl "sigs.k8s.io/controller-runtime"
cosmov1alpha1 "github.com/cosmo-workspace/cosmo/api/v1alpha1"
"github.com/cosmo-workspace/cosmo/pkg/instance"
)
type TraefikIngressRouteConfig struct {
// Entrypoints is the entrypoint of traefik ingress route
Entrypoints []string
// TLS is the TLS of traefik ingress route
TLS *traefikv1.TLS
// AuthenMiddleware is the name and namespace of middleware for cosmo-auth
// Namespace must be the same as where trafik LB is running
AuthenMiddleware traefikv1.MiddlewareRef
// UserNameHeaderMiddlewareName is the name of middleware for username header
// Namespace must be empty to be the same as the workspace
UserNameHeaderMiddleware traefikv1.MiddlewareRef
// HostBase is a base of hostname
HostBase string
// Domain is a domain of hostname
Domain string
}
func (c *TraefikIngressRouteConfig) PatchTraefikIngressRouteAsDesired(ir *traefikv1.IngressRoute, ws cosmov1alpha1.Workspace, scheme *runtime.Scheme) error {
// metadata
cosmov1alpha1.SetControllerManaged(ir)
// spec.entrypoints
ir.Spec.EntryPoints = c.Entrypoints
// spec.tls
ir.Spec.TLS = c.TLS
// spec.routes
routes := make([]traefikv1.Route, 0, len(ws.Spec.Network))
for _, netRule := range ws.Spec.Network {
traefikRule := c.TraefikRoute(netRule, ws)
routes = append(routes, traefikRule)
}
ir.Spec.Routes = routes
if scheme != nil {
err := ctrl.SetControllerReference(&ws, ir, scheme)
if err != nil {
return fmt.Errorf("failed to set owner reference: %w", err)
}
}
return nil
}
func (c *TraefikIngressRouteConfig) TraefikRoute(r cosmov1alpha1.NetworkRule, ws cosmov1alpha1.Workspace) traefikv1.Route {
matches := []string{}
matches = append(matches, fmt.Sprintf("Host(`%s`)", cosmov1alpha1.GenHost(c.HostBase, c.Domain, r.HostPrefix(), ws)))
if r.HTTPPath != "" && r.HTTPPath != "/" {
matches = append(matches, fmt.Sprintf("PathPrefix(`%s`)", r.HTTPPath))
}
match := strings.Join(matches[:], " && ")
var middlewares []traefikv1.MiddlewareRef
if r.Public {
middlewares = []traefikv1.MiddlewareRef{}
} else {
middlewares = []traefikv1.MiddlewareRef{c.UserNameHeaderMiddleware, c.AuthenMiddleware}
}
backendSvcName := instance.InstanceResourceName(ws.Name, ws.Status.Config.ServiceName)
return traefikv1.Route{
Kind: "Rule",
Match: match,
Priority: 100,
Services: []traefikv1.Service{
{
LoadBalancerSpec: traefikv1.LoadBalancerSpec{
Kind: "Service",
Name: backendSvcName,
Port: intstr.FromInt(int(r.PortNumber)),
Scheme: "http",
},
},
},
Middlewares: middlewares,
}
}