Skip to content

Commit 9fde164

Browse files
committed
BUG: update runtime servers in HAProxy for standalone backends.
1 parent ab609d6 commit 9fde164

File tree

7 files changed

+110
-34
lines changed

7 files changed

+110
-34
lines changed

pkg/ingress/ingress.go

+18
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,24 @@ func (i *Ingress) handlePath(k store.K8s, h haproxy.HAProxy, host string, path *
7575
return
7676
}
7777
backendName, _ := svc.GetBackendName()
78+
// If we've got a standalone ingress, put an adhoc RuntimeBackend in HAProxyRuntimeStandalone
79+
// This RuntimeBackend will be used for runtime update of server lists(enpoints) in EventEndpoints
80+
if svc.IsStandalone() {
81+
ns := k.GetNamespace(i.resource.Namespace)
82+
svcHAProxyRuntimeStandalone := ns.HAProxyRuntimeStandalone[svc.GetResource().Name]
83+
if svcHAProxyRuntimeStandalone == nil {
84+
svcHAProxyRuntimeStandalone = map[string]map[string]*store.RuntimeBackend{}
85+
ns.HAProxyRuntimeStandalone[svc.GetResource().Name] = svcHAProxyRuntimeStandalone
86+
}
87+
runtimeBackends := svcHAProxyRuntimeStandalone[path.SvcPortResolved.Name]
88+
if runtimeBackends == nil {
89+
runtimeBackends = map[string]*store.RuntimeBackend{}
90+
svcHAProxyRuntimeStandalone[path.SvcPortResolved.Name] = runtimeBackends
91+
}
92+
if runtimeBackends[backendName] == nil {
93+
runtimeBackends[backendName] = &store.RuntimeBackend{Name: backendName}
94+
}
95+
}
7896
// Route
7997
ingRoute := route.Route{
8098
Host: host,

pkg/k8s/informers.go

+14-12
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ func (k k8s) getNamespaceInfomer(eventChan chan k8ssync.SyncDataEvent, factory i
4747
}
4848

4949
item := &store.Namespace{
50-
Name: data.GetName(),
51-
Endpoints: make(map[string]map[string]*store.Endpoints),
52-
Services: make(map[string]*store.Service),
53-
Ingresses: make(map[string]*store.Ingress),
54-
Secret: make(map[string]*store.Secret),
55-
HAProxyRuntime: make(map[string]map[string]*store.RuntimeBackend),
50+
Name: data.GetName(),
51+
Endpoints: make(map[string]map[string]*store.Endpoints),
52+
Services: make(map[string]*store.Service),
53+
Ingresses: make(map[string]*store.Ingress),
54+
Secret: make(map[string]*store.Secret),
55+
HAProxyRuntime: make(map[string]map[string]*store.RuntimeBackend),
56+
HAProxyRuntimeStandalone: make(map[string]map[string]map[string]*store.RuntimeBackend),
5657
CRs: &store.CustomResources{
5758
Global: make(map[string]*models.Global),
5859
Defaults: make(map[string]*models.Defaults),
@@ -75,12 +76,13 @@ func (k k8s) getNamespaceInfomer(eventChan chan k8ssync.SyncDataEvent, factory i
7576
}
7677
status := store.DELETED
7778
item := &store.Namespace{
78-
Name: data.GetName(),
79-
Endpoints: make(map[string]map[string]*store.Endpoints),
80-
Services: make(map[string]*store.Service),
81-
Ingresses: make(map[string]*store.Ingress),
82-
Secret: make(map[string]*store.Secret),
83-
HAProxyRuntime: make(map[string]map[string]*store.RuntimeBackend),
79+
Name: data.GetName(),
80+
Endpoints: make(map[string]map[string]*store.Endpoints),
81+
Services: make(map[string]*store.Service),
82+
Ingresses: make(map[string]*store.Ingress),
83+
Secret: make(map[string]*store.Secret),
84+
HAProxyRuntime: make(map[string]map[string]*store.RuntimeBackend),
85+
HAProxyRuntimeStandalone: make(map[string]map[string]map[string]*store.RuntimeBackend),
8486
CRs: &store.CustomResources{
8587
Global: make(map[string]*models.Global),
8688
Defaults: make(map[string]*models.Defaults),

pkg/service/service.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func (s *Service) GetBackendName() (name string, err error) {
124124
resourceNamespace := s.resource.Namespace
125125
resourceName := s.resource.Name
126126
prefix := ""
127-
if s.standalone && s.ingress != nil && s.ingress.Name != "" {
127+
if s.IsStandalone() && s.ingress != nil && s.ingress.Name != "" {
128128
resourceName = s.ingress.Name + "-" + s.resource.Name
129129
resourceNamespace = s.ingress.Namespace
130130
prefix = "ing_"
@@ -287,3 +287,7 @@ func (s *Service) SetDefaultBackend(k store.K8s, h haproxy.HAProxy, frontends []
287287
s.HandleHAProxySrvs(k, h)
288288
return
289289
}
290+
291+
func (s Service) IsStandalone() bool {
292+
return s.standalone
293+
}

pkg/store/events.go

+33
Original file line numberDiff line numberDiff line change
@@ -131,19 +131,52 @@ func (k *K8s) EventEndpoints(ns *Namespace, data *Endpoints, syncHAproxySrvs fun
131131
ns.HAProxyRuntime[data.Service] = make(map[string]*RuntimeBackend)
132132
}
133133
logger.Tracef("service %s : number of already existing backend(s) in this transaction for this endpoint: %d", data.Service, len(ns.HAProxyRuntime[data.Service]))
134+
// Standalone
135+
_, ok = ns.HAProxyRuntimeStandalone[data.Service]
136+
if !ok {
137+
ns.HAProxyRuntimeStandalone[data.Service] = make(map[string]map[string]*RuntimeBackend)
138+
}
134139
for key, value := range ns.HAProxyRuntime[data.Service] {
135140
logger.Tracef("service %s : port name %s, backend %+v", data.Service, key, *value)
136141
}
142+
// Standalone
143+
for portName, backendsNames := range ns.HAProxyRuntimeStandalone[data.Service] {
144+
for backendName := range backendsNames {
145+
logger.Tracef("service %s : port name %s, backend %+v", data.Service, portName, backendName)
146+
}
147+
}
137148
for portName, portEndpoints := range endpoints {
149+
// Make a copy of addresses for potential standalone runtime backend
150+
// as these addresses are consumed/removed in the process
151+
backendAddresses := utils.CopyMap(portEndpoints.Addresses)
138152
newBackend := &RuntimeBackend{Endpoints: portEndpoints}
139153
backend, ok := ns.HAProxyRuntime[data.Service][portName]
154+
// Make a copy of haproxy server list for potential standalone runtime backend
155+
// as this servere list is modified in the process
156+
var backendHAProxySrvs []*HAProxySrv
140157
if ok {
158+
backendHAProxySrvs = utils.CopySliceFunc(backend.HAProxySrvs, utils.CopyPointer)
141159
portUpdated := (newBackend.Endpoints.Port != backend.Endpoints.Port)
142160
newBackend.HAProxySrvs = backend.HAProxySrvs
143161
newBackend.Name = backend.Name
144162
logger.Warning(syncHAproxySrvs(newBackend, portUpdated))
145163
}
146164
ns.HAProxyRuntime[data.Service][portName] = newBackend
165+
166+
// Reprocuce the same steps ar regular runtime backend for each standalone runtime backend
167+
// referring to the same port and service
168+
standaloneNewBackend := &RuntimeBackend{Endpoints: portEndpoints}
169+
for standaloneBackendName, standaloneRuntimeBackend := range ns.HAProxyRuntimeStandalone[data.Service][portName] {
170+
// Make own copy of regular runtime backend portEndpoint addresses
171+
standaloneNewBackend.Endpoints.Addresses = utils.CopyMap(backendAddresses)
172+
// Make own copy of regular runtime backend portEndpoint servers list
173+
standaloneNewBackend.HAProxySrvs = utils.CopySliceFunc(backendHAProxySrvs, utils.CopyPointer)
174+
standaloneNewBackend.Name = standaloneRuntimeBackend.Name
175+
standalonePortUpdated := (standaloneNewBackend.Endpoints.Port != standaloneRuntimeBackend.Endpoints.Port)
176+
logger.Warning(syncHAproxySrvs(standaloneNewBackend, standalonePortUpdated))
177+
ns.HAProxyRuntimeStandalone[data.Service][portName][standaloneBackendName] = standaloneNewBackend
178+
standaloneNewBackend = &RuntimeBackend{Endpoints: portEndpoints}
179+
}
147180
}
148181
return true
149182
}

pkg/store/store.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ func (k *K8s) Clean() {
117117
if len(namespace.Endpoints[slice.Service]) == 0 {
118118
delete(namespace.Endpoints, slice.Service)
119119
delete(namespace.HAProxyRuntime, slice.Service)
120+
delete(namespace.HAProxyRuntimeStandalone, slice.Service)
120121
}
121122
default:
122123
slice.Status = EMPTY
@@ -167,13 +168,14 @@ func (k K8s) GetNamespace(name string) *Namespace {
167168
return namespace
168169
}
169170
newNamespace := &Namespace{
170-
Name: name,
171-
Relevant: k.isRelevantNamespace(name),
172-
Endpoints: make(map[string]map[string]*Endpoints),
173-
Services: make(map[string]*Service),
174-
Ingresses: make(map[string]*Ingress),
175-
Secret: make(map[string]*Secret),
176-
HAProxyRuntime: make(map[string]map[string]*RuntimeBackend),
171+
Name: name,
172+
Relevant: k.isRelevantNamespace(name),
173+
Endpoints: make(map[string]map[string]*Endpoints),
174+
Services: make(map[string]*Service),
175+
Ingresses: make(map[string]*Ingress),
176+
Secret: make(map[string]*Secret),
177+
HAProxyRuntime: make(map[string]map[string]*RuntimeBackend),
178+
HAProxyRuntimeStandalone: make(map[string]map[string]map[string]*RuntimeBackend),
177179
CRs: &CustomResources{
178180
Global: make(map[string]*models.Global),
179181
Defaults: make(map[string]*models.Defaults),

pkg/store/types.go

+15-14
Original file line numberDiff line numberDiff line change
@@ -86,20 +86,21 @@ type RuntimeBackend struct {
8686

8787
// Namespace is useful data from k8s structures about namespace
8888
type Namespace struct {
89-
_ [0]int
90-
Secret map[string]*Secret
91-
Ingresses map[string]*Ingress
92-
Endpoints map[string]map[string]*Endpoints // service -> sliceName -> Endpoints
93-
Services map[string]*Service
94-
HAProxyRuntime map[string]map[string]*RuntimeBackend // service -> portName -> Backend
95-
CRs *CustomResources
96-
Gateways map[string]*Gateway
97-
TCPRoutes map[string]*TCPRoute
98-
ReferenceGrants map[string]*ReferenceGrant
99-
Labels map[string]string
100-
Name string
101-
Status Status
102-
Relevant bool
89+
_ [0]int
90+
Secret map[string]*Secret
91+
Ingresses map[string]*Ingress
92+
Endpoints map[string]map[string]*Endpoints // service -> sliceName -> Endpoints
93+
Services map[string]*Service
94+
HAProxyRuntime map[string]map[string]*RuntimeBackend // service -> portName -> Backend
95+
HAProxyRuntimeStandalone map[string]map[string]map[string]*RuntimeBackend // service -> portName -> backendName -> Backend
96+
CRs *CustomResources
97+
Gateways map[string]*Gateway
98+
TCPRoutes map[string]*TCPRoute
99+
ReferenceGrants map[string]*ReferenceGrant
100+
Labels map[string]string
101+
Name string
102+
Status Status
103+
Relevant bool
103104
}
104105

105106
type CustomResources struct {

pkg/utils/utils.go

+16
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,19 @@ func JSONDiff(diffs map[string][]interface{}) string {
229229
}
230230
return string(diffRule)
231231
}
232+
233+
func CopySliceFunc[T any](slice []T, f func(T) T) (clone []T) {
234+
clone = make([]T, 0, len(slice))
235+
for _, t := range slice {
236+
clone = append(clone, f(t))
237+
}
238+
return
239+
}
240+
241+
func CopyPointer[T any](a *T) *T {
242+
if a == nil {
243+
return nil
244+
}
245+
clone := *a
246+
return &clone
247+
}

0 commit comments

Comments
 (0)