Skip to content

Commit 1f08caf

Browse files
committed
BUG: update runtime servers in HAProxy for standalone backends.
1 parent 8ec89c8 commit 1f08caf

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
@@ -119,6 +119,24 @@ func (i *Ingress) handlePath(k store.K8s, h haproxy.HAProxy, host string, path *
119119
return
120120
}
121121
backendName, _ := svc.GetBackendName()
122+
// If we've got a standalone ingress, put an adhoc RuntimeBackend in HAProxyRuntimeStandalone
123+
// This RuntimeBackend will be used for runtime update of server lists(enpoints) in EventEndpoints
124+
if svc.IsStandalone() {
125+
ns := k.GetNamespace(i.resource.Namespace)
126+
svcHAProxyRuntimeStandalone := ns.HAProxyRuntimeStandalone[svc.GetResource().Name]
127+
if svcHAProxyRuntimeStandalone == nil {
128+
svcHAProxyRuntimeStandalone = map[string]map[string]*store.RuntimeBackend{}
129+
ns.HAProxyRuntimeStandalone[svc.GetResource().Name] = svcHAProxyRuntimeStandalone
130+
}
131+
runtimeBackends := svcHAProxyRuntimeStandalone[path.SvcPortResolved.Name]
132+
if runtimeBackends == nil {
133+
runtimeBackends = map[string]*store.RuntimeBackend{}
134+
svcHAProxyRuntimeStandalone[path.SvcPortResolved.Name] = runtimeBackends
135+
}
136+
if runtimeBackends[backendName] == nil {
137+
runtimeBackends[backendName] = &store.RuntimeBackend{Name: backendName}
138+
}
139+
}
122140
// Route
123141
ingRoute := route.Route{
124142
Host: host,

pkg/k8s/informers.go

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

4747
item := &store.Namespace{
48-
Name: data.GetName(),
49-
Endpoints: make(map[string]map[string]*store.Endpoints),
50-
Services: make(map[string]*store.Service),
51-
Ingresses: make(map[string]*store.Ingress),
52-
Secret: make(map[string]*store.Secret),
53-
HAProxyRuntime: make(map[string]map[string]*store.RuntimeBackend),
48+
Name: data.GetName(),
49+
Endpoints: make(map[string]map[string]*store.Endpoints),
50+
Services: make(map[string]*store.Service),
51+
Ingresses: make(map[string]*store.Ingress),
52+
Secret: make(map[string]*store.Secret),
53+
HAProxyRuntime: make(map[string]map[string]*store.RuntimeBackend),
54+
HAProxyRuntimeStandalone: make(map[string]map[string]map[string]*store.RuntimeBackend),
5455
CRs: &store.CustomResources{
5556
Global: make(map[string]*models.Global),
5657
Defaults: make(map[string]*models.Defaults),
@@ -74,12 +75,13 @@ func (k k8s) getNamespaceInfomer(eventChan chan k8ssync.SyncDataEvent, factory i
7475
}
7576
status := store.DELETED
7677
item := &store.Namespace{
77-
Name: data.GetName(),
78-
Endpoints: make(map[string]map[string]*store.Endpoints),
79-
Services: make(map[string]*store.Service),
80-
Ingresses: make(map[string]*store.Ingress),
81-
Secret: make(map[string]*store.Secret),
82-
HAProxyRuntime: make(map[string]map[string]*store.RuntimeBackend),
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),
84+
HAProxyRuntimeStandalone: make(map[string]map[string]map[string]*store.RuntimeBackend),
8385
CRs: &store.CustomResources{
8486
Global: make(map[string]*models.Global),
8587
Defaults: make(map[string]*models.Defaults),

pkg/service/service.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (s *Service) GetBackendName() (name string, err error) {
125125
resourceNamespace := s.resource.Namespace
126126
resourceName := s.resource.Name
127127
prefix := ""
128-
if s.standalone && s.ingress != nil && s.ingress.Name != "" {
128+
if s.IsStandalone() && s.ingress != nil && s.ingress.Name != "" {
129129
resourceName = s.ingress.Name + "-" + s.resource.Name
130130
resourceNamespace = s.ingress.Namespace
131131
prefix = "ing_"
@@ -263,3 +263,7 @@ func (s *Service) SetDefaultBackend(k store.K8s, h haproxy.HAProxy, frontends []
263263
s.HandleHAProxySrvs(k, h)
264264
return
265265
}
266+
267+
func (s Service) IsStandalone() bool {
268+
return s.standalone
269+
}

pkg/store/events.go

+33
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,52 @@ func (k *K8s) EventEndpoints(ns *Namespace, data *Endpoints, syncHAproxySrvs fun
127127
ns.HAProxyRuntime[data.Service] = make(map[string]*RuntimeBackend)
128128
}
129129
logger.Tracef("service %s : number of already existing backend(s) in this transaction for this endpoint: %d", data.Service, len(ns.HAProxyRuntime[data.Service]))
130+
// Standalone
131+
_, ok = ns.HAProxyRuntimeStandalone[data.Service]
132+
if !ok {
133+
ns.HAProxyRuntimeStandalone[data.Service] = make(map[string]map[string]*RuntimeBackend)
134+
}
130135
for key, value := range ns.HAProxyRuntime[data.Service] {
131136
logger.Tracef("service %s : port name %s, backend %+v", data.Service, key, *value)
132137
}
138+
// Standalone
139+
for portName, backendsNames := range ns.HAProxyRuntimeStandalone[data.Service] {
140+
for backendName := range backendsNames {
141+
logger.Tracef("service %s : port name %s, backend %+v", data.Service, portName, backendName)
142+
}
143+
}
133144
for portName, portEndpoints := range endpoints {
145+
// Make a copy of addresses for potential standalone runtime backend
146+
// as these addresses are consumed/removed in the process
147+
backendAddresses := utils.CopyMap(portEndpoints.Addresses)
134148
newBackend := &RuntimeBackend{Endpoints: portEndpoints}
135149
backend, ok := ns.HAProxyRuntime[data.Service][portName]
150+
// Make a copy of haproxy server list for potential standalone runtime backend
151+
// as this servere list is modified in the process
152+
var backendHAProxySrvs []*HAProxySrv
136153
if ok {
154+
backendHAProxySrvs = utils.CopySliceFunc(backend.HAProxySrvs, utils.CopyPointer)
137155
portUpdated := (newBackend.Endpoints.Port != backend.Endpoints.Port)
138156
newBackend.HAProxySrvs = backend.HAProxySrvs
139157
newBackend.Name = backend.Name
140158
logger.Warning(syncHAproxySrvs(newBackend, portUpdated))
141159
}
142160
ns.HAProxyRuntime[data.Service][portName] = newBackend
161+
162+
// Reprocuce the same steps ar regular runtime backend for each standalone runtime backend
163+
// referring to the same port and service
164+
standaloneNewBackend := &RuntimeBackend{Endpoints: portEndpoints}
165+
for standaloneBackendName, standaloneRuntimeBackend := range ns.HAProxyRuntimeStandalone[data.Service][portName] {
166+
// Make own copy of regular runtime backend portEndpoint addresses
167+
standaloneNewBackend.Endpoints.Addresses = utils.CopyMap(backendAddresses)
168+
// Make own copy of regular runtime backend portEndpoint servers list
169+
standaloneNewBackend.HAProxySrvs = utils.CopySliceFunc(backendHAProxySrvs, utils.CopyPointer)
170+
standaloneNewBackend.Name = standaloneRuntimeBackend.Name
171+
standalonePortUpdated := (standaloneNewBackend.Endpoints.Port != standaloneRuntimeBackend.Endpoints.Port)
172+
logger.Warning(syncHAproxySrvs(standaloneNewBackend, standalonePortUpdated))
173+
ns.HAProxyRuntimeStandalone[data.Service][portName][standaloneBackendName] = standaloneNewBackend
174+
standaloneNewBackend = &RuntimeBackend{Endpoints: portEndpoints}
175+
}
143176
}
144177
return true
145178
}

pkg/store/store.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ func (k *K8s) Clean() {
113113
if len(namespace.Endpoints[slice.Service]) == 0 {
114114
delete(namespace.Endpoints, slice.Service)
115115
delete(namespace.HAProxyRuntime, slice.Service)
116+
delete(namespace.HAProxyRuntimeStandalone, slice.Service)
116117
}
117118
default:
118119
slice.Status = EMPTY
@@ -163,13 +164,14 @@ func (k K8s) GetNamespace(name string) *Namespace {
163164
return namespace
164165
}
165166
newNamespace := &Namespace{
166-
Name: name,
167-
Relevant: k.isRelevantNamespace(name),
168-
Endpoints: make(map[string]map[string]*Endpoints),
169-
Services: make(map[string]*Service),
170-
Ingresses: make(map[string]*Ingress),
171-
Secret: make(map[string]*Secret),
172-
HAProxyRuntime: make(map[string]map[string]*RuntimeBackend),
167+
Name: name,
168+
Relevant: k.isRelevantNamespace(name),
169+
Endpoints: make(map[string]map[string]*Endpoints),
170+
Services: make(map[string]*Service),
171+
Ingresses: make(map[string]*Ingress),
172+
Secret: make(map[string]*Secret),
173+
HAProxyRuntime: make(map[string]map[string]*RuntimeBackend),
174+
HAProxyRuntimeStandalone: make(map[string]map[string]map[string]*RuntimeBackend),
173175
CRs: &CustomResources{
174176
Global: make(map[string]*models.Global),
175177
Defaults: make(map[string]*models.Defaults),

pkg/store/types.go

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

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

104105
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)