Skip to content

Commit

Permalink
MINOR: arguments: add IC arg to allow disabling one or several config…
Browse files Browse the repository at this point in the history
… snippet types
  • Loading branch information
hdurand0710 committed Aug 22, 2023
1 parent 5a55fb7 commit 5846dd5
Show file tree
Hide file tree
Showing 13 changed files with 250 additions and 17 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.vscode/*
.idea/*
.test/*
kubernetes-ingress
dist/
.code-generator/
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Example environment can be created with
make example
```

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

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

Expand Down
6 changes: 3 additions & 3 deletions deploy/tests/rebuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ command -v kubectl >/dev/null 2>&1 || { echo >&2 "Kubectl not installed. Aborti
DIR=$(dirname "$0")

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

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

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

echo "wait --for=condition=ready ..."
COUNTER=0
while [ $COUNTER -lt 150 ]; do
sleep 2
kubectl get pods -n haproxy-controller --no-headers --selector=run=haproxy-ingress | awk '{print "haproxy-controller/haproxy-kubernetes-ingress " $3 " " $5}'
result=$(kubectl get pods -n default --no-headers --selector=run=haproxy-ingress | awk '{print $3}')
result=$(kubectl get pods -n haproxy-controller --no-headers --selector=run=haproxy-ingress | awk '{print $3}')
if [ "$result" = "Running" ]; then
COUNTER=151
else
Expand Down
24 changes: 24 additions & 0 deletions documentation/controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Image can be run with arguments:
| [`--runtime-dir`](#--runtime-dir) | `/tmp/haproxy-ingress/run` |
| [`--disable-service-external-name`](#--disable-service-external-name) | `false` |
| [`--channel-size`](#--channel-size) | `600` |
| [`--disable-config-snippets`](#--disable-config-snippets) :construction:(dev) | |


### `--configmap`
Expand Down Expand Up @@ -720,3 +721,26 @@ Example:

***

### `--disable-config-snippets`


> :construction: this is only available from next version, currently available in dev build
Allow to disable one or several of the following config snippets: backend, frontend, global.

Possible values:

- Comma separated list of the kind of config snippets to disable. Possible values in the list are
- backend,frontend,global,all
- If 'all' is present then all (backend, frontend, global) config snippets are disabled.

Example:

```yaml
--disable-config-snippets=backend,frontend
```

<p align='right'><a href='#haproxy-kubernetes-ingress-controller'>:arrow_up_small: back to top</a></p>

***

9 changes: 9 additions & 0 deletions documentation/doc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,15 @@ image_arguments:
default: 600
version_min: "1.7"
example: --channel-size=10000
- argument: --disable-config-snippets
description: |-
Allow to disable one or several of the following config snippets: backend, frontend, global.
values:
- Comma separated list of the kind of config snippets to disable. Possible values in the list are
- backend,frontend,global,all
- If 'all' is present then all (backend, frontend, global) config snippets are disabled.
version_min: "1.11"
example: --disable-config-snippets=backend,frontend
groups:
config-snippet:
header: |-
Expand Down
4 changes: 4 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ func logInfo(logger utils.Logger, osArgs utils.OSArgs) bool {
if osArgs.ConfigMapPatternFiles.Name != "" {
logger.Printf("Pattern files provided in '%s'", osArgs.ConfigMapPatternFiles)
}
if osArgs.DisableConfigSnippets != "" {
logger.Printf("Disabling config snippets for [%s]", osArgs.DisableConfigSnippets)
annotations.DisableConfigSnippets(osArgs.DisableConfigSnippets)
}
logger.Debugf("Kubernetes Informers resync period: %s", osArgs.CacheResyncPeriod.String())
logger.Printf("Controller sync period: %s\n", osArgs.SyncPeriod.String())

Expand Down
22 changes: 18 additions & 4 deletions pkg/annotations/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,24 @@ func (a annImpl) Timeout(name string, annotations ...map[string]string) (out *in

func (a annImpl) GlobalCfgSnipp() []Annotation {
return []Annotation{
NewGlobalCfgSnippet("global-config-snippet"),
NewFrontendCfgSnippet("frontend-config-snippet", "http"),
NewFrontendCfgSnippet("frontend-config-snippet", "https"),
NewFrontendCfgSnippet("stats-config-snippet", "stats"),
// global
NewCfgSnippet(ConfigSnippetOptions{Name: "global-config-snippet"}),
// frontend
NewCfgSnippet(ConfigSnippetOptions{
Name: "frontend-config-snippet",
Frontend: utils.Ptr("http"),
},
),
NewCfgSnippet(ConfigSnippetOptions{
Name: "frontend-config-snippet",
Frontend: utils.Ptr("https"),
},
),
NewCfgSnippet(ConfigSnippetOptions{
Name: "stats-config-snippet",
Frontend: utils.Ptr("stats"),
},
),
}
}

Expand Down
80 changes: 74 additions & 6 deletions pkg/annotations/cfgSnippet.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ type cfgData struct {
status store.Status
}

// CfgSnippetType represents type of a config snippet
type cfgSnippetType string

const (
// CfgSnippetType values
configSnippetBackend cfgSnippetType = "backend"
configSnippetFrontend cfgSnippetType = "frontend"
configSnippetGlobal cfgSnippetType = "global"
)

// cfgSnippet is a particular type of config that is not
// handled by the upstram library haproxytech/client-native.
// Which means there is no client-native models to
Expand All @@ -55,6 +65,8 @@ var cfgSnippet struct {
frontends map[string]*cfgData
backends map[string]map[string]*cfgData // backends[backend][origin] = &cfgData{}
disabledServices map[string]bool
// Flags to allow disable some config snippet ("backend", "frontend", "global")
disabledSnippets map[cfgSnippetType]struct{}
}

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

func NewGlobalCfgSnippet(n string) *CfgSnippet {
return &CfgSnippet{name: n}
type ConfigSnippetOptions struct {
Name string
Backend *string
Frontend *string
Ingress *store.Ingress
}

func NewFrontendCfgSnippet(n string, f string) *CfgSnippet {
return &CfgSnippet{name: n, frontend: f}
// DisableConfigSnippets fills a map[cfgSnippetType]struct{} of disabled config snippet types:
// - backend/frontend/global
// and store it in the global var cfgSnippet
// from a comma separated list : all,backend,frontend,global.
// If "all" is present in the list, then: backend, frontend and global config snippets are disabled.
func DisableConfigSnippets(disableConfigSnippets string) {
disable := map[cfgSnippetType]struct{}{}
for _, d := range strings.Split(disableConfigSnippets, ",") {
switch strings.TrimSpace(d) {
case "all":
disable[configSnippetBackend] = struct{}{}
disable[configSnippetFrontend] = struct{}{}
disable[configSnippetGlobal] = struct{}{}
case "frontend":
disable[configSnippetFrontend] = struct{}{}
case "backend":
disable[configSnippetBackend] = struct{}{}
case "global":
disable[configSnippetGlobal] = struct{}{}
default:
logger.Errorf("wrong config snippet type '%s' in disable-config-snippets arg in command line", d)
}
}
cfgSnippet.disabledSnippets = disable
}

func NewBackendCfgSnippet(n string, b string, ingress *store.Ingress) *CfgSnippet {
return &CfgSnippet{name: n, backend: b, ingress: ingress}
func isConfigSnippetDisabled(name cfgSnippetType) bool {
_, disabled := cfgSnippet.disabledSnippets[name]
return disabled
}

func NewCfgSnippet(opts ConfigSnippetOptions) *CfgSnippet {
frontend := ""
backend := ""
if opts.Backend != nil {
backend = *opts.Backend
}
if opts.Frontend != nil {
frontend = *opts.Frontend
}
return &CfgSnippet{
name: opts.Name,
frontend: frontend,
backend: backend,
ingress: opts.Ingress,
}
}

func (a *CfgSnippet) GetName() string {
Expand All @@ -82,6 +137,10 @@ func (a *CfgSnippet) GetName() string {
func (a *CfgSnippet) Process(k store.K8s, annotations ...map[string]string) error {
switch {
case a.frontend != "":
if isConfigSnippetDisabled(configSnippetFrontend) {
// frontend snippet is disabled, do not handle
return nil
}
var data []string
input := common.GetValue(a.GetName(), annotations...)
if input != "" {
Expand All @@ -97,7 +156,12 @@ func (a *CfgSnippet) Process(k store.K8s, annotations ...map[string]string) erro
cfgSnippet.frontends[a.frontend].value = data
cfgSnippet.frontends[a.frontend].updated = updated
}

case a.backend != "":
if isConfigSnippetDisabled(configSnippetBackend) {
// backend snippet is disabled, do not handle
return nil
}
anns := common.GetValuesAndIndices(a.GetName(), annotations...)
// We don't want configmap value unless it's configmap being processed.
// We detect that by name of the backend and indice of maps providing the value
Expand Down Expand Up @@ -132,6 +196,10 @@ func (a *CfgSnippet) Process(k store.K8s, annotations ...map[string]string) erro
}
}
default:
if isConfigSnippetDisabled(configSnippetGlobal) {
// global snippet is disabled, do not handle
return nil
}
var data []string
input := common.GetValue(a.GetName(), annotations...)
if input != "" {
Expand Down
97 changes: 97 additions & 0 deletions pkg/annotations/cfgSnippet_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2023 HAProxy Technologies LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package annotations

import (
"reflect"
"testing"
)

func Test_DisableConfigSnippets(t *testing.T) {
tests := []struct {
name string
disableConfigSnippets string
want map[cfgSnippetType]struct{}
}{
{
name: "No meaningful value",
disableConfigSnippets: "invalid",
want: map[cfgSnippetType]struct{}{},
},
{
name: "all",
disableConfigSnippets: "all",
want: map[cfgSnippetType]struct{}{
configSnippetBackend: {},
configSnippetFrontend: {},
configSnippetGlobal: {},
},
},
{
name: "frontend only",
disableConfigSnippets: "frontend",
want: map[cfgSnippetType]struct{}{
configSnippetFrontend: {},
},
},
{
name: "backend only",
disableConfigSnippets: "backend",
want: map[cfgSnippetType]struct{}{
configSnippetBackend: {},
},
},
{
name: "global only",
disableConfigSnippets: "global",
want: map[cfgSnippetType]struct{}{
configSnippetGlobal: {},
},
},
{
name: "frontend and backend",
disableConfigSnippets: "backend,frontend",
want: map[cfgSnippetType]struct{}{
configSnippetFrontend: {},
configSnippetBackend: {},
},
},
{
name: "frontend and global, whitespaces",
disableConfigSnippets: " frontend, global",
want: map[cfgSnippetType]struct{}{
configSnippetGlobal: {},
configSnippetFrontend: {},
},
},
{
name: "frontend global, backend",
disableConfigSnippets: "backend,global,frontend",
want: map[cfgSnippetType]struct{}{
configSnippetBackend: {},
configSnippetFrontend: {},
configSnippetGlobal: {},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
DisableConfigSnippets(tt.disableConfigSnippets)
if !reflect.DeepEqual(cfgSnippet.disabledSnippets, tt.want) {
t.Errorf("DisabledConfigSnippets() = %v, want %v", cfgSnippet.disabledSnippets, tt.want)
}
})
}
}
7 changes: 6 additions & 1 deletion pkg/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,12 @@ func (c *HAProxyController) updateHAProxy() {
}

// global config-snippet
logger.Error(annotations.NewBackendCfgSnippet("backend-config-snippet", "configmap", nil).
logger.Error(annotations.NewCfgSnippet(
annotations.ConfigSnippetOptions{
Name: "backend-config-snippet",
Backend: utils.Ptr("configmap"),
Ingress: nil,
}).
Process(c.store, c.store.ConfigMaps.Main.Annotations))

for _, namespace := range c.store.Namespaces {
Expand Down
9 changes: 7 additions & 2 deletions pkg/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,13 @@ func (s *Service) HandleBackend(storeK8s store.K8s, client api.HAProxyClient, a
reload = true
logger.Debugf("Service '%s/%s': new backend '%s', reload required", s.resource.Namespace, s.resource.Name, newBackend.Name)
}
// config-snippet
backendCfgSnippetHandler := annotations.NewBackendCfgSnippet("backend-config-snippet", newBackend.Name, s.ingress)
// config-snippet: backend
backendCfgSnippetHandler := annotations.NewCfgSnippet(
annotations.ConfigSnippetOptions{
Name: "backend-config-snippet",
Backend: utils.PtrString(newBackend.Name),
Ingress: s.ingress,
})
backendCfgSnippetHandler.SetService(s.resource)
logger.Error(backendCfgSnippetHandler.Process(storeK8s, s.annotations...))
return
Expand Down
1 change: 1 addition & 0 deletions pkg/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,5 @@ type OSArgs struct {
PrometheusEnabled bool `long:"prometheus" description:"enable prometheus of IC data"`
DisableHTTP bool `long:"disable-http" description:"toggle to disable the HTTP frontend"`
DisableIPV6 bool `long:"disable-ipv6" description:"toggle to disable the IPv6 protocol from all frontends"`
DisableConfigSnippets string `long:"disable-config-snippets" description:"Allow to disable config snippets. List of comma separated values (possible values: all/global/backend/frontend)"`
}
Loading

0 comments on commit 5846dd5

Please sign in to comment.