Skip to content

Commit af7e80e

Browse files
committed
CLEANUP/MINOR: simplify frontend custom annotations
1 parent 4796f39 commit af7e80e

File tree

5 files changed

+71
-18
lines changed

5 files changed

+71
-18
lines changed

deploy/tests/integration/base-suite.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ func (suite *BaseSuite) StopController() {
159159
testController := suite.TestControllers[suite.T().Name()]
160160
testController.Controller.Stop()
161161
testController.Store.Clean()
162+
annotations.Clean()
162163
close(testController.EventChan)
163164
}
164165

documentation/annotations-custom.md

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ backend default_svc_http-echo_http
112112
...
113113
```
114114

115-
we can see that a config snippet was added, but compared to regular snippet, our annotation has full validation that we defined (and also its limiting what we can put)
115+
we can see that a config snippet was added, but compared to regular snippet, our annotation has full validation that we defined (and also it is limiting what we can put)
116116

117117
what happens if we try to add value that is not accepted ?
118118

@@ -147,6 +147,13 @@ if template is not defined, value as is will be copied
147147

148148
usage
149149

150+
```yaml
151+
backend.example.com/maxconn: "1000"
152+
```
153+
154+
⚠ `duration`, `int`, `uint`, `bool` and `float` values needs to be defined as strings in annotation value. This is limitation of k8s for annotation values. If using type `json` normal number and boolean values can be used.
155+
156+
**invalid**
150157
```yaml
151158
backend.example.com/maxconn: 1000
152159
```
@@ -314,7 +321,7 @@ config
314321
rule: "value > duration('42s') && value <= duration('42m')" # CEL expression
315322
```
316323
317-
## How do i create frontend annotations ?
324+
## How do I create frontend annotations ?
318325
319326
in same way as backend ones, except there is no `frontend` object in k8s. Therefore we will use configmap
320327

@@ -325,24 +332,39 @@ metadata:
325332
name: haproxy-kubernetes-ingress
326333
namespace: haproxy-controller
327334
annotations:
328-
frontend.http.example.com/timeout-server: "5s"
329-
frontend.http.example.com/timeout-client: "6s"
330-
frontend.https.example.com/timeout-server: "7s"
331-
frontend.stats.example.com/timeout-server: "8s"
335+
frontend.example.com/timeout-server: "5s"
336+
frontend.example.com/timeout-client: "6s"
332337
data:
333-
syslog-server: |
334-
address: stdout, format: raw, facility:daemon
335-
cr-global: haproxy-controller/global-full
338+
...
336339
```
337340

338-
its similar as with other configuration values, except we define it as configmap annotations
341+
it is similar as with other configuration values, except we define it as configmap annotations.
339342

340343
### Structure
341344

342-
`frontend.<frontend-name>.<org>/<custom-annotation-name>`
345+
`frontend.<prefix>/<custom-annotation-name>`
346+
347+
With HAProxy Ingress controller, you have 3 different frontends: `http`, `https` and `stats`, each can be customized with custom annotations.
343348

344-
the only difference is extra information what frontend this settings belong to. With HAProxy Ingress controller, you have 3 different frontends: `http`, `https` and `stats`, each can be customized with custom annotations.
349+
If you want to create a annotation for specific frontend use `resources` as shown in example:
345350

351+
```yaml
352+
apiVersion: ingress.v3.haproxy.org/v3
353+
kind: ValidationRules
354+
metadata:
355+
name: custom-validation-rules
356+
namespace: haproxy-controller
357+
spec:
358+
prefix: "haproxy.org"
359+
validation_rules:
360+
maxconn:
361+
section: frontend
362+
resources:
363+
- http
364+
- https
365+
type: int
366+
rule: "value >= 10 && value <= 1000000"
367+
```
346368

347369
## Where can custom annotations can be defined ?
348370

@@ -357,7 +379,7 @@ metadata:
357379
name: haproxy-kubernetes-ingress
358380
namespace: haproxy-controller
359381
annotations:
360-
frontend.<frontend-name>.<org>/<custom-annotation-name>: <value>
382+
frontend.<org>/<custom-annotation-name>: <value>
361383
```
362384

363385
### Backend Annotations

