Skip to content

Commit

Permalink
[GEP-21] Handle Seed IPFamilies (IPv6) (gardener#7561)
Browse files Browse the repository at this point in the history
* Replace decentralized FeatureGates with one centralized FeatureGate

Signed-off-by: Niclas Schad <niclas.schad@stackit.de>

* Regenerate certificate for gardener-admission-controller webhook

* Enable featureGate IPv6SingleStack and load featuresGates before validating SeedConfig

* Only filter envoyfilter via port number

Currently filtering by name restricts traffic to IPv4 only. By filtering
via port number this restriction is resolved and all traffic is respected.

* Filter config files via ipFamily

* Deploy IPv6 ready gardenlet

* Set IPv6 CIDRs via skaffold

* Set IPv6 IPs for local development setup

* Update Documentation for IPv6 local development

Signed-off-by: Felix Breuer <fbreuer@pm.me>

* Use net package to join host with port

Signed-off-by: Felix Breuer <fbreuer@pm.me>

* Make `IPv6SingleStack` explanation clearer

* Document purpose of central feature gate map

* Clean up gardenlet `bootstrapKubeconfig` values

Use the same `bootstrapKubeconfig` for all clusters with the in-cluster
kubernetes service except for the kind2 cluster.
With this, kind2 won't work with IPv6 single-stack, but we can live with
this for now.

* Fix SC2235

* Switch back to kind node's hostname

We tried to use `kubernetes.default.svc` instead of the kind node's hostname
as the garden cluster address for the gardenlet values.
This works from within the kind cluster itself also if it is IPv6 single-stack.
However, it doesn't work from within `ManagedSeeds`.
Hence, the managed seed e2e fails because gardenlet cannot register itself in the garden cluster.

* Document requirement for IPv6 `localhost` entry in `/etc/hosts`

* Introduce `garden.local.gardener.cloud` hostname that works everywhere

This replaces the use of kind container names to reach the garden cluster
and to reach the registry mirrors.
This works in
- the first and the second kind cluster
- in IPv4 and IPv6 kind clusters

* Adapt `0.0.0.0/0` `NetworkPolicies`

* Use `net.JoinHostPort` in all components

* Drop `bindAddress=0.0.0.0` everywhere, drop unnecessary IPv6 switches

`net.Listen` listens on all available IP addresses if the hostname
(configured by `*bindAddress` fields) is omitted.
I.e., this works for both IP families without explicit configuration.
This simplifies a lot of config files and development scripts.

* Make `bindAddress` chart values optional

* Dump logs from containerd-configuration-local-setup service

* Fix IP and cert handling in provider-local process-based setup

* Add missing license header

* Add missing comment for `gardener-admission-controller` `clusterIP` usage

* Consistently set feature gates in `validate`

* Manage kind network ourselves

* Replace `jq` in `kind-up.sh` with `yq`

* Move `DefaultFeatureGate.SetFromMap` to `options.complete`

---------

Signed-off-by: Niclas Schad <niclas.schad@stackit.de>
Signed-off-by: Felix Breuer <fbreuer@pm.me>
Co-authored-by: Niclas Schad <niclas.schad@stackit.de>
Co-authored-by: Tim Ebert <timebertt@gmail.com>
  • Loading branch information
3 people authored Apr 12, 2023
1 parent a36c673 commit 375af56
Show file tree
Hide file tree
Showing 123 changed files with 773 additions and 561 deletions.
15 changes: 9 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ GOMEGACHECK_DIR := $(TOOLS_DIR)/gomegacheck
# Rules for local development scenarios #
#########################################

dev-setup register-local-env start-extension-provider-local: export IPFAMILY := $(IPFAMILY)

.PHONY: dev-setup
dev-setup:
@if [ "$(DEV_SETUP_WITH_WEBHOOKS)" = "true" ]; then ./hack/local-development/dev-setup --with-webhooks; else ./hack/local-development/dev-setup; fi
Expand Down Expand Up @@ -310,12 +312,12 @@ kind-ha-single-zone-up kind-ha-single-zone-down gardener-ha-single-zone-up regis
kind-ha-multi-zone-up kind-ha-multi-zone-down gardener-ha-multi-zone-up register-kind-ha-multi-zone-env tear-down-kind-ha-multi-zone-env ci-e2e-kind-ha-multi-zone ci-e2e-kind-ha-multi-zone-upgrade: export KUBECONFIG = $(GARDENER_LOCAL_HA_MULTI_ZONE_KUBECONFIG)
kind-operator-up kind-operator-down operator-up operator-down test-e2e-local-operator ci-e2e-kind-operator: export KUBECONFIG = $(GARDENER_LOCAL_OPERATOR_KUBECONFIG)

kind-up: $(KIND) $(KUBECTL) $(HELM)
kind-up: $(KIND) $(KUBECTL) $(HELM) $(YQ)
./hack/kind-up.sh --cluster-name gardener-local --environment $(KIND_ENV) --path-kubeconfig $(REPO_ROOT)/example/provider-local/seed-kind/base/kubeconfig --path-cluster-values $(REPO_ROOT)/example/gardener-local/kind/local/values.yaml
kind-down: $(KIND)
./hack/kind-down.sh --cluster-name gardener-local --path-kubeconfig $(REPO_ROOT)/example/provider-local/seed-kind/base/kubeconfig

kind2-up: $(KIND) $(KUBECTL) $(HELM)
kind2-up: $(KIND) $(KUBECTL) $(HELM) $(YQ)
./hack/kind-up.sh --cluster-name gardener-local2 --environment $(KIND_ENV) --path-kubeconfig $(REPO_ROOT)/example/provider-local/seed-kind2/base/kubeconfig --path-cluster-values $(REPO_ROOT)/example/gardener-local/kind/local2/values.yaml --skip-registry
kind2-down: $(KIND)
./hack/kind-down.sh --cluster-name gardener-local2 --path-kubeconfig $(REPO_ROOT)/example/provider-local/seed-kind2/base/kubeconfig --keep-backupbuckets-dir
Expand All @@ -327,17 +329,17 @@ kind-extensions-down: $(KIND)
kind-extensions-clean:
./hack/kind-down.sh --cluster-name gardener-extensions --path-kubeconfig $(REPO_ROOT)/example/provider-extensions/garden/kubeconfig

kind-ha-single-zone-up: $(KIND) $(KUBECTL) $(HELM)
kind-ha-single-zone-up: $(KIND) $(KUBECTL) $(HELM) $(YQ)
./hack/kind-up.sh --cluster-name gardener-local-ha-single-zone --environment $(KIND_ENV) --path-kubeconfig $(REPO_ROOT)/example/provider-local/seed-kind-ha-single-zone/base/kubeconfig --path-cluster-values $(REPO_ROOT)/example/gardener-local/kind/ha-single-zone/values.yaml
kind-ha-single-zone-down: $(KIND)
./hack/kind-down.sh --cluster-name gardener-local-ha-single-zone --path-kubeconfig $(REPO_ROOT)/example/provider-local/seed-kind-ha-single-zone/base/kubeconfig

kind-ha-multi-zone-up: $(KIND) $(KUBECTL) $(HELM)
kind-ha-multi-zone-up: $(KIND) $(KUBECTL) $(HELM) $(YQ)
./hack/kind-up.sh --cluster-name gardener-local-ha-multi-zone --environment $(KIND_ENV) --path-kubeconfig $(REPO_ROOT)/example/provider-local/seed-kind-ha-multi-zone/base/kubeconfig --path-cluster-values $(REPO_ROOT)/example/gardener-local/kind/ha-multi-zone/values.yaml --multi-zonal
kind-ha-multi-zone-down: $(KIND)
./hack/kind-down.sh --cluster-name gardener-local-ha-multi-zone --path-kubeconfig $(REPO_ROOT)/example/provider-local/seed-kind-ha-multi-zone/base/kubeconfig

kind-operator-up: $(KIND) $(KUBECTL) $(HELM)
kind-operator-up: $(KIND) $(KUBECTL) $(HELM) $(YQ)
./hack/kind-up.sh --cluster-name gardener-operator-local --environment $(KIND_ENV) --path-kubeconfig $(REPO_ROOT)/example/gardener-local/kind/operator/kubeconfig --path-cluster-values $(REPO_ROOT)/example/gardener-local/kind/operator/values.yaml
mkdir -p $(REPO_ROOT)/dev/local-backupbuckets/gardener-operator
kind-operator-down: $(KIND)
Expand Down Expand Up @@ -375,7 +377,8 @@ gardener-extensions-down: $(SKAFFOLD) $(HELM) $(KUBECTL)

register-local-env: $(KUBECTL)
$(KUBECTL) apply -k $(REPO_ROOT)/example/provider-local/garden/local
$(KUBECTL) apply -k $(REPO_ROOT)/example/provider-local/seed-kind/local
@if [[ -z "$(IPFAMILY)" ]]; then $(KUBECTL) apply -k $(REPO_ROOT)/example/provider-local/seed-kind/local; else $(KUBECTL) apply -k $(REPO_ROOT)/example/provider-local/seed-kind/local-ipv6; fi

tear-down-local-env: $(KUBECTL)
$(KUBECTL) annotate project local confirmation.gardener.cloud/deletion=true
$(KUBECTL) delete -k $(REPO_ROOT)/example/provider-local/seed-kind/local
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,21 @@ data:
logFormat: {{ .Values.global.admission.config.logFormat | default "json" }}
server:
webhooks:
bindAddress: {{ required ".Values.global.admission.config.server.webhooks.bindAddress is required" .Values.global.admission.config.server.webhooks.bindAddress }}
{{- if .Values.global.admission.config.server.webhooks.bindAddress }}
bindAddress: {{ .Values.global.admission.config.server.webhooks.bindAddress }}
{{- end }}
port: {{ required ".Values.global.admission.config.server.webhooks.port is required" .Values.global.admission.config.server.webhooks.port }}
tls:
serverCertDir: /etc/gardener-admission-controller/srv
healthProbes:
bindAddress: {{ required ".Values.global.admission.config.server.healthProbes.bindAddress is required" .Values.global.admission.config.server.healthProbes.bindAddress }}
{{- if .Values.global.admission.config.server.healthProbes.bindAddress }}
bindAddress: {{ .Values.global.admission.config.server.healthProbes.bindAddress }}
{{- end }}
port: {{ required ".Values.global.admission.config.server.healthProbes.port is required" .Values.global.admission.config.server.healthProbes.port }}
metrics:
bindAddress: {{ required ".Values.global.admission.config.server.metrics.bindAddress is required" .Values.global.admission.config.server.metrics.bindAddress }}
{{- if .Values.global.admission.config.server.metrics.bindAddress }}
bindAddress: {{ .Values.global.admission.config.server.metrics.bindAddress }}
{{- end }}
port: {{ required ".Values.global.admission.config.server.metrics.port is required" .Values.global.admission.config.server.metrics.port }}
{{- if .Values.global.admission.config.server.resourceAdmissionConfiguration }}
resourceAdmissionConfiguration:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,15 @@ data:
logLevel: {{ required ".Values.global.controller.config.logLevel is required" .Values.global.controller.config.logLevel }}
server:
healthProbes:
bindAddress: {{ required ".Values.global.controller.config.server.healthProbes.bindAddress is required" .Values.global.controller.config.server.healthProbes.bindAddress }}
{{- if .Values.global.controller.config.server.healthProbes.bindAddress }}
bindAddress: {{ .Values.global.controller.config.server.healthProbes.bindAddress }}
{{- end }}
port: {{ required ".Values.global.controller.config.server.healthProbes.port is required" .Values.global.controller.config.server.healthProbes.port }}
{{- if .Values.global.controller.config.server.metrics }}
metrics:
bindAddress: {{ required ".Values.global.controller.config.server.metrics.bindAddress is required" .Values.global.controller.config.server.metrics.bindAddress }}
{{- if .Values.global.controller.config.server.metrics.bindAddress }}
bindAddress: {{ .Values.global.controller.config.server.metrics.bindAddress }}
{{- end }}
port: {{ required ".Values.global.controller.config.server.metrics.port is required" .Values.global.controller.config.server.metrics.port }}
{{- end }}
{{- if .Values.global.controller.config.debugging }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,14 @@ data:
logLevel: {{ required ".Values.global.scheduler.config.logLevel is required" .Values.global.scheduler.config.logLevel }}
server:
healthProbes:
bindAddress: {{ required ".Values.global.scheduler.config.server.healthProbes.bindAddress is required" .Values.global.scheduler.config.server.healthProbes.bindAddress }}
{{- if .Values.global.scheduler.config.server.healthProbes.bindAddress }}
bindAddress: {{ .Values.global.scheduler.config.server.healthProbes.bindAddress }}
{{- end }}
port: {{ required ".Values.global.scheduler.config.server.healthProbes.port is required" .Values.global.scheduler.config.server.healthProbes.port }}
metrics:
bindAddress: {{ required ".Values.global.scheduler.config.server.metrics.bindAddress is required" .Values.global.scheduler.config.server.metrics.bindAddress }}
{{- if .Values.global.scheduler.config.server.metrics.bindAddress }}
bindAddress: {{ .Values.global.scheduler.config.server.metrics.bindAddress }}
{{- end }}
port: {{ required ".Values.global.scheduler.config.server.metrics.port is required" .Values.global.scheduler.config.server.metrics.port }}
{{- if .Values.global.scheduler.config.debugging }}
debugging:
Expand Down
7 changes: 0 additions & 7 deletions charts/gardener/controlplane/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,6 @@ global:
logFormat: json
server:
webhooks:
bindAddress: 0.0.0.0
port: 2719
tlsSecretName:
tls:
Expand All @@ -320,10 +319,8 @@ global:
...
-----END RSA PRIVATE KEY-----
healthProbes:
bindAddress: 0.0.0.0
port: 2722
metrics:
bindAddress: 0.0.0.0
port: 2723
# resourceAdmissionConfiguration:
# limits:
Expand Down Expand Up @@ -447,10 +444,8 @@ global:
logLevel: info
server:
healthProbes:
bindAddress: 0.0.0.0
port: 2718
metrics:
bindAddress: 0.0.0.0
port: 2719
debugging:
enableProfiling: false
Expand Down Expand Up @@ -494,10 +489,8 @@ global:
logLevel: info
server:
healthProbes:
bindAddress: 0.0.0.0
port: 10251
metrics:
bindAddress: 0.0.0.0
port: 19251
debugging:
enableProfiling: false
Expand Down
8 changes: 6 additions & 2 deletions charts/gardener/gardenlet/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,15 @@ config.yaml: |
logFormat: {{ .Values.config.logFormat }}
server:
healthProbes:
bindAddress: {{ required ".Values.config.server.healthProbes.bindAddress is required" .Values.config.server.healthProbes.bindAddress }}
{{- if .Values.config.server.healthProbes.bindAddress }}
bindAddress: {{ .Values.config.server.healthProbes.bindAddress }}
{{- end }}
port: {{ required ".Values.config.server.healthProbes.port is required" .Values.config.server.healthProbes.port }}
{{- if .Values.config.server.metrics }}
metrics:
bindAddress: {{ required ".Values.config.server.metrics.bindAddress is required" .Values.config.server.metrics.bindAddress }}
{{- if .Values.config.server.metrics.bindAddress }}
bindAddress: {{ .Values.config.server.metrics.bindAddress }}
{{- end }}
port: {{ required ".Values.config.server.metrics.port is required" .Values.config.server.metrics.port }}
{{- end }}
{{- if .Values.config.debugging }}
Expand Down
2 changes: 2 additions & 0 deletions charts/gardener/gardenlet/templates/networkpolicy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@ spec:
podSelector: {}
- ipBlock:
cidr: 0.0.0.0/0
- ipBlock:
cidr: ::/0
policyTypes:
- Egress
2 changes: 0 additions & 2 deletions charts/gardener/gardenlet/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,8 @@ config:
logFormat: json
server:
healthProbes:
bindAddress: 0.0.0.0
port: 2728
metrics:
bindAddress: 0.0.0.0
port: 2729
debugging:
enableProfiling: false
Expand Down
3 changes: 0 additions & 3 deletions charts/gardener/operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,10 @@ config:
logFormat: json
server:
webhooks:
bindAddress: 0.0.0.0
port: 2750
healthProbes:
bindAddress: 0.0.0.0
port: 2751
metrics:
bindAddress: 0.0.0.0
port: 2752
debugging:
enableProfiling: false
Expand Down
3 changes: 0 additions & 3 deletions charts/gardener/resource-manager/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ global:
logFormat: text
server:
webhooks:
bindAddress: 0.0.0.0
port: 10250
# ca: |
# some-tls-certificate
Expand All @@ -61,10 +60,8 @@ global:
# privateKey: |
# some-private-key
healthProbes:
bindAddress: 0.0.0.0
port: 8081
metrics:
bindAddress: 0.0.0.0
port: 8080
debugging:
enableProfiling: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ spec:
namespaceSelector: {}
- ipBlock:
cidr: 0.0.0.0/0
- ipBlock:
cidr: ::/0
ingress:
- from:
- podSelector: {}
namespaceSelector: {}
- ipBlock:
cidr: 0.0.0.0/0
- ipBlock:
cidr: ::/0
policyTypes:
- Egress
- Ingress
Expand Down
6 changes: 4 additions & 2 deletions cmd/gardener-admission-controller/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ package app
import (
"context"
"fmt"
"net"
"os"
goruntime "runtime"
"strconv"
"time"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -111,8 +113,8 @@ func run(ctx context.Context, log logr.Logger, cfg *config.AdmissionControllerCo
Port: cfg.Server.Webhooks.Port,
CertDir: cfg.Server.Webhooks.TLS.ServerCertDir,

HealthProbeBindAddress: fmt.Sprintf("%s:%d", cfg.Server.HealthProbes.BindAddress, cfg.Server.HealthProbes.Port),
MetricsBindAddress: fmt.Sprintf("%s:%d", cfg.Server.Metrics.BindAddress, cfg.Server.Metrics.Port),
HealthProbeBindAddress: net.JoinHostPort(cfg.Server.HealthProbes.BindAddress, strconv.Itoa(cfg.Server.HealthProbes.Port)),
MetricsBindAddress: net.JoinHostPort(cfg.Server.Metrics.BindAddress, strconv.Itoa(cfg.Server.Metrics.Port)),

LeaderElection: false,
})
Expand Down
6 changes: 3 additions & 3 deletions cmd/gardener-apiserver/app/gardener_apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import (
genericoptions "k8s.io/apiserver/pkg/server/options"
"k8s.io/apiserver/pkg/server/resourceconfig"
serverstorage "k8s.io/apiserver/pkg/server/storage"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic"
kubeinformers "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
Expand Down Expand Up @@ -68,6 +67,7 @@ import (
seedmanagementinformers "github.com/gardener/gardener/pkg/client/seedmanagement/informers/externalversions"
settingsclientset "github.com/gardener/gardener/pkg/client/settings/clientset/versioned"
settingsinformers "github.com/gardener/gardener/pkg/client/settings/informers/externalversions"
"github.com/gardener/gardener/pkg/features"
"github.com/gardener/gardener/pkg/logger"
"github.com/gardener/gardener/pkg/openapi"
)
Expand Down Expand Up @@ -270,7 +270,7 @@ func (o *Options) Run(ctx context.Context) error {
klog.SetLogger(log)

log.Info("Starting gardener-apiserver", "version", version.Get())
log.Info("Feature Gates", "featureGates", utilfeature.DefaultFeatureGate)
log.Info("Feature Gates", "featureGates", features.DefaultFeatureGate)

// Create clientset for the native Kubernetes API group
// Use remote kubeconfig file (if set) or in-cluster config to create a new Kubernetes client for the native Kubernetes API groups
Expand Down Expand Up @@ -398,7 +398,7 @@ func (o *Options) ApplyTo(config *apiserver.Config) error {
}
if initializers, err := o.Recommended.ExtraAdmissionInitializers(gardenerAPIServerConfig); err != nil {
return err
} else if err := o.Recommended.Admission.ApplyTo(&gardenerAPIServerConfig.Config, gardenerAPIServerConfig.SharedInformerFactory, gardenerAPIServerConfig.ClientConfig, utilfeature.DefaultFeatureGate, initializers...); err != nil {
} else if err := o.Recommended.Admission.ApplyTo(&gardenerAPIServerConfig.Config, gardenerAPIServerConfig.SharedInformerFactory, gardenerAPIServerConfig.ClientConfig, features.DefaultFeatureGate, initializers...); err != nil {
return err
}
if err := o.ExtraOptions.ApplyTo(config); err != nil {
Expand Down
14 changes: 6 additions & 8 deletions cmd/gardener-controller-manager/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ package app
import (
"context"
"fmt"
"net"
"os"
goruntime "runtime"
"strconv"
"time"

"github.com/go-logr/logr"
Expand All @@ -40,8 +42,8 @@ import (
"github.com/gardener/gardener/pkg/client/kubernetes"
"github.com/gardener/gardener/pkg/controllermanager/apis/config"
"github.com/gardener/gardener/pkg/controllermanager/controller"
controllermanagerfeatures "github.com/gardener/gardener/pkg/controllermanager/features"
"github.com/gardener/gardener/pkg/controllerutils/routes"
"github.com/gardener/gardener/pkg/features"
gardenerhealthz "github.com/gardener/gardener/pkg/healthz"
"github.com/gardener/gardener/pkg/logger"
)
Expand Down Expand Up @@ -97,11 +99,7 @@ func NewCommand() *cobra.Command {
}

func run(ctx context.Context, log logr.Logger, cfg *config.ControllerManagerConfiguration) error {
// Add feature flags
if err := controllermanagerfeatures.FeatureGate.SetFromMap(cfg.FeatureGates); err != nil {
return err
}
log.Info("Feature Gates", "featureGates", controllermanagerfeatures.FeatureGate.String())
log.Info("Feature Gates", "featureGates", features.DefaultFeatureGate)

// This is like importing the automaxprocs package for its init func (it will in turn call maxprocs.Set).
// Here we pass a custom logger, so that the result of the library gets logged to the same logger we use for the
Expand All @@ -128,8 +126,8 @@ func run(ctx context.Context, log logr.Logger, cfg *config.ControllerManagerConf
Scheme: kubernetes.GardenScheme,
GracefulShutdownTimeout: pointer.Duration(5 * time.Second),

HealthProbeBindAddress: fmt.Sprintf("%s:%d", cfg.Server.HealthProbes.BindAddress, cfg.Server.HealthProbes.Port),
MetricsBindAddress: fmt.Sprintf("%s:%d", cfg.Server.Metrics.BindAddress, cfg.Server.Metrics.Port),
HealthProbeBindAddress: net.JoinHostPort(cfg.Server.HealthProbes.BindAddress, strconv.Itoa(cfg.Server.HealthProbes.Port)),
MetricsBindAddress: net.JoinHostPort(cfg.Server.Metrics.BindAddress, strconv.Itoa(cfg.Server.Metrics.Port)),

LeaderElection: cfg.LeaderElection.LeaderElect,
LeaderElectionResourceLock: cfg.LeaderElection.ResourceLock,
Expand Down
7 changes: 7 additions & 0 deletions cmd/gardener-controller-manager/app/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/gardener/gardener/pkg/controllermanager/apis/config"
controllermanagerv1alpha1 "github.com/gardener/gardener/pkg/controllermanager/apis/config/v1alpha1"
controllermanagervalidation "github.com/gardener/gardener/pkg/controllermanager/apis/config/validation"
"github.com/gardener/gardener/pkg/features"
)

var configDecoder runtime.Decoder
Expand Down Expand Up @@ -64,6 +65,12 @@ func (o *options) complete() error {
return fmt.Errorf("error decoding config: %w", err)
}

// Set feature gates immediately after decoding the config.
// Feature gates might influence the next steps, e.g., validating the config.
if err := features.DefaultFeatureGate.SetFromMap(o.config.FeatureGates); err != nil {
return err
}

return nil
}

Expand Down
Loading

0 comments on commit 375af56

Please sign in to comment.