Skip to content

Commit 5846dd5

Browse files
committed
MINOR: arguments: add IC arg to allow disabling one or several config snippet types
1 parent 5a55fb7 commit 5846dd5

File tree

13 files changed

+250
-17
lines changed

13 files changed

+250
-17
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.vscode/*
22
.idea/*
3+
.test/*
34
kubernetes-ingress
45
dist/
56
.code-generator/

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Example environment can be created with
3434
make example
3535
```
3636

37-
Please see [controller.md](https://github.com/haproxytech/kubernetes-ingress/blob/master/documentation/controller.md) for all available arguments of controler image.
37+
Please see [controller.md](https://github.com/haproxytech/kubernetes-ingress/blob/master/documentation/controller.md) for all available arguments of controller image.
3838

3939
Available customisations are described in [doc](https://github.com/haproxytech/kubernetes-ingress/blob/master/documentation/README.md)
4040

deploy/tests/rebuild.sh

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ command -v kubectl >/dev/null 2>&1 || { echo >&2 "Kubectl not installed. Aborti
66
DIR=$(dirname "$0")
77

88
echo "delete image of ingress controller"
9-
kubectl delete -f $DIR/config/4.ingress-controller.yaml
9+
kubectl delete -f $DIR/config/3.ingress-controller.yaml
1010

1111
echo "building image for ingress controller"
1212
docker build -t haproxytech/kubernetes-ingress -f build/Dockerfile .
1313
kind --name=dev load docker-image haproxytech/kubernetes-ingress:latest
1414

1515
echo "deploying Ingress Controller ..."
16-
kubectl apply -f $DIR/config/4.ingress-controller.yaml
16+
kubectl apply -f $DIR/config/3.ingress-controller.yaml
1717

1818
echo "wait --for=condition=ready ..."
1919
COUNTER=0
2020
while [ $COUNTER -lt 150 ]; do
2121
sleep 2
2222
kubectl get pods -n haproxy-controller --no-headers --selector=run=haproxy-ingress | awk '{print "haproxy-controller/haproxy-kubernetes-ingress " $3 " " $5}'
23-
result=$(kubectl get pods -n default --no-headers --selector=run=haproxy-ingress | awk '{print $3}')
23+
result=$(kubectl get pods -n haproxy-controller --no-headers --selector=run=haproxy-ingress | awk '{print $3}')
2424
if [ "$result" = "Running" ]; then
2525
COUNTER=151
2626
else

documentation/controller.md

+24
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Image can be run with arguments:
4141
| [`--runtime-dir`](#--runtime-dir) | `/tmp/haproxy-ingress/run` |
4242
| [`--disable-service-external-name`](#--disable-service-external-name) | `false` |
4343
| [`--channel-size`](#--channel-size) | `600` |
44+
| [`--disable-config-snippets`](#--disable-config-snippets) :construction:(dev) | |
4445

4546

4647
### `--configmap`
@@ -720,3 +721,26 @@ Example:
720721

721722
***
722723

724+
### `--disable-config-snippets`
725+
726+
727+
> :construction: this is only available from next version, currently available in dev build
728+
729+
Allow to disable one or several of the following config snippets: backend, frontend, global.
730+
731+
Possible values:
732+
733+
- Comma separated list of the kind of config snippets to disable. Possible values in the list are
734+
- backend,frontend,global,all
735+
- If 'all' is present then all (backend, frontend, global) config snippets are disabled.
736+
737+
Example:
738+
739+
```yaml
740+
--disable-config-snippets=backend,frontend
741+
```
742+
743+
<p align='right'><a href='#haproxy-kubernetes-ingress-controller'>:arrow_up_small: back to top</a></p>
744+
745+
***
746+

documentation/doc.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,15 @@ image_arguments:
361361
default: 600
362362
version_min: "1.7"
363363
example: --channel-size=10000
364+
- argument: --disable-config-snippets
365+
description: |-
366+
Allow to disable one or several of the following config snippets: backend, frontend, global.
367+
values:
368+
- Comma separated list of the kind of config snippets to disable. Possible values in the list are
369+
- backend,frontend,global,all
370+
- If 'all' is present then all (backend, frontend, global) config snippets are disabled.
371+
version_min: "1.11"
372+
example: --disable-config-snippets=backend,frontend
364373
groups:
365374
config-snippet:
366375
header: |-

main.go

+4
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ func logInfo(logger utils.Logger, osArgs utils.OSArgs) bool {
192192
if osArgs.ConfigMapPatternFiles.Name != "" {
193193
logger.Printf("Pattern files provided in '%s'", osArgs.ConfigMapPatternFiles)
194194
}
195+
if osArgs.DisableConfigSnippets != "" {
196+
logger.Printf("Disabling config snippets for [%s]", osArgs.DisableConfigSnippets)
197+
annotations.DisableConfigSnippets(osArgs.DisableConfigSnippets)
198+
}
195199
logger.Debugf("Kubernetes Informers resync period: %s", osArgs.CacheResyncPeriod.String())
196200
logger.Printf("Controller sync period: %s\n", osArgs.SyncPeriod.String())
197201

pkg/annotations/annotations.go

+18-4
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,24 @@ func (a annImpl) Timeout(name string, annotations ...map[string]string) (out *in
5555

5656
func (a annImpl) GlobalCfgSnipp() []Annotation {
5757
return []Annotation{
58-
NewGlobalCfgSnippet("global-config-snippet"),
59-
NewFrontendCfgSnippet("frontend-config-snippet", "http"),
60-
NewFrontendCfgSnippet("frontend-config-snippet", "https"),
61-
NewFrontendCfgSnippet("stats-config-snippet", "stats"),
58+
// global
59+
NewCfgSnippet(ConfigSnippetOptions{Name: "global-config-snippet"}),
60+
// frontend
61+
NewCfgSnippet(ConfigSnippetOptions{
62+
Name: "frontend-config-snippet",
63+
Frontend: utils.Ptr("http"),
64+
},
65+
),
66+
NewCfgSnippet(ConfigSnippetOptions{
67+
Name: "frontend-config-snippet",
68+
Frontend: utils.Ptr("https"),
69+
},
70+
),
71+
NewCfgSnippet(ConfigSnippetOptions{
72+
Name: "stats-config-snippet",
73+
Frontend: utils.Ptr("stats"),
74+
},
75+
),
6276
}
6377
}
6478

pkg/annotations/cfgSnippet.go

+74-6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ type cfgData struct {
4242
status store.Status
4343
}
4444

45+
// CfgSnippetType represents type of a config snippet
46+
type cfgSnippetType string
47+
48+
const (
49+
// CfgSnippetType values
50+
configSnippetBackend cfgSnippetType = "backend"
51+
configSnippetFrontend cfgSnippetType = "frontend"
52+
configSnippetGlobal cfgSnippetType = "global"
53+
)
54+
4555
// cfgSnippet is a particular type of config that is not
4656
// handled by the upstram library haproxytech/client-native.
4757
// Which means there is no client-native models to
@@ -55,6 +65,8 @@ var cfgSnippet struct {
5565
frontends map[string]*cfgData
5666
backends map[string]map[string]*cfgData // backends[backend][origin] = &cfgData{}
5767
disabledServices map[string]bool
68+
// Flags to allow disable some config snippet ("backend", "frontend", "global")
69+
disabledSnippets map[cfgSnippetType]struct{}
5870
}
5971

6072
func init() { //nolint:gochecknoinits
@@ -63,16 +75,59 @@ func init() { //nolint:gochecknoinits
6375
cfgSnippet.backends = make(map[string]map[string]*cfgData)
6476
}
6577

66-
func NewGlobalCfgSnippet(n string) *CfgSnippet {
67-
return &CfgSnippet{name: n}
78+
type ConfigSnippetOptions struct {
79+
Name string
80+
Backend *string
81+
Frontend *string
82+
Ingress *store.Ingress
6883
}
6984

70-
func NewFrontendCfgSnippet(n string, f string) *CfgSnippet {
71-
return &CfgSnippet{name: n, frontend: f}
85+
// DisableConfigSnippets fills a map[cfgSnippetType]struct{} of disabled config snippet types:
86+
// - backend/frontend/global
87+
// and store it in the global var cfgSnippet
88+
// from a comma separated list : all,backend,frontend,global.
89+
// If "all" is present in the list, then: backend, frontend and global config snippets are disabled.
90+
func DisableConfigSnippets(disableConfigSnippets string) {
91+
disable := map[cfgSnippetType]struct{}{}
92+
for _, d := range strings.Split(disableConfigSnippets, ",") {
93+
switch strings.TrimSpace(d) {
94+
case "all":
95+
disable[configSnippetBackend] = struct{}{}
96+
disable[configSnippetFrontend] = struct{}{}
97+
disable[configSnippetGlobal] = struct{}{}
98+
case "frontend":
99+
disable[configSnippetFrontend] = struct{}{}
100+
case "backend":
101+
disable[configSnippetBackend] = struct{}{}
102+
case "global":
103+
disable[configSnippetGlobal] = struct{}{}
104+
default:
105+
logger.Errorf("wrong config snippet type '%s' in disable-config-snippets arg in command line", d)
106+
}
107+
}
108+
cfgSnippet.disabledSnippets = disable
72109
}
73110

74-
func NewBackendCfgSnippet(n string, b string, ingress *store.Ingress) *CfgSnippet {
75-
return &CfgSnippet{name: n, backend: b, ingress: ingress}
111+
func isConfigSnippetDisabled(name cfgSnippetType) bool {
112+
_, disabled := cfgSnippet.disabledSnippets[name]
113+
return disabled
114+
}
115+
116+
func NewCfgSnippet(opts ConfigSnippetOptions) *CfgSnippet {
117+
frontend := ""
118+
backend := ""
119+
if opts.Backend != nil {
120+
backend = *opts.Backend
121+
}
122+
if opts.Frontend != nil {
123+
frontend = *opts.Frontend
124+
}
125+
return &CfgSnippet{
126+
name: opts.Name,
127+
frontend: frontend,
128+
backend: backend,
129+
ingress: opts.Ingress,
130+
}
76131
}
77132

78133
func (a *CfgSnippet) GetName() string {
@@ -82,6 +137,10 @@ func (a *CfgSnippet) GetName() string {
82137
func (a *CfgSnippet) Process(k store.K8s, annotations ...map[string]string) error {
83138
switch {
84139
case a.frontend != "":
140+
if isConfigSnippetDisabled(configSnippetFrontend) {
141+
// frontend snippet is disabled, do not handle
142+
return nil
143+
}
85144
var data []string
86145
input := common.GetValue(a.GetName(), annotations...)
87146
if input != "" {
@@ -97,7 +156,12 @@ func (a *CfgSnippet) Process(k store.K8s, annotations ...map[string]string) erro
97156
cfgSnippet.frontends[a.frontend].value = data
98157
cfgSnippet.frontends[a.frontend].updated = updated
99158
}
159+
100160
case a.backend != "":
161+
if isConfigSnippetDisabled(configSnippetBackend) {
162+
// backend snippet is disabled, do not handle
163+
return nil
164+
}
101165
anns := common.GetValuesAndIndices(a.GetName(), annotations...)
102166
// We don't want configmap value unless it's configmap being processed.
103167
// We detect that by name of the backend and indice of maps providing the value
@@ -132,6 +196,10 @@ func (a *CfgSnippet) Process(k store.K8s, annotations ...map[string]string) erro
132196
}
133197
}
134198
default:
199+
if isConfigSnippetDisabled(configSnippetGlobal) {
200+
// global snippet is disabled, do not handle
201+
return nil
202+
}
135203
var data []string
136204
input := common.GetValue(a.GetName(), annotations...)
137205
if input != "" {

pkg/annotations/cfgSnippet_test.go

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2023 HAProxy Technologies LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package annotations
16+
17+
import (
18+
"reflect"
19+
"testing"
20+
)
21+
22+
func Test_DisableConfigSnippets(t *testing.T) {
23+
tests := []struct {
24+
name string
25+
disableConfigSnippets string
26+
want map[cfgSnippetType]struct{}
27+
}{
28+
{
29+
name: "No meaningful value",
30+
disableConfigSnippets: "invalid",
31+
want: map[cfgSnippetType]struct{}{},
32+
},
33+
{
34+
name: "all",
35+
disableConfigSnippets: "all",
36+
want: map[cfgSnippetType]struct{}{
37+
configSnippetBackend: {},
38+
configSnippetFrontend: {},
39+
configSnippetGlobal: {},
40+
},
41+
},
42+
{
43+
name: "frontend only",
44+
disableConfigSnippets: "frontend",
45+
want: map[cfgSnippetType]struct{}{
46+
configSnippetFrontend: {},
47+
},
48+
},
49+
{
50+
name: "backend only",
51+
disableConfigSnippets: "backend",
52+
want: map[cfgSnippetType]struct{}{
53+
configSnippetBackend: {},
54+
},
55+
},
56+
{
57+
name: "global only",
58+
disableConfigSnippets: "global",
59+
want: map[cfgSnippetType]struct{}{
60+
configSnippetGlobal: {},
61+
},
62+
},
63+
{
64+
name: "frontend and backend",
65+
disableConfigSnippets: "backend,frontend",
66+
want: map[cfgSnippetType]struct{}{
67+
configSnippetFrontend: {},
68+
configSnippetBackend: {},
69+
},
70+
},
71+
{
72+
name: "frontend and global, whitespaces",
73+
disableConfigSnippets: " frontend, global",
74+
want: map[cfgSnippetType]struct{}{
75+
configSnippetGlobal: {},
76+
configSnippetFrontend: {},
77+
},
78+
},
79+
{
80+
name: "frontend global, backend",
81+
disableConfigSnippets: "backend,global,frontend",
82+
want: map[cfgSnippetType]struct{}{
83+
configSnippetBackend: {},
84+
configSnippetFrontend: {},
85+
configSnippetGlobal: {},
86+
},
87+
},
88+
}
89+
for _, tt := range tests {
90+
t.Run(tt.name, func(t *testing.T) {
91+
DisableConfigSnippets(tt.disableConfigSnippets)
92+
if !reflect.DeepEqual(cfgSnippet.disabledSnippets, tt.want) {
93+
t.Errorf("DisabledConfigSnippets() = %v, want %v", cfgSnippet.disabledSnippets, tt.want)
94+
}
95+
})
96+
}
97+
}

pkg/controller/controller.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,12 @@ func (c *HAProxyController) updateHAProxy() {
114114
}
115115

116116
// global config-snippet
117-
logger.Error(annotations.NewBackendCfgSnippet("backend-config-snippet", "configmap", nil).
117+
logger.Error(annotations.NewCfgSnippet(
118+
annotations.ConfigSnippetOptions{
119+
Name: "backend-config-snippet",
120+
Backend: utils.Ptr("configmap"),
121+
Ingress: nil,
122+
}).
118123
Process(c.store, c.store.ConfigMaps.Main.Annotations))
119124

120125
for _, namespace := range c.store.Namespaces {

pkg/service/service.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,13 @@ func (s *Service) HandleBackend(storeK8s store.K8s, client api.HAProxyClient, a
165165
reload = true
166166
logger.Debugf("Service '%s/%s': new backend '%s', reload required", s.resource.Namespace, s.resource.Name, newBackend.Name)
167167
}
168-
// config-snippet
169-
backendCfgSnippetHandler := annotations.NewBackendCfgSnippet("backend-config-snippet", newBackend.Name, s.ingress)
168+
// config-snippet: backend
169+
backendCfgSnippetHandler := annotations.NewCfgSnippet(
170+
annotations.ConfigSnippetOptions{
171+
Name: "backend-config-snippet",
172+
Backend: utils.PtrString(newBackend.Name),
173+
Ingress: s.ingress,
174+
})
170175
backendCfgSnippetHandler.SetService(s.resource)
171176
logger.Error(backendCfgSnippetHandler.Process(storeK8s, s.annotations...))
172177
return

pkg/utils/flags.go

+1
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,5 @@ type OSArgs struct {
107107
PrometheusEnabled bool `long:"prometheus" description:"enable prometheus of IC data"`
108108
DisableHTTP bool `long:"disable-http" description:"toggle to disable the HTTP frontend"`
109109
DisableIPV6 bool `long:"disable-ipv6" description:"toggle to disable the IPv6 protocol from all frontends"`
110+
DisableConfigSnippets string `long:"disable-config-snippets" description:"Allow to disable config snippets. List of comma separated values (possible values: all/global/backend/frontend)"`
110111
}

0 commit comments

Comments
 (0)