pkg/annotations/cfgSnippet-user-annotations.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"strings"
55

66
"github.com/haproxytech/kubernetes-ingress/pkg/annotations/validators"
7+
"github.com/haproxytech/kubernetes-ingress/pkg/store"
78
)
89

910
func processCustomAnnotationsFrontend(customAnnotations map[string]string, a *CfgSnippet, validator *validators.Validator) error {
@@ -71,6 +72,14 @@ func processCustomAnnotationsFrontend(customAnnotations map[string]string, a *Cf
7172
}
7273
processConfigSnippetFrontendCustom(a.frontend, origin, rdata, len(keys)-index+1)
7374
}
75+
if len(keys) == 0 && len(cfgSnippet.frontendsCustom[a.frontend]) != 0 {
76+
// go through cfgSnippet.frontendsCustom[a.frontend] and mark them as deleted
77+
for _, value := range cfgSnippet.frontendsCustom[a.frontend] {
78+
value.status = store.DELETED
79+
value.value = []string{}
80+
value.updated = []string{}
81+
}
82+
}
7483

7584
return nil
7685
}

pkg/annotations/cfgSnippet.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,19 @@ func InitCfgSnippet() {
8585
cfgSnippet.disabledSnippets = make(map[CfgSnippetType]struct{})
8686
}
8787

88+
// Clean removes all deleted custom config snippets from the global map cfgSnippet.
89+
// It iterates over the frontend custom config snippets and checks if any of them
90+
// have a status of DELETED. If so, it deletes them from the map.
91+
func Clean() {
92+
for _, v := range cfgSnippet.frontendsCustom {
93+
for annKey, annVal := range v {
94+
if annVal.status == store.DELETED {
95+
delete(v, annKey)
96+
}
97+
}
98+
}
99+
}
100+
88101
type ConfigSnippetOptions struct {
89102
Backend *string
90103
Frontend *string
@@ -156,8 +169,8 @@ func (a *CfgSnippet) Process(k store.K8s, annotations ...map[string]string) erro
156169
customAnnotations := map[string]string{}
157170
for _, annotation := range annotations {
158171
for k, v := range annotation {
159-
if strings.HasPrefix(k, "frontend."+a.frontend+"."+validator.Prefix()) {
160-
key := strings.TrimPrefix(k, "frontend."+a.frontend+"."+validator.Prefix())
172+
if strings.HasPrefix(k, "frontend."+validator.Prefix()) {
173+
key := strings.TrimPrefix(k, "frontend."+validator.Prefix())
161174
customAnnotations[key] = v
162175
}
163176
}
@@ -268,13 +281,20 @@ func UpdateFrontendCfgSnippet(api api.HAProxyClient, frontends ...string) (updat
268281
if !ok && !okCustom {
269282
continue
270283
}
284+
deleted := []string{}
271285
if okCustom {
272286
newData := make([]string, 0)
273-
for _, v := range customData {
287+
for k, v := range customData {
288+
if v.status == store.DELETED {
289+
updated = append(updated, "DELETED: "+k)
290+
deleted = append(deleted, k)
291+
continue
292+
}
274293
newData = append(newData, v.value...)
275294
updated = append(updated, v.updated...)
276295
}
277-
if len(customData) > 0 {
296+
297+
if len(newData) > 0 {
278298
newData = append(newData, "### custom annotations end ###")
279299
}
280300
if data != nil && len(data.value) > 0 {
@@ -283,7 +303,7 @@ func UpdateFrontendCfgSnippet(api api.HAProxyClient, frontends ...string) (updat
283303
data = &cfgData{value: newData}
284304
}
285305
}
286-
if data == nil || len(data.value) == 0 {
306+
if len(deleted) == 0 && (data == nil || len(data.value) == 0) {
287307
continue
288308
}
289309
err = api.FrontendCfgSnippetSet(ft, data.value)

pkg/controller/controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ func (c *HAProxyController) clean(failedSync bool) {
350350
logger.Error(c.setupHAProxyRules())
351351
if !failedSync {
352352
c.store.Clean()
353+
annotations.Clean()
353354
}
354355
}
355356

0 commit comments

Comments
 (0)