/
upstream.go
124 lines (114 loc) · 3.41 KB
/
upstream.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package kongstate
import (
"github.com/kong/go-kong/kong"
corev1 "k8s.io/api/core/v1"
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
"github.com/kong/kubernetes-ingress-controller/v2/internal/annotations"
kongv1 "github.com/kong/kubernetes-ingress-controller/v2/pkg/apis/configuration/v1"
)
// Upstream is a wrapper around Upstream object in Kong.
type Upstream struct {
kong.Upstream
Targets []Target
// Service this upstream is associated with.
Service Service
}
func (u *Upstream) overrideHostHeader(anns map[string]string) {
if u == nil {
return
}
host := annotations.ExtractHostHeader(anns)
if host == "" {
return
}
u.HostHeader = kong.String(host)
}
// overrideByAnnotation modifies the Kong upstream based on annotations
// on the Kubernetes service.
func (u *Upstream) overrideByAnnotation(anns map[string]string) {
if u == nil {
return
}
u.overrideHostHeader(anns)
}
// overrideByKongIngress modifies the Kong upstream based on KongIngresses
// associated with the Kubernetes service.
func (u *Upstream) overrideByKongIngress(kongIngress *kongv1.KongIngress) {
if u == nil {
return
}
if kongIngress == nil || kongIngress.Upstream == nil {
return
}
k := kongIngress.Upstream
if k.HostHeader != nil {
u.HostHeader = kong.String(*k.HostHeader)
}
if k.Algorithm != nil {
u.Algorithm = kong.String(*k.Algorithm)
}
if k.Slots != nil {
u.Slots = kong.Int(*k.Slots)
}
if k.Healthchecks != nil {
u.Healthchecks = k.Healthchecks
}
if k.HashOn != nil {
u.HashOn = kong.String(*k.HashOn)
}
if k.HashFallback != nil {
u.HashFallback = kong.String(*k.HashFallback)
}
if k.HashOnHeader != nil {
u.HashOnHeader = kong.String(*k.HashOnHeader)
}
if k.HashFallbackHeader != nil {
u.HashFallbackHeader = kong.String(*k.HashFallbackHeader)
}
if k.HashOnCookie != nil {
u.HashOnCookie = kong.String(*k.HashOnCookie)
}
if k.HashOnCookiePath != nil {
u.HashOnCookiePath = kong.String(*k.HashOnCookiePath)
}
if k.HashOnQueryArg != nil {
u.HashOnQueryArg = kong.String(*k.HashOnQueryArg)
}
if k.HashFallbackQueryArg != nil {
u.HashFallbackQueryArg = kong.String(*k.HashFallbackQueryArg)
}
if k.HashOnURICapture != nil {
u.HashOnURICapture = kong.String(*k.HashOnURICapture)
}
if k.HashFallbackURICapture != nil {
u.HashFallbackURICapture = kong.String(*k.HashFallbackURICapture)
}
// TODO https://github.com/Kong/kubernetes-ingress-controller/issues/2075
}
// override sets Upstream fields by KongIngress first, then by k8s Service's annotations.
func (u *Upstream) override(
kongIngress *kongv1.KongIngress,
svc *corev1.Service,
) {
if u == nil {
return
}
if u.Service.Parent != nil && kongIngress != nil {
// If the parent object behind Kong Upstream's is a Gateway API object
// (probably *Route) then check if we're trying to override said Service
// configuration with a KongIngress object and if that's the case then
// skip it since those should not be affected.
gvk := u.Service.Parent.GetObjectKind().GroupVersionKind()
if gvk.Group == gatewayv1alpha2.GroupName {
// No log needed here as there will be one issued already from Kong's
// Service override. The reason for this is that there is no other
// object in Kubernetes that creates a Kong's Upstream and Kubernetes
// Service will already trigger Kong's Service creation and log issuance.
return
}
}
u.overrideByKongIngress(kongIngress)
if svc != nil {
u.overrideByAnnotation(svc.Annotations)
}
}