diff --git a/charts/gardener/gardenlet/charts/runtime/templates/configmap-componentconfig.yaml b/charts/gardener/gardenlet/charts/runtime/templates/configmap-componentconfig.yaml
index 64695616b7b..abdffcc801a 100644
--- a/charts/gardener/gardenlet/charts/runtime/templates/configmap-componentconfig.yaml
+++ b/charts/gardener/gardenlet/charts/runtime/templates/configmap-componentconfig.yaml
@@ -161,10 +161,6 @@ data:
{{- if .Values.global.gardenlet.config.featureGates }}
featureGates:
{{ toYaml .Values.global.gardenlet.config.featureGates | indent 6 }}
- {{- end }}
- {{- if .Values.global.gardenlet.config.seedSelector }}
- seedSelector:
-{{ toYaml .Values.global.gardenlet.config.seedSelector | indent 6 }}
{{- end }}
{{- if .Values.global.gardenlet.config.seedConfig }}
seedConfig:
diff --git a/charts/gardener/gardenlet/values.yaml b/charts/gardener/gardenlet/values.yaml
index 91438eeb686..97b83c5fdd9 100644
--- a/charts/gardener/gardenlet/values.yaml
+++ b/charts/gardener/gardenlet/values.yaml
@@ -155,7 +155,6 @@ global:
# labels:
# istio: ingressgateway-handler-2
- # seedSelector: {}
# seedConfig: {}
# logging:
# fluentBit:
diff --git a/cmd/gardenlet/app/gardenlet.go b/cmd/gardenlet/app/gardenlet.go
index 8296020ca8a..d52c8b66e87 100644
--- a/cmd/gardenlet/app/gardenlet.go
+++ b/cmd/gardenlet/app/gardenlet.go
@@ -323,7 +323,6 @@ func NewGardenlet(ctx context.Context, cfg *config.GardenletConfiguration) (*Gar
}
seedClientMapBuilder := clientmapbuilder.NewSeedClientMapBuilder().
- WithInCluster(cfg.SeedSelector == nil).
WithClientConnectionConfig(&cfg.SeedClientConnection.ClientConnectionConfiguration)
shootClientMapBuilder := clientmapbuilder.NewShootClientMapBuilder().
WithClientConnectionConfig(&cfg.ShootClientConnection.ClientConnectionConfiguration)
diff --git a/docs/concepts/gardenlet.md b/docs/concepts/gardenlet.md
index 2a8e6bbbf45..fd5971bfada 100644
--- a/docs/concepts/gardenlet.md
+++ b/docs/concepts/gardenlet.md
@@ -111,28 +111,34 @@ for example, using command `kubectl certificate approve seed-csr-<...>`).
If that doesn’t happen within 15 minutes,
the gardenlet repeats the process and creates another CSR.
-## Seed Config versus Seed Selector
-
-The usage of the gardenlet is flexible:
-
-| Usage | Description |
-|:---|:---|
-| `seedConfig` | Run one gardenlet per seed cluster inside the seed cluster itself.|
-| `seedSelector` | Use one gardenlet to manage multiple seed clusters. The gardenlet can run outside of the seed cluster.|
-
-> For production use it’s recommended to go for the `seedConfig` option,
-> because it makes scaling easier and leads to a better distribution of responsibilities.
-
-* Provide a `seedConfig` that contains information about the seed cluster itself
- if you want the gardenlet in the standard way,
- see [the example gardenlet configuration](../../example/20-componentconfig-gardenlet.yaml).
- Once bootstrapped, the gardenlet creates and updates its `Seed` object itself.
-
-* Provide a `seedSelector` that incorporates a label selector for the
- targeted seed clusters if you want the gardenlet to manage multiple seeds,
- see [the example gardenlet configuration](../../example/20-componentconfig-gardenlet.yaml).
- In this case, you have to create the `Seed` objects
- together with a `kubeconfig` pointing to the cluster yourself.
+## Configuring the Seed to work with
+
+The Gardenlet works with a single seed, which must be configured in the
+`GardenletConfiguration` under `.seedConfig`. This must be a copy of the
+`Seed` resource, for example (see `example/20-componentconfig-gardenlet.yaml`
+for a more complete example):
+
+```yaml
+apiVersion: gardenlet.config.gardener.cloud/v1alpha1
+kind: GardenletConfiguration
+seedConfig:
+ metadata:
+ name: my-seed
+ spec:
+ provider:
+ type: aws
+ # ...
+ secretRef:
+ name: my-seed-secret
+ namespace: garden
+```
+
+When using `make start-gardenlet`, the corresponding script will automatically
+fetch the seed cluster's `kubeconfig` based on the `seedConfig.spec.secretRef`
+and set the environment accordingly.
+
+On startup, gardenlet registers a `Seed` resource using the given template
+in `seedConfig` if it's not present already.
## Component Configuration
@@ -166,13 +172,7 @@ It’s used as a liveness probe in the `Deployment` of the gardenlet.
If the gardenlet fails to renew its lease
then the endpoint returns `500 Internal Server Error`, otherwise it returns `200 OK`.
-> ⚠️
In case the gardenlet is managing multiple seeds
-> (that is, a seed selector is used) then the `/healthz`
-> reports `500 Internal Server Error` if there is at least one seed
-> for which it couldn’t renew its lease. Only if it can renew the lease
-> for all seeds it reports `200 OK`.
-
-Please note, that the `/healthz` only indicates whether the gardenlet
+Please note that the `/healthz` only indicates whether the gardenlet
could successfully probe the Seed's API server and renew the lease with
the Garden cluster.
It does *not* show that the Gardener extension API server (with the Gardener resource groups)
diff --git a/docs/deployment/deploy_gardenlet_manually.md b/docs/deployment/deploy_gardenlet_manually.md
index eb6f4252e00..3564b45f9c6 100755
--- a/docs/deployment/deploy_gardenlet_manually.md
+++ b/docs/deployment/deploy_gardenlet_manually.md
@@ -2,16 +2,16 @@
Manually deploying a gardenlet is required in the following cases:
-- The Kubernetes cluster to be registered as a seed cluster has no public endpoint,
- because it is behind a firewall.
+- The Kubernetes cluster to be registered as a seed cluster has no public endpoint,
+ because it is behind a firewall.
The gardenlet must then be deployed into the cluster itself.
-- The Kubernetes cluster to be registered as a seed cluster is managed externally
+- The Kubernetes cluster to be registered as a seed cluster is managed externally
(the Kubernetes cluster is not a shoot cluster, so [Automatic Deployment of Gardenlets](deploy_gardenlet_automatically.md) cannot be used).
-- The gardenlet runs outside of the Kubernetes cluster
- that should be registered as a seed cluster.
- (The gardenlet is not restricted to run in the seed cluster or
+- The gardenlet runs outside of the Kubernetes cluster
+ that should be registered as a seed cluster.
+ (The gardenlet is not restricted to run in the seed cluster or
to be deployed into a Kubernetes cluster at all).
> Once you’ve deployed a gardenlet manually, for example, behind a firewall, you can deploy new gardenlets automatically. The manually deployed gardenlet is then used as a template for the new gardenlets. More information: [Automatic Deployment of Gardenlets](deploy_gardenlet_automatically.md).
@@ -19,15 +19,15 @@ Manually deploying a gardenlet is required in the following cases:
## Prerequisites
### Kubernetes cluster that should be registered as a seed cluster
-
+
- Verify that the cluster has a [supported Kubernetes version](../usage/supported_k8s_versions.md).
-
-- Determine the nodes, pods, and services CIDR of the cluster.
+
+- Determine the nodes, pods, and services CIDR of the cluster.
You need to configure this information in the `Seed` configuration.
Gardener uses this information to check that the shoot cluster isn’t created with overlapping CIDR ranges.
- Every Seed cluster needs an Ingress controller which distributes external requests to internal components like grafana and prometheus. Gardener supports two approaches to achieve this:
-
+
a. Gardener managed Ingress controller and DNS records. For this configure the following lines in your [Seed resource](../../example/50-seed.yaml):
```yaml
spec:
@@ -49,7 +49,7 @@ spec:
b. Self-managed DNS record and Ingress controller:
-:warning:
+:warning:
There should exist a DNS record `*.ingress.` where `` is the value of the `.dns.ingressDomain` field of [a Seed cluster resource](../../example/50-seed.yaml) (or the [respective Gardenlet configuration](../../example/20-componentconfig-gardenlet.yaml#L84-L85)).
*This is how it could be done for the Nginx ingress controller*
@@ -77,27 +77,27 @@ spec:
### `kubeconfig` for the Seed Cluster
-The `kubeconfig` is required to deploy the gardenlet Helm chart to the seed cluster.
-The gardenlet requires certain privileges to be able to operate.
-These privileges are described in RBAC resources in the gardenlet Helm chart (see [charts/gardener/gardenlet/charts/runtime/templates](../../charts/gardener/gardenlet/charts/runtime/templates)).
-The Helm chart contains a service account `gardenlet`
+The `kubeconfig` is required to deploy the gardenlet Helm chart to the seed cluster.
+The gardenlet requires certain privileges to be able to operate.
+These privileges are described in RBAC resources in the gardenlet Helm chart (see [charts/gardener/gardenlet/charts/runtime/templates](../../charts/gardener/gardenlet/charts/runtime/templates)).
+The Helm chart contains a service account `gardenlet`
that the gardenlet deployment uses by default to talk to the Seed API server.
-> If the gardenlet isn’t deployed in the seed cluster,
-> the gardenlet can be configured to use a `kubeconfig`,
-> which also requires the above-mentioned privileges, from a mounted directory.
-> The `kubeconfig` is specified in section `seedClientConnection.kubeconfig`
+> If the gardenlet isn’t deployed in the seed cluster,
+> the gardenlet can be configured to use a `kubeconfig`,
+> which also requires the above-mentioned privileges, from a mounted directory.
+> The `kubeconfig` is specified in section `seedClientConnection.kubeconfig`
> of the [Gardenlet configuration](../../example/20-componentconfig-gardenlet.yaml).
-> This configuration option isn’t used in the following,
-> as this procedure only describes the recommended setup option
-> where the gardenlet is running in the seed cluster itself.
+> This configuration option isn’t used in the following,
+> as this procedure only describes the recommended setup option
+> where the gardenlet is running in the seed cluster itself.
## Procedure Overview
1. Prepare the garden cluster:
1. [Create a bootstrap token secret in the `kube-system` namespace of the garden cluster](#create-a-bootstrap-token-secret-in-the-kube-system-namespace-of-the-garden-cluster)
1. [Create RBAC roles for the gardenlet to allow bootstrapping in the garden cluster](#create-rbac-roles-for-the-gardenlet-to-allow-bootstrapping-in-the-garden-cluster)
-
+
1. [Prepare the gardenlet Helm chart](#prepare-the-gardenlet-helm-chart).
1. [Automatically register shoot cluster as a seed cluster](#automatically-register-shoot-cluster-as-a-seed-cluster).
1. [Deploy the gardenlet](#deploy-the-gardenlet)
@@ -105,32 +105,32 @@ that the gardenlet deployment uses by default to talk to the Seed API server.
## Create a bootstrap token secret in the `kube-system` namespace of the garden cluster
-The gardenlet needs to talk to the [Gardener API server](../concepts/apiserver.md) residing in the garden cluster.
+The gardenlet needs to talk to the [Gardener API server](../concepts/apiserver.md) residing in the garden cluster.
-The gardenlet can be configured with an already existing garden cluster `kubeconfig` in one of the following ways:
+The gardenlet can be configured with an already existing garden cluster `kubeconfig` in one of the following ways:
- - Either by specifying `gardenClientConnection.kubeconfig`
+ - Either by specifying `gardenClientConnection.kubeconfig`
in the [Gardenlet configuration](../../example/20-componentconfig-gardenlet.yaml) or
- - by supplying the environment variable `GARDEN_KUBECONFIG` pointing to
+ - by supplying the environment variable `GARDEN_KUBECONFIG` pointing to
a mounted `kubeconfig` file).
-The preferred way however, is to use the gardenlets ability to request
-a signed certificate for the garden cluster by leveraging
+The preferred way however, is to use the gardenlets ability to request
+a signed certificate for the garden cluster by leveraging
[Kubernetes Certificate Signing Requests](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/).
-The gardenlet performs a TLS bootstrapping process that is similar to the
+The gardenlet performs a TLS bootstrapping process that is similar to the
[Kubelet TLS Bootstrapping](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/).
-Make sure that the API server of the garden cluster has
-[bootstrap token authentication](https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/#enabling-bootstrap-token-authentication)
+Make sure that the API server of the garden cluster has
+[bootstrap token authentication](https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/#enabling-bootstrap-token-authentication)
enabled.
-The client credentials required for the gardenlets TLS bootstrapping process,
+The client credentials required for the gardenlets TLS bootstrapping process,
need to be either `token` or `certificate` (OIDC isn’t supported) and have permissions
to create a Certificate Signing Request ([CSR](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/)).
-It’s recommended to use [bootstrap tokens](https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/)
+It’s recommended to use [bootstrap tokens](https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/)
due to their desirable security properties (such as a limited token lifetime).
-Therefore, first create a bootstrap token secret for the garden cluster:
+Therefore, first create a bootstrap token secret for the garden cluster:
``` yaml
apiVersion: v1
@@ -158,20 +158,20 @@ stringData:
usage-bootstrap-signing: "true"
```
-When you later prepare the gardenlet Helm chart,
+When you later prepare the gardenlet Helm chart,
a `kubeconfig` based on this token is shared with the gardenlet upon deployment.
## Create RBAC roles for the gardenlet to allow bootstrapping in the garden cluster
-
-This step is only required if the gardenlet you deploy is the first gardenlet
-in the Gardener installation.
-Additionally, when using the [control plane chart](../../charts/gardener/controlplane),
-the following resources are already contained in the Helm chart,
-that is, if you use it you can skip these steps as the needed RBAC roles already exist.
+
+This step is only required if the gardenlet you deploy is the first gardenlet
+in the Gardener installation.
+Additionally, when using the [control plane chart](../../charts/gardener/controlplane),
+the following resources are already contained in the Helm chart,
+that is, if you use it you can skip these steps as the needed RBAC roles already exist.
The gardenlet uses the configured bootstrap `kubeconfig` in `gardenClientConnection.bootstrapKubeconfig` to request a signed certificate for the user `gardener.cloud:system:seed:` in the group `gardener.cloud:system:seeds`.
-Create a `ClusterRole` and `ClusterRoleBinding` that grant full admin permissions to authenticated gardenlets.
+Create a `ClusterRole` and `ClusterRoleBinding` that grant full admin permissions to authenticated gardenlets.
Create the following resources in the garden cluster:
@@ -243,17 +243,17 @@ Please take a look into [this document](gardenlet_api_access.md).
## Prepare the gardenlet Helm chart
-This section only describes the minimal configuration,
-using the global configuration values of the gardenlet Helm chart.
-For an overview over all values, see the [configuration values](../../charts/gardener/gardenlet/values.yaml).
+This section only describes the minimal configuration,
+using the global configuration values of the gardenlet Helm chart.
+For an overview over all values, see the [configuration values](../../charts/gardener/gardenlet/values.yaml).
We refer to the global configuration values as _gardenlet configuration_ in the remaining procedure.
1. Create a gardenlet configuration `gardenlet-values.yaml` based on [this template](https://github.com/gardener/gardener/blob/master/charts/gardener/gardenlet/values.yaml).
-
+
2. Create a bootstrap `kubeconfig` based on the bootstrap token created in the garden cluster.
Replace the `` with `token-id.token-secret` (from our previous example: `07401b.f395accd246ae52d`) from the bootstrap token secret.
-
+
```yaml
apiVersion: v1
kind: Config
@@ -275,7 +275,7 @@ We refer to the global configuration values as _gardenlet configuration_ in the
```
3. In section `gardenClientConnection.bootstrapKubeconfig` of your gardenlet configuration, provide the bootstrap `kubeconfig` together with a name and namespace to the gardenlet Helm chart.
-
+
```yaml
gardenClientConnection:
bootstrapKubeconfig:
@@ -284,14 +284,14 @@ We refer to the global configuration values as _gardenlet configuration_ in the
kubeconfig: |
# will be base64 encoded by helm
```
-
+
The bootstrap `kubeconfig` is stored in the specified secret.
-
-4. In section `gardenClientConnection.kubeconfigSecret` of your gardenlet configuration,
- define a name and a namespace where the gardenlet stores
- the real `kubeconfig` that it creates during the bootstrap process. If the secret doesn't exist,
- the gardenlet creates it for you.
-
+
+4. In section `gardenClientConnection.kubeconfigSecret` of your gardenlet configuration,
+ define a name and a namespace where the gardenlet stores
+ the real `kubeconfig` that it creates during the bootstrap process. If the secret doesn't exist,
+ the gardenlet creates it for you.
+
```yaml
gardenClientConnection:
kubeconfigSecret:
@@ -301,15 +301,15 @@ We refer to the global configuration values as _gardenlet configuration_ in the
## Automatically register shoot cluster as a seed cluster
-A seed cluster can either be registered by manually creating
-the [`Seed` resource](../../example/50-seed.yaml)
-or automatically by the gardenlet.
-This functionality is useful for managed seed clusters,
-as the gardenlet in the garden cluster deploys a copy of itself
-into the cluster with automatic registration of the `Seed` configured.
+A seed cluster can either be registered by manually creating
+the [`Seed` resource](../../example/50-seed.yaml)
+or automatically by the gardenlet.
+This functionality is useful for managed seed clusters,
+as the gardenlet in the garden cluster deploys a copy of itself
+into the cluster with automatic registration of the `Seed` configured.
However, it can also be used to have a streamlined seed cluster registration process when manually deploying the gardenlet.
-> This procedure doesn’t describe all the possible configurations
+> This procedure doesn’t describe all the possible configurations
> for the `Seed` resource. For more information, see:
> * [Example Seed resource](../../example/50-seed.yaml)
> * [Configurable Seed settings](../usage/seed_settings.md).
@@ -317,12 +317,9 @@ However, it can also be used to have a streamlined seed cluster registration pro
### Adjust the gardenlet component configuration
1. Supply the `Seed` resource in section `seedConfig` of your gardenlet configuration `gardenlet-values.yaml`.
-
- > Note that with the `seedConfig` supplied, the gardenlet is only responsible to create and reconcile this one configured seed (in the previous example: `sweet-seed`). The gardenlet can also be configured to reconcile (but not create!) multiple Seeds [based on a label selector](../concepts/gardenlet.md#seed-config-vs-seed-selector), which is only recommended [for a development setup](../development/local_setup.md#appendix).
-
1. Add the `seedConfig` to your gardenlet configuration `gardenlet-values.yaml`.
The field `seedConfig.spec.provider.type` specifies the infrastructure provider type (for example, `aws`) of the seed cluster.
-For all supported infrastructure providers, see [Known Extension Implementations](../../extensions/README.md#known-extension-implementations).
+For all supported infrastructure providers, see [Known Extension Implementations](../../extensions/README.md#known-extension-implementations).
```yaml
....
@@ -346,18 +343,18 @@ For all supported infrastructure providers, see [Known Extension Implementations
### Optional: Enable backup and restore
-The seed cluster can be set up with backup and restore
-for the main `etcds` of shoot clusters.
+The seed cluster can be set up with backup and restore
+for the main `etcds` of shoot clusters.
Gardener uses [etcd-backup-restore](https://github.com/gardener/etcd-backup-restore)
-that [integrates with different storage providers](https://github.com/gardener/etcd-backup-restore/blob/master/doc/usage/getting_started.md#usage)
+that [integrates with different storage providers](https://github.com/gardener/etcd-backup-restore/blob/master/doc/usage/getting_started.md#usage)
to store the shoot cluster's main `etcd` backups.
Make sure to obtain client credentials that have sufficient permissions with the chosen storage provider.
Create a secret in the garden cluster with client credentials for the storage provider.
-The format of the secret is cloud provider specific and can be found
-in the repository of the respective Gardener extension.
-For example, the secret for AWS S3 can be found in the AWS provider extension
+The format of the secret is cloud provider specific and can be found
+in the repository of the respective Gardener extension.
+For example, the secret for AWS S3 can be found in the AWS provider extension
([30-etcd-backup-secret.yaml](https://github.com/gardener/gardener-extension-provider-aws/blob/master/example/30-etcd-backup-secret.yaml)).
```yaml
@@ -388,12 +385,12 @@ seedConfig:
## Deploy the gardenlet
-> The gardenlet doesn’t have to run in the same Kubernetes cluster as the seed cluster
-> it’s registering and reconciling, but it is in most cases advantageous
-> to use in-cluster communication to talk to the Seed API server.
+> The gardenlet doesn’t have to run in the same Kubernetes cluster as the seed cluster
+> it’s registering and reconciling, but it is in most cases advantageous
+> to use in-cluster communication to talk to the Seed API server.
> Running a gardenlet outside of the cluster is mostly used for local development.
-The `gardenlet-values.yaml` looks something like this
+The `gardenlet-values.yaml` looks something like this
(with automatic Seed registration and backup for shoot clusters enabled):
```yaml
@@ -418,7 +415,7 @@ global:
server:
name: my-kubernetes-cluster
....
-
+
kubeconfigSecret:
name: gardenlet-kubeconfig
namespace: garden
@@ -467,37 +464,37 @@ This helm chart creates:
## Check that the gardenlet is successfully deployed
1. Check that the gardenlets certificate bootstrap was successful.
-
+
Check if the secret `gardenlet-kubeconfig` in the namespace `garden` in the seed cluster
is created and contains a `kubeconfig` with a valid certificate.
-
+
1. Get the `kubeconfig` from the created secret.
-
+
```
$ kubectl -n garden get secret gardenlet-kubeconfig -o json | jq -r .data.kubeconfig | base64 -d
```
-
+
1. Test against the garden cluster and verify it’s working.
-
+
1. Extract the `client-certificate-data` from the user `gardenlet`.
-
+
1. View the certificate:
-
+
```
$ openssl x509 -in ./gardenlet-cert -noout -text
```
-
- Check that the certificate is valid for a year (that is the lifetime of new certificates).
-
+
+ Check that the certificate is valid for a year (that is the lifetime of new certificates).
+
2. Check that the bootstrap secret `gardenlet-bootstrap-kubeconfig` has been deleted from the seed cluster in namespace `garden`.
-
+
3. Check that the seed cluster is registered and `READY` in the garden cluster.
-
+
Check that the seed cluster `sweet-seed` exists and all conditions indicate that it’s available.
If so, the [Gardenlet is sending regular heartbeats](../concepts/gardenlet.md#heartbeats) and the [seed bootstrapping](../usage/seed_bootstrapping.md) was successful.
-
+
Check that the conditions on the `Seed` resource look similar to the following:
-
+
```bash
$ kubectl get seed sweet-seed -o json | jq .status.conditions
[
diff --git a/docs/usage/managed_seed.md b/docs/usage/managed_seed.md
index e97b1d1abdf..104339ff6ce 100644
--- a/docs/usage/managed_seed.md
+++ b/docs/usage/managed_seed.md
@@ -8,8 +8,8 @@ An existing shoot can be registered as a seed by creating a `ManagedSeed` resour
* `gardenlet` deployment parameters, such as the number of replicas, the image, etc.
* The `GardenletConfiguration` resource that contains controllers configuration, feature gates, and a `seedConfig` section that contains the `Seed` spec and parts of its metadata.
* Additional configuration parameters, such as the garden connection bootstrap mechanism (see [TLS Bootstrapping](../concepts/gardenlet.md#tls-bootstrapping)), and whether to merge the provided configuration with the configuration of the parent `gardenlet`.
-
-Either the `seedTemplate` or the `gardenlet` section must be specified, but not both:
+
+Either the `seedTemplate` or the `gardenlet` section must be specified, but not both:
* If the `seedTemplate` section is specified, `gardenlet` is not deployed to the shoot, and a new `Seed` resource is created based on the template.
* If the `gardenlet` section is specified, `gardenlet` is deployed to the shoot, and it registers a new seed upon startup based on the `seedConfig` section of the `GardenletConfiguration` resource.
@@ -17,9 +17,9 @@ Either the `seedTemplate` or the `gardenlet` section must be specified, but not
Note the following important aspects:
* Unlike the `Seed` resource, the `ManagedSeed` resource is namespaced. Currently, managed seeds are restricted to the `garden` namespace.
-* The newly created `Seed` resource always has the same name as the `ManagedSeed` resource. Attempting to specify a different name in `seedTemplate` or `seedConfig` will fail.
+* The newly created `Seed` resource always has the same name as the `ManagedSeed` resource. Attempting to specify a different name in `seedTemplate` or `seedConfig` will fail.
* The `ManagedSeed` resource must always refer to an existing shoot. Attempting to create a `ManagedSeed` referring to a non-existing shoot will fail.
-* A shoot that is being referred to by a `ManagedSeed` cannot be deleted. Attempting to delete such a shoot will fail.
+* A shoot that is being referred to by a `ManagedSeed` cannot be deleted. Attempting to delete such a shoot will fail.
* You can omit practically everything from the `seedTemplate` or `gardenlet` section, including all or most of the `Seed` spec fields. Proper defaults will be supplied in all cases, based either on the most common use cases or the information already available in the `Shoot` resource.
* Some `Seed` spec fields, for example the provider type and region, networking CIDRs for pods, services, and nodes, etc., must be the same as the corresponding `Shoot` spec fields of the shoot that is being registered as seed. Attempting to use different values (except empty ones, so that they are supplied by the defaulting mechanims) will fail.
@@ -55,9 +55,6 @@ spec:
shoot:
name: crazy-botany
seedTemplate:
- metadata:
- labels:
- seed.gardener.cloud/gardenlet: local
spec:
dns:
ingressDomain: ""
@@ -69,8 +66,6 @@ spec:
region: ""
```
-Note the `seed.gardener.cloud/gardenlet: local` label above. It stands for the label that is used in a `seedSelector` field of a `gardenlet` that takes care of multiple seeds. This label can be omitted if the `seedSelector` field selects all seeds. If there is no gardenlet running outside the cluster and selecting the seed, it won't be reconciled and no shoots will be scheduled on it.
-
For an example that uses non-default configuration, see [55-managed-seed-seedtemplate.yaml](../../example/55-managedseed-seedtemplate.yaml)
## Migrating from the `use-as-seed` Annotation to `ManagedSeeds`
@@ -97,6 +92,6 @@ Option | Description
`apiServer.autoscaler.maxReplicas` | Controls the maximum number of `kube-apiserver` replicas for the shooted seed cluster.
`apiServer.replicas` | Controls how many `kube-apiserver` replicas the shooted seed cluster gets by default.
-For backward compatibility, it is still possible to specify these options via the `shoot.gardener.cloud/managed-seed-api-server` annotation, using exactly the same syntax as before.
+For backward compatibility, it is still possible to specify these options via the `shoot.gardener.cloud/managed-seed-api-server` annotation, using exactly the same syntax as before.
If you use any of these fields in any or your `use-as-seed` annotations, instead of removing the annotation completely as mentioned above, simply rename it to `managed-seed-api-server`, keeping these fields, and removing everything else.
diff --git a/docs/usage/shooted_seed.md b/docs/usage/shooted_seed.md
index 0100c35643c..0a38a2d9d12 100644
--- a/docs/usage/shooted_seed.md
+++ b/docs/usage/shooted_seed.md
@@ -56,7 +56,7 @@ It is strongly recommended to use such resources directly to register shoots as
Option | Description
--- | ---
`true` | Registers the cluster as a seed cluster. Automatically deploys the gardenlet into the shoot cluster, unless specified otherwise (e.g. setting the `no-gardenlet` flag).
-`no-gardenlet` | Prevents the automatic deployment of the gardenlet into the shoot cluster. Instead, the `Seed` object will be created with the assumption that another gardenlet will be responsible for managing it (according to its `seedSelector` configuration).
+`no-gardenlet` | Prevents the automatic deployment of the gardenlet into the shoot cluster. Instead, the `Seed` object will be created with the assumption that another gardenlet will be responsible for managing it (according to its `seedConfig` configuration).
`disable-capacity-reservation` | Set `spec.settings.excessCapacity.enabled` in the seed cluster to false (see [/example/50-seed.yaml](../../example/50-seed.yaml)).
`invisible` | Set `spec.settings.scheduling.visible` in the seed cluster to false (see [/example/50-seed.yaml](../../example/50-seed.yaml))
`visible` | Set `spec.settings.scheduling.visible` in the seed cluster to true (see [/example/50-seed.yaml](../../example/50-seed.yaml)) (**default**).
diff --git a/example/55-managedseed-seedtemplate.yaml b/example/55-managedseed-seedtemplate.yaml
index 6c1ed1b0088..3f8ed7c1834 100644
--- a/example/55-managedseed-seedtemplate.yaml
+++ b/example/55-managedseed-seedtemplate.yaml
@@ -8,10 +8,7 @@ spec:
name: crazy-botany
# seedTemplate is a template for a Seed object, that should be used to register a given cluster as a Seed.
# When seedTemplate is specified, the ManagedSeed controller will not deploy a gardenlet into the cluster
- # and an existing gardenlet reconciling the new Seed is required.
+ # and an existing gardenlet reconciling the new Seed is required.
seedTemplate:
-# metadata:
-# labels:
-# seed.gardener.cloud/gardenlet: local # Label to use in seedSelector of the existing gardenlet
spec: # Seed spec
#
diff --git a/landscaper/pkg/gardenlet/apis/imports/validation/validation.go b/landscaper/pkg/gardenlet/apis/imports/validation/validation.go
index 191fdfdd34c..2afe95327ef 100644
--- a/landscaper/pkg/gardenlet/apis/imports/validation/validation.go
+++ b/landscaper/pkg/gardenlet/apis/imports/validation/validation.go
@@ -71,10 +71,6 @@ func ValidateLandscaperImports(imports *imports.Imports) field.ErrorList {
func validateGardenletConfiguration(gardenletConfig *gardenletconfig.GardenletConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
- if gardenletConfig.SeedSelector != nil {
- allErrs = append(allErrs, field.Forbidden(fldPath.Child("seedSelector"), "seed selector is forbidden, provide a seedConfig instead."))
- }
-
if gardenletConfig.SeedConfig == nil {
return append(allErrs, field.Required(fldPath.Child("seedConfig"), "the seed configuration has to be provided. This is used to automatically register the seed."))
}
diff --git a/landscaper/pkg/gardenlet/apis/imports/validation/validation_test.go b/landscaper/pkg/gardenlet/apis/imports/validation/validation_test.go
index 6a12aa645e2..3a5b3779794 100644
--- a/landscaper/pkg/gardenlet/apis/imports/validation/validation_test.go
+++ b/landscaper/pkg/gardenlet/apis/imports/validation/validation_test.go
@@ -115,31 +115,6 @@ var _ = Describe("ValidateLandscaperImports", func() {
})
Context("validate Gardenlet configuration", func() {
- It("should validate that the Seed selector is not set", func() {
- // only pick one required Gardenlet component configuration to show that the configuration is indeed verified
- // neither seedSelector nor seedConfig are provided. One of them has to be set to
- // pass the validation of the GardenletConfiguration
- gardenletConfiguration.SeedSelector = &metav1.LabelSelector{
- MatchLabels: map[string]string{
- "x": "y",
- },
- }
- gardenletConfiguration.SeedConfig = nil
- landscaperGardenletImport.ComponentConfiguration = &gardenletConfiguration
-
- errorList := ValidateLandscaperImports(landscaperGardenletImport)
- Expect(errorList).To(ConsistOf(
- PointTo(MatchFields(IgnoreExtras, Fields{
- "Type": Equal(field.ErrorTypeForbidden),
- "Field": Equal("componentConfiguration.seedSelector"),
- })),
- PointTo(MatchFields(IgnoreExtras, Fields{
- "Type": Equal(field.ErrorTypeRequired),
- "Field": Equal("componentConfiguration.seedConfig"),
- })),
- ))
- })
-
It("should validate that the kubeconfig in the GardenClientConnection is not set", func() {
gardenletConfiguration.GardenClientConnection = &gardenletconfigv1alpha1.GardenClientConnection{
ClientConnectionConfiguration: componentbaseconfigv1alpha1.ClientConnectionConfiguration{
diff --git a/pkg/apis/seedmanagement/validation/managedseed.go b/pkg/apis/seedmanagement/validation/managedseed.go
index 8b225de3109..3433dbf5f23 100644
--- a/pkg/apis/seedmanagement/validation/managedseed.go
+++ b/pkg/apis/seedmanagement/validation/managedseed.go
@@ -293,11 +293,6 @@ func validateImage(image *seedmanagement.Image, fldPath *field.Path) field.Error
func validateGardenletConfiguration(gardenletConfig *config.GardenletConfiguration, bootstrap seedmanagement.Bootstrap, mergeWithParent bool, fldPath *field.Path, inTemplate bool) field.ErrorList {
allErrs := field.ErrorList{}
- // Ensure seed selector is not specified
- if gardenletConfig.SeedSelector != nil {
- allErrs = append(allErrs, field.Forbidden(fldPath.Child("seedSelector"), "seed selector is forbidden"))
- }
-
// Ensure name is not specified since it will be set by the controller
if gardenletConfig.SeedConfig != nil && gardenletConfig.SeedConfig.Name != "" {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("seedConfig", "metadata", "name"), "seed name is forbidden"))
diff --git a/pkg/client/kubernetes/clientmap/builder/deleg_builder.go b/pkg/client/kubernetes/clientmap/builder/deleg_builder.go
index 625ccfc3241..c864c990825 100644
--- a/pkg/client/kubernetes/clientmap/builder/deleg_builder.go
+++ b/pkg/client/kubernetes/clientmap/builder/deleg_builder.go
@@ -27,7 +27,7 @@ import (
// based on the type of the key (e.g. a call with keys.ForShoot() will be delegated to the ShootClientMap).
type DelegatingClientMapBuilder struct {
gardenClientMapFunc func(logger logrus.FieldLogger) (clientmap.ClientMap, error)
- seedClientMapFunc func(gardenClients clientmap.ClientMap, logger logrus.FieldLogger) (clientmap.ClientMap, error)
+ seedClientMapFunc func(logger logrus.FieldLogger) (clientmap.ClientMap, error)
shootClientMapFunc func(gardenClients, seedClients clientmap.ClientMap, logger logrus.FieldLogger) (clientmap.ClientMap, error)
plantClientMapFunc func(gardenClients clientmap.ClientMap, logger logrus.FieldLogger) (clientmap.ClientMap, error)
@@ -69,7 +69,7 @@ func (b *DelegatingClientMapBuilder) WithGardenClientMapBuilder(builder *GardenC
// WithSeedClientMap sets the ClientMap that should be used for Seed clients.
func (b *DelegatingClientMapBuilder) WithSeedClientMap(clientMap clientmap.ClientMap) *DelegatingClientMapBuilder {
- b.seedClientMapFunc = func(_ clientmap.ClientMap, _ logrus.FieldLogger) (clientmap.ClientMap, error) {
+ b.seedClientMapFunc = func(_ logrus.FieldLogger) (clientmap.ClientMap, error) {
return clientMap, nil
}
return b
@@ -77,10 +77,9 @@ func (b *DelegatingClientMapBuilder) WithSeedClientMap(clientMap clientmap.Clien
// WithSeedClientMapBuilder sets a ClientMap builder that should be used to build a ClientMap for Seed clients.
func (b *DelegatingClientMapBuilder) WithSeedClientMapBuilder(builder *SeedClientMapBuilder) *DelegatingClientMapBuilder {
- b.seedClientMapFunc = func(gardenClients clientmap.ClientMap, logger logrus.FieldLogger) (clientmap.ClientMap, error) {
+ b.seedClientMapFunc = func(logger logrus.FieldLogger) (clientmap.ClientMap, error) {
return builder.
WithLogger(logger.WithField("ClientMap", "SeedClientMap")).
- WithGardenClientMap(gardenClients).
Build()
}
return b
@@ -139,7 +138,7 @@ func (b *DelegatingClientMapBuilder) Build() (clientmap.ClientMap, error) {
var seedClients, shootClients, plantClients clientmap.ClientMap
if b.seedClientMapFunc != nil {
- seedClients, err = b.seedClientMapFunc(gardenClients, b.logger)
+ seedClients, err = b.seedClientMapFunc(b.logger)
if err != nil {
return nil, fmt.Errorf("failed to construct seed ClientMap: %w", err)
}
diff --git a/pkg/client/kubernetes/clientmap/builder/deleg_builder_test.go b/pkg/client/kubernetes/clientmap/builder/deleg_builder_test.go
index e8eb83cc7d9..cef647deeb3 100644
--- a/pkg/client/kubernetes/clientmap/builder/deleg_builder_test.go
+++ b/pkg/client/kubernetes/clientmap/builder/deleg_builder_test.go
@@ -73,7 +73,7 @@ var _ = Describe("DelegatingClientMapBuilder", func() {
Context("#seedClientMapFunc", func() {
It("should be set correctly by WithSeedClientMap", func() {
builder := NewDelegatingClientMapBuilder().WithSeedClientMap(fakeSeedClientMap)
- Expect(builder.seedClientMapFunc(nil, nil)).To(BeIdenticalTo(fakeSeedClientMap))
+ Expect(builder.seedClientMapFunc(nil)).To(BeIdenticalTo(fakeSeedClientMap))
})
It("should be set correctly by WithSeedClientMapBuilder", func() {
@@ -154,7 +154,7 @@ var _ = Describe("DelegatingClientMapBuilder", func() {
builder := NewDelegatingClientMapBuilder().
WithLogger(fakeLogger).
WithGardenClientMap(fakeGardenClientMap)
- builder.seedClientMapFunc = func(clientmap.ClientMap, logrus.FieldLogger) (clientmap.ClientMap, error) {
+ builder.seedClientMapFunc = func(logrus.FieldLogger) (clientmap.ClientMap, error) {
return nil, fakeErr
}
clientMap, err := builder.Build()
diff --git a/pkg/client/kubernetes/clientmap/builder/seed_builder.go b/pkg/client/kubernetes/clientmap/builder/seed_builder.go
index 0b7dd1e8a0c..b9965c8f78b 100644
--- a/pkg/client/kubernetes/clientmap/builder/seed_builder.go
+++ b/pkg/client/kubernetes/clientmap/builder/seed_builder.go
@@ -15,23 +15,18 @@
package builder
import (
- "context"
"fmt"
"github.com/sirupsen/logrus"
baseconfig "k8s.io/component-base/config"
- "github.com/gardener/gardener/pkg/client/kubernetes"
"github.com/gardener/gardener/pkg/client/kubernetes/clientmap"
"github.com/gardener/gardener/pkg/client/kubernetes/clientmap/internal"
- "github.com/gardener/gardener/pkg/client/kubernetes/clientmap/keys"
)
// SeedClientMapBuilder can build a ClientMap which can be used to construct a ClientMap for requesting and storing
// clients for Seed clusters.
type SeedClientMapBuilder struct {
- gardenClientFunc func(ctx context.Context) (kubernetes.Interface, error)
- inCluster bool
clientConnectionConfig *baseconfig.ClientConnectionConfiguration
logger logrus.FieldLogger
@@ -48,29 +43,6 @@ func (b *SeedClientMapBuilder) WithLogger(logger logrus.FieldLogger) *SeedClient
return b
}
-// WithGardenClientMap sets the ClientMap that should be used to retrieve Garden clients.
-func (b *SeedClientMapBuilder) WithGardenClientMap(clientMap clientmap.ClientMap) *SeedClientMapBuilder {
- b.gardenClientFunc = func(ctx context.Context) (kubernetes.Interface, error) {
- return clientMap.GetClient(ctx, keys.ForGarden())
- }
- return b
-}
-
-// WithGardenClientSet sets the ClientSet that should be used as the Garden client.
-func (b *SeedClientMapBuilder) WithGardenClientSet(clientSet kubernetes.Interface) *SeedClientMapBuilder {
- b.gardenClientFunc = func(ctx context.Context) (kubernetes.Interface, error) {
- return clientSet, nil
- }
- return b
-}
-
-// WithInCluster sets the inCluster attribute of the builder. If true, the created ClientSets will use in-cluster communication
-// (using the provided ClientConnectionConfig.Kubeconfig or fallback to mounted ServiceAccount if unset).
-func (b *SeedClientMapBuilder) WithInCluster(inCluster bool) *SeedClientMapBuilder {
- b.inCluster = inCluster
- return b
-}
-
// WithClientConnectionConfig sets the ClientConnectionConfiguration that should be used by ClientSets created by this ClientMap.
func (b *SeedClientMapBuilder) WithClientConnectionConfig(cfg *baseconfig.ClientConnectionConfiguration) *SeedClientMapBuilder {
b.clientConnectionConfig = cfg
@@ -82,16 +54,11 @@ func (b *SeedClientMapBuilder) Build() (clientmap.ClientMap, error) {
if b.logger == nil {
return nil, fmt.Errorf("logger is required but not set")
}
- if b.gardenClientFunc == nil {
- return nil, fmt.Errorf("garden client is required but not set")
- }
if b.clientConnectionConfig == nil {
return nil, fmt.Errorf("clientConnectionConfig is required but not set")
}
return internal.NewSeedClientMap(&internal.SeedClientSetFactory{
- GetGardenClient: b.gardenClientFunc,
- InCluster: b.inCluster,
ClientConnectionConfig: *b.clientConnectionConfig,
}, b.logger), nil
}
diff --git a/pkg/client/kubernetes/clientmap/builder/seed_builder_test.go b/pkg/client/kubernetes/clientmap/builder/seed_builder_test.go
index 2559c7e59f0..49bf8174514 100644
--- a/pkg/client/kubernetes/clientmap/builder/seed_builder_test.go
+++ b/pkg/client/kubernetes/clientmap/builder/seed_builder_test.go
@@ -15,11 +15,6 @@
package builder
import (
- "context"
-
- fakeclientmap "github.com/gardener/gardener/pkg/client/kubernetes/clientmap/fake"
- "github.com/gardener/gardener/pkg/client/kubernetes/clientmap/keys"
- fakeclientset "github.com/gardener/gardener/pkg/client/kubernetes/fake"
"github.com/gardener/gardener/pkg/logger"
. "github.com/onsi/ginkgo"
@@ -29,23 +24,14 @@ import (
)
var _ = Describe("SeedClientMapBuilder", func() {
-
var (
- ctx context.Context
-
- fakeLogger logrus.FieldLogger
- fakeGardenClientMap *fakeclientmap.ClientMap
- fakeGardenClientSet *fakeclientset.ClientSet
+ fakeLogger logrus.FieldLogger
clientConnectionConfig *baseconfig.ClientConnectionConfiguration
)
BeforeEach(func() {
- ctx = context.TODO()
-
fakeLogger = logger.NewNopLogger()
- fakeGardenClientSet = fakeclientset.NewClientSet()
- fakeGardenClientMap = fakeclientmap.NewClientMapBuilder().WithClientSetForKey(keys.ForGarden(), fakeGardenClientSet).Build()
clientConnectionConfig = &baseconfig.ClientConnectionConfiguration{}
})
@@ -57,25 +43,6 @@ var _ = Describe("SeedClientMapBuilder", func() {
})
})
- Context("#gardenClientFunc", func() {
- It("should be correctly set by WithGardenClientSet", func() {
- builder := NewSeedClientMapBuilder().WithGardenClientSet(fakeGardenClientSet)
- Expect(builder.gardenClientFunc(ctx)).To(BeEquivalentTo(fakeGardenClientSet))
- })
-
- It("should be correctly set by WithGardenClientMap", func() {
- builder := NewSeedClientMapBuilder().WithGardenClientMap(fakeGardenClientMap)
- Expect(builder.gardenClientFunc(ctx)).To(BeEquivalentTo(fakeGardenClientSet))
- })
- })
-
- Context("#inCluster", func() {
- It("should be correctly set by WithInCluster", func() {
- builder := NewSeedClientMapBuilder().WithInCluster(true)
- Expect(builder.inCluster).To(BeTrue())
- })
- })
-
Context("#clientConnectionConfig", func() {
It("should be correctly set by WithClientConnectionConfig", func() {
builder := NewSeedClientMapBuilder().WithClientConnectionConfig(clientConnectionConfig)
@@ -90,14 +57,8 @@ var _ = Describe("SeedClientMapBuilder", func() {
Expect(clientMap).To(BeNil())
})
- It("should fail if garden ClientMap was not set", func() {
- clientMap, err := NewSeedClientMapBuilder().WithLogger(fakeLogger).Build()
- Expect(err).To(MatchError("garden client is required but not set"))
- Expect(clientMap).To(BeNil())
- })
-
It("should fail if clientConnectionConfig was not set", func() {
- clientMap, err := NewSeedClientMapBuilder().WithLogger(fakeLogger).WithGardenClientSet(fakeGardenClientSet).Build()
+ clientMap, err := NewSeedClientMapBuilder().WithLogger(fakeLogger).Build()
Expect(err).To(MatchError("clientConnectionConfig is required but not set"))
Expect(clientMap).To(BeNil())
})
@@ -105,7 +66,6 @@ var _ = Describe("SeedClientMapBuilder", func() {
It("should succeed to build ClientMap", func() {
clientSet, err := NewSeedClientMapBuilder().
WithLogger(fakeLogger).
- WithGardenClientMap(fakeGardenClientMap).
WithClientConnectionConfig(clientConnectionConfig).
Build()
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/client/kubernetes/clientmap/internal/seed_clientmap.go b/pkg/client/kubernetes/clientmap/internal/seed_clientmap.go
index 6f720a7e479..793eaf5c475 100644
--- a/pkg/client/kubernetes/clientmap/internal/seed_clientmap.go
+++ b/pkg/client/kubernetes/clientmap/internal/seed_clientmap.go
@@ -19,14 +19,11 @@ import (
"fmt"
"github.com/sirupsen/logrus"
- corev1 "k8s.io/api/core/v1"
baseconfig "k8s.io/component-base/config"
"sigs.k8s.io/controller-runtime/pkg/client"
- gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1"
"github.com/gardener/gardener/pkg/client/kubernetes"
"github.com/gardener/gardener/pkg/client/kubernetes/clientmap"
- "github.com/gardener/gardener/pkg/utils"
)
// seedClientMap is a ClientMap for requesting and storing clients for Seed clusters.
@@ -43,92 +40,34 @@ func NewSeedClientMap(factory *SeedClientSetFactory, logger logrus.FieldLogger)
// SeedClientSetFactory is a ClientSetFactory that can produce new ClientSets to Seed clusters.
type SeedClientSetFactory struct {
- // GetGardenClient is a func that will be used to get a client to the garden cluster to retrieve the Seed's
- // kubeconfig secret (if InCluster=false).
- GetGardenClient func(ctx context.Context) (kubernetes.Interface, error)
- // If InCluster is set to true, the created ClientSets will use in-cluster communication
- // (using ClientConnectionConfig.Kubeconfig or fallback to mounted ServiceAccount if unset).
- InCluster bool
// ClientConnectionConfiguration is the configuration that will be used by created ClientSets.
ClientConnectionConfig baseconfig.ClientConnectionConfiguration
}
-// CalculateClientSetHash returns "" if the gardenlet uses in-cluster communication. Otherwise, it calculates a SHA256
-// hash of the kubeconfig in the seed secret.
+// CalculateClientSetHash always returns "" and nil.
func (f *SeedClientSetFactory) CalculateClientSetHash(ctx context.Context, k clientmap.ClientSetKey) (string, error) {
- key, ok := k.(SeedClientSetKey)
- if !ok {
- return "", fmt.Errorf("unsupported ClientSetKey: expected %T got %T", SeedClientSetKey(""), k)
- }
-
- if f.InCluster {
- return "", nil
- }
-
- secretRef, gardenClient, err := f.getSeedSecretRef(ctx, key)
- if err != nil {
- return "", err
- }
-
- kubeconfigSecret := &corev1.Secret{}
- if err := gardenClient.Client().Get(ctx, client.ObjectKey{Namespace: secretRef.Namespace, Name: secretRef.Name}, kubeconfigSecret); err != nil {
- return "", err
- }
-
- return utils.ComputeSHA256Hex(kubeconfigSecret.Data[kubernetes.KubeConfig]), nil
+ return "", nil
}
// NewClientSet creates a new ClientSet for a Seed cluster.
func (f *SeedClientSetFactory) NewClientSet(ctx context.Context, k clientmap.ClientSetKey) (kubernetes.Interface, error) {
- key, ok := k.(SeedClientSetKey)
+ _, ok := k.(SeedClientSetKey)
if !ok {
- return nil, fmt.Errorf("unsupported ClientSetKey: expected %T got %T", SeedClientSetKey(""), k)
- }
-
- if f.InCluster {
- return NewClientFromFile(
- "",
- f.ClientConnectionConfig.Kubeconfig,
- kubernetes.WithClientConnectionOptions(f.ClientConnectionConfig),
- kubernetes.WithClientOptions(
- client.Options{
- Scheme: kubernetes.SeedScheme,
- },
- ),
- )
+ return nil, fmt.Errorf("unsupported ClientSetKey: expected %T, but got %T", SeedClientSetKey(""), k)
}
- secretRef, gardenClient, err := f.getSeedSecretRef(ctx, key)
- if err != nil {
- return nil, err
- }
-
- return NewClientFromSecret(ctx, gardenClient.Client(), secretRef.Namespace, secretRef.Name,
+ return NewClientFromFile(
+ "",
+ f.ClientConnectionConfig.Kubeconfig,
kubernetes.WithClientConnectionOptions(f.ClientConnectionConfig),
- kubernetes.WithClientOptions(client.Options{
- Scheme: kubernetes.SeedScheme,
- }),
+ kubernetes.WithClientOptions(
+ client.Options{
+ Scheme: kubernetes.SeedScheme,
+ },
+ ),
)
}
-func (f *SeedClientSetFactory) getSeedSecretRef(ctx context.Context, key SeedClientSetKey) (*corev1.SecretReference, kubernetes.Interface, error) {
- gardenClient, err := f.GetGardenClient(ctx)
- if err != nil {
- return nil, nil, fmt.Errorf("failed to get garden client: %w", err)
- }
-
- seed := &gardencorev1beta1.Seed{}
- if err := gardenClient.Client().Get(ctx, client.ObjectKey{Name: key.Key()}, seed); err != nil {
- return nil, nil, fmt.Errorf("failed to get Seed object %q: %w", key.Key(), err)
- }
-
- if seed.Spec.SecretRef == nil {
- return nil, nil, fmt.Errorf("seed %q does not have a secretRef", key.Key())
- }
-
- return seed.Spec.SecretRef, gardenClient, nil
-}
-
// SeedClientSetKey is a ClientSetKey for a Seed cluster.
type SeedClientSetKey string
diff --git a/pkg/client/kubernetes/clientmap/internal/seed_clientmap_test.go b/pkg/client/kubernetes/clientmap/internal/seed_clientmap_test.go
index ef914eace67..001bcbe4dda 100644
--- a/pkg/client/kubernetes/clientmap/internal/seed_clientmap_test.go
+++ b/pkg/client/kubernetes/clientmap/internal/seed_clientmap_test.go
@@ -26,13 +26,11 @@ import (
fakeclientset "github.com/gardener/gardener/pkg/client/kubernetes/fake"
. "github.com/gardener/gardener/pkg/client/kubernetes/test"
"github.com/gardener/gardener/pkg/logger"
- mockclient "github.com/gardener/gardener/pkg/mock/controller-runtime/client"
"github.com/golang/mock/gomock"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
- apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
baseconfig "k8s.io/component-base/config"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -40,10 +38,8 @@ import (
var _ = Describe("SeedClientMap", func() {
var (
- ctx context.Context
- ctrl *gomock.Controller
- c *mockclient.MockClient
- fakeGardenClient *fakeclientset.ClientSet
+ ctx context.Context
+ ctrl *gomock.Controller
cm clientmap.ClientMap
key clientmap.ClientSetKey
@@ -56,8 +52,6 @@ var _ = Describe("SeedClientMap", func() {
BeforeEach(func() {
ctx = context.TODO()
ctrl = gomock.NewController(GinkgoT())
- c = mockclient.NewMockClient(ctrl)
- fakeGardenClient = fakeclientset.NewClientSetBuilder().WithClient(c).Build()
seed = &gardencorev1beta1.Seed{
ObjectMeta: metav1.ObjectMeta{
@@ -81,9 +75,6 @@ var _ = Describe("SeedClientMap", func() {
Burst: 43,
}
factory = &internal.SeedClientSetFactory{
- GetGardenClient: func(ctx context.Context) (kubernetes.Interface, error) {
- return fakeGardenClient, nil
- },
ClientConnectionConfig: clientConnectionConfig,
}
cm = internal.NewSeedClientMap(factory, logger.NewNopLogger())
@@ -94,15 +85,7 @@ var _ = Describe("SeedClientMap", func() {
})
Context("#GetClient", func() {
- It("should fail if ClientSetKey type is unsupported", func() {
- key = fakeKey{}
- cs, err := cm.GetClient(ctx, key)
- Expect(cs).To(BeNil())
- Expect(err).To(MatchError(ContainSubstring("unsupported ClientSetKey")))
- })
-
- It("should fail if NewClientFromFile fails (in-cluster)", func() {
- factory.InCluster = true
+ It("should fail if NewClientFromSecret fails", func() {
fakeErr := fmt.Errorf("fake")
internal.NewClientFromFile = func(masterURL, kubeconfigPath string, fns ...kubernetes.ConfigFunc) (kubernetes.Interface, error) {
return nil, fakeErr
@@ -113,8 +96,7 @@ var _ = Describe("SeedClientMap", func() {
Expect(err).To(MatchError(fmt.Sprintf("error creating new ClientSet for key %q: fake", key.Key())))
})
- It("should correctly construct a new ClientSet (in-cluster)", func() {
- factory.InCluster = true
+ It("should correctly construct a new ClientSet", func() {
fakeCS := fakeclientset.NewClientSet()
internal.NewClientFromFile = func(masterURL, kubeconfigPath string, fns ...kubernetes.ConfigFunc) (kubernetes.Interface, error) {
Expect(masterURL).To(BeEmpty())
@@ -130,134 +112,13 @@ var _ = Describe("SeedClientMap", func() {
Expect(err).NotTo(HaveOccurred())
Expect(cs).To(BeIdenticalTo(fakeCS))
})
-
- It("should fail if GetGardenClient fails", func() {
- fakeErr := fmt.Errorf("fake")
- factory.GetGardenClient = func(ctx context.Context) (kubernetes.Interface, error) {
- return nil, fakeErr
- }
-
- cs, err := cm.GetClient(ctx, key)
- Expect(cs).To(BeNil())
- Expect(err).To(MatchError(ContainSubstring("failed to get garden client: fake")))
- })
-
- It("should fail if it cannot get Seed object", func() {
- c.EXPECT().Get(ctx, client.ObjectKey{Name: seed.Name}, gomock.AssignableToTypeOf(&gardencorev1beta1.Seed{})).
- Return(apierrors.NewNotFound(gardencorev1beta1.Resource("seed"), seed.Name))
-
- cs, err := cm.GetClient(ctx, key)
- Expect(cs).To(BeNil())
- Expect(err).To(MatchError(ContainSubstring("failed to get Seed object")))
- })
-
- It("should fail if Seed object does not have a secretRef", func() {
- seed.Spec.SecretRef = nil
- c.EXPECT().Get(ctx, client.ObjectKey{Name: seed.Name}, gomock.AssignableToTypeOf(&gardencorev1beta1.Seed{})).
- DoAndReturn(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
- seed.DeepCopyInto(obj.(*gardencorev1beta1.Seed))
- return nil
- })
-
- cs, err := cm.GetClient(ctx, key)
- Expect(cs).To(BeNil())
- Expect(err).To(MatchError(ContainSubstring("does not have a secretRef")))
- })
-
- It("should fail if NewClientFromSecret fails", func() {
- fakeErr := fmt.Errorf("fake")
- c.EXPECT().Get(ctx, client.ObjectKey{Name: seed.Name}, gomock.AssignableToTypeOf(&gardencorev1beta1.Seed{})).
- DoAndReturn(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
- seed.DeepCopyInto(obj.(*gardencorev1beta1.Seed))
- return nil
- })
- internal.NewClientFromSecret = func(ctx context.Context, c client.Client, namespace, secretName string, fns ...kubernetes.ConfigFunc) (kubernetes.Interface, error) {
- return nil, fakeErr
- }
-
- cs, err := cm.GetClient(ctx, key)
- Expect(cs).To(BeNil())
- Expect(err).To(MatchError(fmt.Sprintf("error creating new ClientSet for key %q: fake", key.Key())))
- })
-
- It("should correctly construct a new ClientSet", func() {
- fakeCS := fakeclientset.NewClientSet()
- c.EXPECT().Get(ctx, client.ObjectKey{Name: seed.Name}, gomock.AssignableToTypeOf(&gardencorev1beta1.Seed{})).
- DoAndReturn(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
- seed.DeepCopyInto(obj.(*gardencorev1beta1.Seed))
- return nil
- }).Times(2)
- c.EXPECT().Get(ctx, client.ObjectKey{Namespace: seed.Spec.SecretRef.Namespace, Name: seed.Spec.SecretRef.Name}, gomock.AssignableToTypeOf(&corev1.Secret{})).
- DoAndReturn(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
- return nil
- })
- internal.NewClientFromSecret = func(ctx context.Context, c client.Client, namespace, secretName string, fns ...kubernetes.ConfigFunc) (kubernetes.Interface, error) {
- Expect(c).To(BeIdenticalTo(fakeGardenClient.Client()))
- Expect(namespace).To(Equal(seed.Spec.SecretRef.Namespace))
- Expect(secretName).To(Equal(seed.Spec.SecretRef.Name))
- Expect(fns).To(ConsistOfConfigFuncs(
- kubernetes.WithClientConnectionOptions(clientConnectionConfig),
- kubernetes.WithClientOptions(client.Options{Scheme: kubernetes.SeedScheme}),
- ))
- return fakeCS, nil
- }
-
- cs, err := cm.GetClient(ctx, key)
- Expect(err).NotTo(HaveOccurred())
- Expect(cs).To(BeIdenticalTo(fakeCS))
- })
})
Context("#CalculateClientSetHash", func() {
- It("should fail if ClientSetKey type is unsupported", func() {
+ It("should always return the same identifier", func() {
key = fakeKey{}
hash, err := factory.CalculateClientSetHash(ctx, key)
Expect(hash).To(BeEmpty())
- Expect(err).To(MatchError(ContainSubstring("unsupported ClientSetKey")))
- })
-
- It("should fail if getSeedSecretRef fails", func() {
- fakeErr := fmt.Errorf("fake")
- factory.GetGardenClient = func(ctx context.Context) (kubernetes.Interface, error) {
- return nil, fakeErr
- }
-
- hash, err := factory.CalculateClientSetHash(ctx, key)
- Expect(hash).To(BeEmpty())
- Expect(err).To(MatchError(ContainSubstring("failed to get garden client: fake")))
- })
-
- It("should fail if Get Seed Secret fails", func() {
- fakeErr := fmt.Errorf("fake")
- c.EXPECT().Get(ctx, client.ObjectKey{Name: seed.Name}, gomock.AssignableToTypeOf(&gardencorev1beta1.Seed{})).
- DoAndReturn(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
- seed.DeepCopyInto(obj.(*gardencorev1beta1.Seed))
- return nil
- })
- c.EXPECT().Get(ctx, client.ObjectKey{Namespace: seed.Spec.SecretRef.Namespace, Name: seed.Spec.SecretRef.Name}, gomock.AssignableToTypeOf(&corev1.Secret{})).
- DoAndReturn(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
- return fakeErr
- })
-
- hash, err := factory.CalculateClientSetHash(ctx, key)
- Expect(hash).To(BeEmpty())
- Expect(err).To(MatchError("fake"))
- })
-
- It("should correctly calculate hash", func() {
- c.EXPECT().Get(ctx, client.ObjectKey{Name: seed.Name}, gomock.AssignableToTypeOf(&gardencorev1beta1.Seed{})).
- DoAndReturn(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
- seed.DeepCopyInto(obj.(*gardencorev1beta1.Seed))
- return nil
- })
- c.EXPECT().Get(ctx, client.ObjectKey{Namespace: seed.Spec.SecretRef.Namespace, Name: seed.Spec.SecretRef.Name}, gomock.AssignableToTypeOf(&corev1.Secret{})).
- DoAndReturn(func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
- (&corev1.Secret{}).DeepCopyInto(obj.(*corev1.Secret))
- return nil
- })
-
- hash, err := factory.CalculateClientSetHash(ctx, key)
- Expect(hash).To(Equal("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"))
Expect(err).NotTo(HaveOccurred())
})
})
diff --git a/pkg/controllerutils/seedfilter.go b/pkg/controllerutils/seedfilter.go
index 8c92cafe431..5d08790c20f 100644
--- a/pkg/controllerutils/seedfilter.go
+++ b/pkg/controllerutils/seedfilter.go
@@ -21,41 +21,27 @@ import (
gardencorev1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
operationsv1alpha1 "github.com/gardener/gardener/pkg/apis/operations/v1alpha1"
seedmanagementv1alpha1 "github.com/gardener/gardener/pkg/apis/seedmanagement/v1alpha1"
- gardencorelisters "github.com/gardener/gardener/pkg/client/core/listers/core/v1beta1"
"github.com/gardener/gardener/pkg/gardenlet/apis/config"
confighelper "github.com/gardener/gardener/pkg/gardenlet/apis/config/helper"
kutil "github.com/gardener/gardener/pkg/utils/kubernetes"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/labels"
"sigs.k8s.io/controller-runtime/pkg/client"
)
-// LabelsMatchFor checks whether the given label selector matches for the given set of labels.
-func LabelsMatchFor(l map[string]string, labelSelector *metav1.LabelSelector) bool {
- selector, err := metav1.LabelSelectorAsSelector(labelSelector)
- if err != nil {
- return false
- }
- return selector.Matches(labels.Set(l))
-}
-
-// SeedFilterFunc returns a filtering func for the seeds and the given label selector.
-func SeedFilterFunc(seedName string, labelSelector *metav1.LabelSelector) func(obj interface{}) bool {
+// SeedFilterFunc returns a filtering func for the seeds.
+func SeedFilterFunc(seedName string) func(obj interface{}) bool {
return func(obj interface{}) bool {
seed, ok := obj.(*gardencorev1beta1.Seed)
if !ok {
return false
}
- if len(seedName) > 0 {
- return seed.Name == seedName
- }
- return LabelsMatchFor(seed.Labels, labelSelector)
+
+ return seed.Name == seedName
}
}
-// ShootFilterFunc returns a filtering func for the seeds and the given label selector.
-func ShootFilterFunc(seedName string, seedLister gardencorelisters.SeedLister, labelSelector *metav1.LabelSelector) func(obj interface{}) bool {
+// ShootFilterFunc returns a filtering func for the seeds.
+func ShootFilterFunc(seedName string) func(obj interface{}) bool {
return func(obj interface{}) bool {
shoot, ok := obj.(*gardencorev1beta1.Shoot)
if !ok {
@@ -64,67 +50,34 @@ func ShootFilterFunc(seedName string, seedLister gardencorelisters.SeedLister, l
if shoot.Spec.SeedName == nil {
return false
}
- if len(seedName) > 0 {
- if shoot.Status.SeedName == nil || *shoot.Spec.SeedName == *shoot.Status.SeedName {
- return *shoot.Spec.SeedName == seedName
- }
- return *shoot.Status.SeedName == seedName
- }
+
if shoot.Status.SeedName == nil || *shoot.Spec.SeedName == *shoot.Status.SeedName {
- return SeedLabelsMatch(seedLister, *shoot.Spec.SeedName, labelSelector)
+ return *shoot.Spec.SeedName == seedName
}
- return SeedLabelsMatch(seedLister, *shoot.Status.SeedName, labelSelector)
- }
-}
-
-// ShootIsManagedByThisGardenlet checks if the given shoot is managed by this gardenlet by comparing it with the seed name from the GardenletConfiguration
-// or by checking whether the seed labels match the seed selector from the GardenletConfiguration.
-func ShootIsManagedByThisGardenlet(shoot *gardencorev1beta1.Shoot, gc *config.GardenletConfiguration, seedLister gardencorelisters.SeedLister) bool {
- seedName := confighelper.SeedNameFromSeedConfig(gc.SeedConfig)
- if len(seedName) > 0 {
- return *shoot.Spec.SeedName == seedName
- }
- return SeedLabelsMatch(seedLister, *shoot.Spec.SeedName, gc.SeedSelector)
-}
-// SeedLabelsMatch fetches the given seed via a lister by its name and then checks whether the given label selector matches
-// the seed labels.
-func SeedLabelsMatch(seedLister gardencorelisters.SeedLister, seedName string, labelSelector *metav1.LabelSelector) bool {
- seed, err := seedLister.Get(seedName)
- if err != nil {
- return false
+ return *shoot.Status.SeedName == seedName
}
-
- return LabelsMatchFor(seed.Labels, labelSelector)
}
-// seedLabelsMatchWithClient fetches the given seed by its name from the client and then checks whether the given
-// label selector matches the seed labels.
-func seedLabelsMatchWithClient(ctx context.Context, c client.Reader, seedName string, labelSelector *metav1.LabelSelector) bool {
- seed := &gardencorev1beta1.Seed{}
- if err := c.Get(ctx, client.ObjectKey{Name: seedName}, seed); err != nil {
- return false
- }
-
- return LabelsMatchFor(seed.Labels, labelSelector)
+// ShootIsManagedByThisGardenlet checks if the given shoot is managed by this gardenlet by comparing it with the seed name from the GardenletConfiguration.
+func ShootIsManagedByThisGardenlet(shoot *gardencorev1beta1.Shoot, gc *config.GardenletConfiguration) bool {
+ return *shoot.Spec.SeedName == confighelper.SeedNameFromSeedConfig(gc.SeedConfig)
}
-// ControllerInstallationFilterFunc returns a filtering func for the seeds and the given label selector.
-func ControllerInstallationFilterFunc(seedName string, seedLister gardencorelisters.SeedLister, labelSelector *metav1.LabelSelector) func(obj interface{}) bool {
+// ControllerInstallationFilterFunc returns a filtering func for the seeds.
+func ControllerInstallationFilterFunc(seedName string) func(obj interface{}) bool {
return func(obj interface{}) bool {
controllerInstallation, ok := obj.(*gardencorev1beta1.ControllerInstallation)
if !ok {
return false
}
- if len(seedName) > 0 {
- return controllerInstallation.Spec.SeedRef.Name == seedName
- }
- return SeedLabelsMatch(seedLister, controllerInstallation.Spec.SeedRef.Name, labelSelector)
+
+ return controllerInstallation.Spec.SeedRef.Name == seedName
}
}
-// BackupBucketFilterFunc returns a filtering func for the seeds and the given label selector.
-func BackupBucketFilterFunc(ctx context.Context, c client.Reader, seedName string, labelSelector *metav1.LabelSelector) func(obj interface{}) bool {
+// BackupBucketFilterFunc returns a filtering func for the seeds.
+func BackupBucketFilterFunc(seedName string) func(obj interface{}) bool {
return func(obj interface{}) bool {
backupBucket, ok := obj.(*gardencorev1beta1.BackupBucket)
if !ok {
@@ -133,15 +86,13 @@ func BackupBucketFilterFunc(ctx context.Context, c client.Reader, seedName strin
if backupBucket.Spec.SeedName == nil {
return false
}
- if len(seedName) > 0 {
- return *backupBucket.Spec.SeedName == seedName
- }
- return seedLabelsMatchWithClient(ctx, c, *backupBucket.Spec.SeedName, labelSelector)
+
+ return *backupBucket.Spec.SeedName == seedName
}
}
-// BackupEntryFilterFunc returns a filtering func for the seeds and the given label selector.
-func BackupEntryFilterFunc(ctx context.Context, c client.Reader, seedName string, labelSelector *metav1.LabelSelector) func(obj interface{}) bool {
+// BackupEntryFilterFunc returns a filtering func for the seeds.
+func BackupEntryFilterFunc(seedName string) func(obj interface{}) bool {
return func(obj interface{}) bool {
backupEntry, ok := obj.(*gardencorev1beta1.BackupEntry)
if !ok {
@@ -150,31 +101,24 @@ func BackupEntryFilterFunc(ctx context.Context, c client.Reader, seedName string
if backupEntry.Spec.SeedName == nil {
return false
}
- if len(seedName) > 0 {
- if backupEntry.Status.SeedName == nil || *backupEntry.Spec.SeedName == *backupEntry.Status.SeedName {
- return *backupEntry.Spec.SeedName == seedName
- }
- return *backupEntry.Status.SeedName == seedName
- }
+
if backupEntry.Status.SeedName == nil || *backupEntry.Spec.SeedName == *backupEntry.Status.SeedName {
- return seedLabelsMatchWithClient(ctx, c, *backupEntry.Spec.SeedName, labelSelector)
+ return *backupEntry.Spec.SeedName == seedName
}
- return seedLabelsMatchWithClient(ctx, c, *backupEntry.Status.SeedName, labelSelector)
+
+ return *backupEntry.Status.SeedName == seedName
}
}
-// BackupEntryIsManagedByThisGardenlet checks if the given BackupEntry is managed by this gardenlet by comparing it with the seed name from the GardenletConfiguration
-// or by checking whether the seed labels match the seed selector from the GardenletConfiguration.
-func BackupEntryIsManagedByThisGardenlet(ctx context.Context, c client.Reader, backupEntry *gardencorev1beta1.BackupEntry, gc *config.GardenletConfiguration) bool {
+// BackupEntryIsManagedByThisGardenlet checks if the given BackupEntry is managed by this gardenlet by comparing it with the seed name from the GardenletConfiguration.
+func BackupEntryIsManagedByThisGardenlet(backupEntry *gardencorev1beta1.BackupEntry, gc *config.GardenletConfiguration) bool {
seedName := confighelper.SeedNameFromSeedConfig(gc.SeedConfig)
- if len(seedName) > 0 {
- return backupEntry.Spec.SeedName != nil && *backupEntry.Spec.SeedName == seedName
- }
- return seedLabelsMatchWithClient(ctx, c, *backupEntry.Spec.SeedName, gc.SeedSelector)
+
+ return backupEntry.Spec.SeedName != nil && *backupEntry.Spec.SeedName == seedName
}
-// BastionFilterFunc returns a filtering func for the seeds and the given label selector.
-func BastionFilterFunc(ctx context.Context, c client.Reader, seedName string, labelSelector *metav1.LabelSelector) func(obj interface{}) bool {
+// BastionFilterFunc returns a filtering func for the seeds.
+func BastionFilterFunc(seedName string) func(obj interface{}) bool {
return func(obj interface{}) bool {
bastion, ok := obj.(*operationsv1alpha1.Bastion)
if !ok {
@@ -183,25 +127,20 @@ func BastionFilterFunc(ctx context.Context, c client.Reader, seedName string, la
if bastion.Spec.SeedName == nil {
return false
}
- if len(seedName) > 0 {
- return *bastion.Spec.SeedName == seedName
- }
- return seedLabelsMatchWithClient(ctx, c, *bastion.Spec.SeedName, labelSelector)
+
+ return *bastion.Spec.SeedName == seedName
}
}
-// BastionIsManagedByThisGardenlet checks if the given Bastion is managed by this gardenlet by comparing it with the seed name from the GardenletConfiguration
-// or by checking whether the seed labels match the seed selector from the GardenletConfiguration.
-func BastionIsManagedByThisGardenlet(ctx context.Context, c client.Reader, bastion *operationsv1alpha1.Bastion, gc *config.GardenletConfiguration) bool {
+// BastionIsManagedByThisGardenlet checks if the given Bastion is managed by this gardenlet by comparing it with the seed name from the GardenletConfiguration.
+func BastionIsManagedByThisGardenlet(bastion *operationsv1alpha1.Bastion, gc *config.GardenletConfiguration) bool {
seedName := confighelper.SeedNameFromSeedConfig(gc.SeedConfig)
- if len(seedName) > 0 {
- return bastion.Spec.SeedName != nil && *bastion.Spec.SeedName == seedName
- }
- return seedLabelsMatchWithClient(ctx, c, *bastion.Spec.SeedName, gc.SeedSelector)
+
+ return bastion.Spec.SeedName != nil && *bastion.Spec.SeedName == seedName
}
// ManagedSeedFilterFunc returns a filtering func for ManagedSeeds that checks if the ManagedSeed references a Shoot scheduled on a Seed, for which the gardenlet is responsible..
-func ManagedSeedFilterFunc(ctx context.Context, c client.Reader, seedName string, labelSelector *metav1.LabelSelector) func(obj interface{}) bool {
+func ManagedSeedFilterFunc(ctx context.Context, c client.Reader, seedName string) func(obj interface{}) bool {
return func(obj interface{}) bool {
managedSeed, ok := obj.(*seedmanagementv1alpha1.ManagedSeed)
if !ok {
@@ -217,22 +156,18 @@ func ManagedSeedFilterFunc(ctx context.Context, c client.Reader, seedName string
if shoot.Spec.SeedName == nil {
return false
}
- if len(seedName) > 0 {
- if shoot.Status.SeedName == nil || *shoot.Spec.SeedName == *shoot.Status.SeedName {
- return *shoot.Spec.SeedName == seedName
- }
- return *shoot.Status.SeedName == seedName
- }
+
if shoot.Status.SeedName == nil || *shoot.Spec.SeedName == *shoot.Status.SeedName {
- return seedLabelsMatchWithClient(ctx, c, *shoot.Spec.SeedName, labelSelector)
+ return *shoot.Spec.SeedName == seedName
}
- return seedLabelsMatchWithClient(ctx, c, *shoot.Status.SeedName, labelSelector)
+
+ return *shoot.Status.SeedName == seedName
}
}
// SeedOfManagedSeedFilterFunc returns a filtering func for Seeds that checks if the Seed is owned by a ManagedSeed
// that references a Shoot scheduled on a Seed, for which the gardenlet is responsible.
-func SeedOfManagedSeedFilterFunc(ctx context.Context, c client.Reader, seedName string, labelSelector *metav1.LabelSelector) func(obj interface{}) bool {
+func SeedOfManagedSeedFilterFunc(ctx context.Context, c client.Reader, seedName string) func(obj interface{}) bool {
return func(obj interface{}) bool {
seed, ok := obj.(*gardencorev1beta1.Seed)
if !ok {
@@ -242,6 +177,6 @@ func SeedOfManagedSeedFilterFunc(ctx context.Context, c client.Reader, seedName
if err := c.Get(ctx, kutil.Key(gardencorev1beta1constants.GardenNamespace, seed.Name), managedSeed); err != nil {
return false
}
- return ManagedSeedFilterFunc(ctx, c, seedName, labelSelector)(managedSeed)
+ return ManagedSeedFilterFunc(ctx, c, seedName)(managedSeed)
}
}
diff --git a/pkg/controllerutils/seedfilter_test.go b/pkg/controllerutils/seedfilter_test.go
index 771f513d23d..f1e3cf85db3 100644
--- a/pkg/controllerutils/seedfilter_test.go
+++ b/pkg/controllerutils/seedfilter_test.go
@@ -52,7 +52,6 @@ var _ = Describe("seedfilter", func() {
managedSeed *seedmanagementv1alpha1.ManagedSeed
shoot *gardencorev1beta1.Shoot
- seed *gardencorev1beta1.Seed
seedOfManagedSeed *gardencorev1beta1.Seed
)
@@ -85,14 +84,6 @@ var _ = Describe("seedfilter", func() {
SeedName: pointer.String(seedName),
},
}
- seed = &gardencorev1beta1.Seed{
- ObjectMeta: metav1.ObjectMeta{
- Name: seedName,
- Labels: map[string]string{
- "test-label": "test",
- },
- },
- }
seedOfManagedSeed = &gardencorev1beta1.Seed{
ObjectMeta: metav1.ObjectMeta{
Name: name,
@@ -122,15 +113,6 @@ var _ = Describe("seedfilter", func() {
)
}
- expectGetSeed = func() {
- c.EXPECT().Get(ctx, kutil.Key(seedName), gomock.AssignableToTypeOf(&gardencorev1beta1.Seed{})).DoAndReturn(
- func(_ context.Context, _ client.ObjectKey, s *gardencorev1beta1.Seed) error {
- *s = *seed
- return nil
- },
- )
- }
-
expectGetManagedSeed = func() {
c.EXPECT().Get(ctx, kutil.Key(namespace, name), gomock.AssignableToTypeOf(&seedmanagementv1alpha1.ManagedSeed{})).DoAndReturn(
func(_ context.Context, _ client.ObjectKey, ms *seedmanagementv1alpha1.ManagedSeed) error {
@@ -151,93 +133,59 @@ var _ = Describe("seedfilter", func() {
Describe("#ManagedSeedFilterFunc", func() {
It("should return false if the specified object is not a managed seed", func() {
- f := controllerutils.ManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.ManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(shoot)).To(BeFalse())
})
It("should return false with a shoot that is not found", func() {
expectGetShootNotFound()
- f := controllerutils.ManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.ManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(managedSeed)).To(BeFalse())
})
It("should return false with a shoot that is not yet scheduled on a seed", func() {
shoot.Spec.SeedName = nil
expectGetShoot()
- f := controllerutils.ManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.ManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(managedSeed)).To(BeFalse())
})
It("should return true with a shoot that is scheduled on the specified seed", func() {
expectGetShoot()
- f := controllerutils.ManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.ManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(managedSeed)).To(BeTrue())
})
It("should return true with a shoot that is scheduled on the specified seed (status different from spec)", func() {
shoot.Spec.SeedName = pointer.String("foo")
expectGetShoot()
- f := controllerutils.ManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.ManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(managedSeed)).To(BeTrue())
})
It("should return false with a shoot that is scheduled on a different seed", func() {
expectGetShoot()
- f := controllerutils.ManagedSeedFilterFunc(ctx, c, "foo", nil)
- Expect(f(managedSeed)).To(BeFalse())
- })
-
- It("should return true with a shoot that is scheduled on a seed selected by the specified label selector", func() {
- expectGetShoot()
- expectGetSeed()
- f := controllerutils.ManagedSeedFilterFunc(ctx, c, "", &metav1.LabelSelector{
- MatchLabels: map[string]string{
- "test-label": "test",
- },
- })
- Expect(f(managedSeed)).To(BeTrue())
- })
-
- It("should return true with a shoot that is scheduled on a seed selected by the specified label selector (status different from spec)", func() {
- shoot.Spec.SeedName = pointer.String("foo")
- expectGetShoot()
- expectGetSeed()
- f := controllerutils.ManagedSeedFilterFunc(ctx, c, "", &metav1.LabelSelector{
- MatchLabels: map[string]string{
- "test-label": "test",
- },
- })
- Expect(f(managedSeed)).To(BeTrue())
- })
-
- It("should return false with a shoot that is scheduled on a seed not selected by the specified label selector", func() {
- expectGetShoot()
- expectGetSeed()
- f := controllerutils.ManagedSeedFilterFunc(ctx, c, "", &metav1.LabelSelector{
- MatchLabels: map[string]string{
- "foo": "bar",
- },
- })
+ f := controllerutils.ManagedSeedFilterFunc(ctx, c, "foo")
Expect(f(managedSeed)).To(BeFalse())
})
})
Describe("#SeedOfManagedSeedFilterFunc", func() {
It("should return false if the specified object is not a seed", func() {
- f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(shoot)).To(BeFalse())
})
It("should return false if the seed is not owned by a managed seed", func() {
expectGetManagedSeedNotFound()
- f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(seedOfManagedSeed)).To(BeFalse())
})
It("should return false with a shoot that is not found", func() {
expectGetManagedSeed()
expectGetShootNotFound()
- f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(seedOfManagedSeed)).To(BeFalse())
})
@@ -245,14 +193,14 @@ var _ = Describe("seedfilter", func() {
expectGetManagedSeed()
shoot.Spec.SeedName = nil
expectGetShoot()
- f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(seedOfManagedSeed)).To(BeFalse())
})
It("should return true with a shoot that is scheduled on the specified seed", func() {
expectGetManagedSeed()
expectGetShoot()
- f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(seedOfManagedSeed)).To(BeTrue())
})
@@ -260,69 +208,20 @@ var _ = Describe("seedfilter", func() {
expectGetManagedSeed()
shoot.Spec.SeedName = pointer.String("foo")
expectGetShoot()
- f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, seedName)
Expect(f(seedOfManagedSeed)).To(BeTrue())
})
It("should return false with a shoot that is scheduled on a different seed", func() {
expectGetManagedSeed()
expectGetShoot()
- f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, "foo", nil)
- Expect(f(seedOfManagedSeed)).To(BeFalse())
- })
-
- It("should return true with a shoot that is scheduled on a seed selected by the specified label selector", func() {
- expectGetManagedSeed()
- expectGetShoot()
- expectGetSeed()
- f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, "", &metav1.LabelSelector{
- MatchLabels: map[string]string{
- "test-label": "test",
- },
- })
- Expect(f(seedOfManagedSeed)).To(BeTrue())
- })
-
- It("should return true with a shoot that is scheduled on a seed selected by the specified label selector (status different from spec)", func() {
- expectGetManagedSeed()
- shoot.Spec.SeedName = pointer.String("foo")
- expectGetShoot()
- expectGetSeed()
- f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, "", &metav1.LabelSelector{
- MatchLabels: map[string]string{
- "test-label": "test",
- },
- })
- Expect(f(seedOfManagedSeed)).To(BeTrue())
- })
-
- It("should return false with a shoot that is scheduled on a seed not selected by the specified label selector", func() {
- expectGetManagedSeed()
- expectGetShoot()
- expectGetSeed()
- f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, "", &metav1.LabelSelector{
- MatchLabels: map[string]string{
- "foo": "bar",
- },
- })
+ f := controllerutils.SeedOfManagedSeedFilterFunc(ctx, c, "foo")
Expect(f(seedOfManagedSeed)).To(BeFalse())
})
})
Describe("BackupEntry", func() {
- var (
- backupEntry *gardencorev1beta1.BackupEntry
- seedLabelSelector = &metav1.LabelSelector{
- MatchLabels: map[string]string{
- "test-label": "test",
- },
- }
- otherSeedLabelSelector = &metav1.LabelSelector{
- MatchLabels: map[string]string{
- "test-label": "new-test",
- },
- }
- )
+ var backupEntry *gardencorev1beta1.BackupEntry
BeforeEach(func() {
backupEntry = &gardencorev1beta1.BackupEntry{
@@ -335,13 +234,13 @@ var _ = Describe("seedfilter", func() {
Describe("#BackupEntryFilterFunc", func() {
It("should return false if the specified object is not a BackupEntry", func() {
- f := controllerutils.BackupEntryFilterFunc(ctx, c, seedName, nil)
+ f := controllerutils.BackupEntryFilterFunc(seedName)
Expect(f(shoot)).To(BeFalse())
})
DescribeTable("filter BackupEntry by seedName",
func(specSeedName, statusSeedName *string, filterSeedName string, match gomegatypes.GomegaMatcher) {
- f := controllerutils.BackupEntryFilterFunc(ctx, c, filterSeedName, nil)
+ f := controllerutils.BackupEntryFilterFunc(filterSeedName)
backupEntry.Spec.SeedName = specSeedName
backupEntry.Status.SeedName = statusSeedName
Expect(f(backupEntry)).To(match)
@@ -354,20 +253,6 @@ var _ = Describe("seedfilter", func() {
Entry("BackupEntry.Spec.SeedName matches and BackupEntry.Status.SeedName is nil", pointer.String(seedName), nil, seedName, BeTrue()),
Entry("BackupEntry.Spec.SeedName does not match but BackupEntry.Status.SeedName matches", pointer.String(otherSeed), pointer.String(seedName), seedName, BeTrue()),
)
-
- DescribeTable("filter BackupEntry by Seed label selector",
- func(specSeedName, statusSeedName *string, labelSelector *metav1.LabelSelector, match gomegatypes.GomegaMatcher) {
- expectGetSeed()
- f := controllerutils.BackupEntryFilterFunc(ctx, c, "", labelSelector)
- backupEntry.Spec.SeedName = specSeedName
- backupEntry.Status.SeedName = statusSeedName
- Expect(f(backupEntry)).To(match)
- },
- Entry("BackupEntry.Spec.SeedName does not match and BackupEntry.Status.SeedName is nil", pointer.String(seedName), nil, otherSeedLabelSelector, BeFalse()),
- Entry("BackupEntry.Spec.SeedName and BackupEntry.Status.SeedName do not match", pointer.String(seedName), pointer.String(seedName), otherSeedLabelSelector, BeFalse()),
- Entry("BackupEntry.Spec.SeedName matches and BackupEntry.Status.SeedName is nil", pointer.String(seedName), nil, seedLabelSelector, BeTrue()),
- Entry("BackupEntry.Spec.SeedName does not match but BackupEntry.Status.SeedName matches", pointer.String(otherSeed), pointer.String(seedName), seedLabelSelector, BeTrue()),
- )
})
Describe("#BackupEntryIsManagedByThisGardenlet", func() {
@@ -383,24 +268,11 @@ var _ = Describe("seedfilter", func() {
},
},
}
- Expect(controllerutils.BackupEntryIsManagedByThisGardenlet(ctx, c, backupEntry, gc)).To(match)
+ Expect(controllerutils.BackupEntryIsManagedByThisGardenlet(backupEntry, gc)).To(match)
},
Entry("BackupEntry is not managed by this seed", otherSeed, BeFalse()),
Entry("BackupEntry is managed by this seed", seedName, BeTrue()),
)
-
- DescribeTable("check BackupEntry by seed label selector",
- func(labelSelector *metav1.LabelSelector, match gomegatypes.GomegaMatcher) {
- backupEntry.Spec.SeedName = pointer.String(seedName)
- gc := &config.GardenletConfiguration{
- SeedSelector: labelSelector,
- }
- expectGetSeed()
- Expect(controllerutils.BackupEntryIsManagedByThisGardenlet(ctx, c, backupEntry, gc)).To(match)
- },
- Entry("BackupEntry is not managed by this seed", otherSeedLabelSelector, BeFalse()),
- Entry("BackupEntry is managed by this seed", seedLabelSelector, BeTrue()),
- )
})
})
})
diff --git a/pkg/gardenlet/apis/config/types.go b/pkg/gardenlet/apis/config/types.go
index 5f1eff2fbc1..bef67defc8e 100644
--- a/pkg/gardenlet/apis/config/types.go
+++ b/pkg/gardenlet/apis/config/types.go
@@ -54,13 +54,8 @@ type GardenletConfiguration struct {
// "github.com/gardener/gardener/pkg/gardenlet/features/features.go".
// Default: nil
FeatureGates map[string]bool
- // SeedConfig contains configuration for the seed cluster. Must not be set if seed selector is set.
- // In this case the gardenlet creates the `Seed` object itself based on the provided config.
+ // SeedConfig contains configuration for the seed cluster.
SeedConfig *SeedConfig
- // SeedSelector contains an optional list of labels on `Seed` resources that shall be managed by
- // this gardenlet instance. In this case the `Seed` object is not managed by the Gardenlet and must
- // be created by an operator/administrator.
- SeedSelector *metav1.LabelSelector
// Logging contains an optional configurations for the logging stack deployed
// by the Gardenlet in the seed clusters.
Logging *Logging
diff --git a/pkg/gardenlet/apis/config/v1alpha1/types.go b/pkg/gardenlet/apis/config/v1alpha1/types.go
index 0700f666614..0fc20033219 100644
--- a/pkg/gardenlet/apis/config/v1alpha1/types.go
+++ b/pkg/gardenlet/apis/config/v1alpha1/types.go
@@ -66,15 +66,9 @@ type GardenletConfiguration struct {
// Default: nil
// +optional
FeatureGates map[string]bool `json:"featureGates,omitempty"`
- // SeedConfig contains configuration for the seed cluster. Must not be set if seed selector is set.
- // In this case the gardenlet creates the `Seed` object itself based on the provided config.
+ // SeedConfig contains configuration for the seed cluster.
// +optional
SeedConfig *SeedConfig `json:"seedConfig,omitempty"`
- // SeedSelector contains an optional list of labels on `Seed` resources that shall be managed by
- // this gardenlet instance. In this case the `Seed` object is not managed by the Gardenlet and must
- // be created by an operator/administrator.
- // +optional
- SeedSelector *metav1.LabelSelector `json:"seedSelector,omitempty"`
// Logging contains an optional configurations for the logging stack deployed
// by the Gardenlet in the seed clusters.
// +optional
diff --git a/pkg/gardenlet/apis/config/v1alpha1/zz_generated.conversion.go b/pkg/gardenlet/apis/config/v1alpha1/zz_generated.conversion.go
index e052a51df1f..1e01f1d863e 100644
--- a/pkg/gardenlet/apis/config/v1alpha1/zz_generated.conversion.go
+++ b/pkg/gardenlet/apis/config/v1alpha1/zz_generated.conversion.go
@@ -710,7 +710,6 @@ func autoConvert_v1alpha1_GardenletConfiguration_To_config_GardenletConfiguratio
} else {
out.SeedConfig = nil
}
- out.SeedSelector = (*v1.LabelSelector)(unsafe.Pointer(in.SeedSelector))
if in.Logging != nil {
in, out := &in.Logging, &out.Logging
*out = new(config.Logging)
@@ -782,7 +781,6 @@ func autoConvert_config_GardenletConfiguration_To_v1alpha1_GardenletConfiguratio
} else {
out.SeedConfig = nil
}
- out.SeedSelector = (*v1.LabelSelector)(unsafe.Pointer(in.SeedSelector))
if in.Logging != nil {
in, out := &in.Logging, &out.Logging
*out = new(Logging)
diff --git a/pkg/gardenlet/apis/config/v1alpha1/zz_generated.deepcopy.go b/pkg/gardenlet/apis/config/v1alpha1/zz_generated.deepcopy.go
index 61959181738..1af200fe8f6 100644
--- a/pkg/gardenlet/apis/config/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/gardenlet/apis/config/v1alpha1/zz_generated.deepcopy.go
@@ -358,11 +358,6 @@ func (in *GardenletConfiguration) DeepCopyInto(out *GardenletConfiguration) {
*out = new(SeedConfig)
(*in).DeepCopyInto(*out)
}
- if in.SeedSelector != nil {
- in, out := &in.SeedSelector, &out.SeedSelector
- *out = new(v1.LabelSelector)
- (*in).DeepCopyInto(*out)
- }
if in.Logging != nil {
in, out := &in.Logging, &out.Logging
*out = new(Logging)
diff --git a/pkg/gardenlet/apis/config/validation/validation.go b/pkg/gardenlet/apis/config/validation/validation.go
index 6f50bf5820c..39d289408e8 100644
--- a/pkg/gardenlet/apis/config/validation/validation.go
+++ b/pkg/gardenlet/apis/config/validation/validation.go
@@ -46,8 +46,8 @@ func ValidateGardenletConfiguration(cfg *config.GardenletConfiguration, fldPath
}
}
- if !inTemplate && (cfg.SeedConfig == nil && cfg.SeedSelector == nil) || (cfg.SeedConfig != nil && cfg.SeedSelector != nil) {
- allErrs = append(allErrs, field.Invalid(fldPath.Child("seedConfig"), cfg, "either seed config or seed selector is required"))
+ if !inTemplate && cfg.SeedConfig == nil {
+ allErrs = append(allErrs, field.Invalid(fldPath.Child("seedConfig"), cfg, "seed config must be set"))
}
if cfg.SeedConfig != nil {
diff --git a/pkg/gardenlet/apis/config/validation/validation_test.go b/pkg/gardenlet/apis/config/validation/validation_test.go
index 1a0ba6c8ae9..66ed052dcb4 100644
--- a/pkg/gardenlet/apis/config/validation/validation_test.go
+++ b/pkg/gardenlet/apis/config/validation/validation_test.go
@@ -242,9 +242,8 @@ var _ = Describe("GardenletConfiguration", func() {
})
})
- Context("seed selector/config", func() {
- It("should forbid specifying neither a seed selector nor a seed config", func() {
- cfg.SeedSelector = nil
+ Context("seed config", func() {
+ It("should require a seedConfig", func() {
cfg.SeedConfig = nil
errorList := ValidateGardenletConfiguration(cfg, nil, false)
@@ -254,17 +253,6 @@ var _ = Describe("GardenletConfiguration", func() {
"Field": Equal("seedConfig"),
}))))
})
-
- It("should forbid specifying both a seed selector and a seed config", func() {
- cfg.SeedSelector = &metav1.LabelSelector{}
-
- errorList := ValidateGardenletConfiguration(cfg, nil, false)
-
- Expect(errorList).To(ConsistOf(PointTo(MatchFields(IgnoreExtras, Fields{
- "Type": Equal(field.ErrorTypeInvalid),
- "Field": Equal("seedConfig"),
- }))))
- })
})
Context("seed template", func() {
diff --git a/pkg/gardenlet/apis/config/zz_generated.deepcopy.go b/pkg/gardenlet/apis/config/zz_generated.deepcopy.go
index c5f8d03efde..fd402a47843 100644
--- a/pkg/gardenlet/apis/config/zz_generated.deepcopy.go
+++ b/pkg/gardenlet/apis/config/zz_generated.deepcopy.go
@@ -358,11 +358,6 @@ func (in *GardenletConfiguration) DeepCopyInto(out *GardenletConfiguration) {
*out = new(SeedConfig)
(*in).DeepCopyInto(*out)
}
- if in.SeedSelector != nil {
- in, out := &in.SeedSelector, &out.SeedSelector
- *out = new(v1.LabelSelector)
- (*in).DeepCopyInto(*out)
- }
if in.Logging != nil {
in, out := &in.Logging, &out.Logging
*out = new(Logging)
diff --git a/pkg/gardenlet/bootstrap/certificate/certificate_rotation.go b/pkg/gardenlet/bootstrap/certificate/certificate_rotation.go
index 396340a0a53..f16cac4113b 100644
--- a/pkg/gardenlet/bootstrap/certificate/certificate_rotation.go
+++ b/pkg/gardenlet/bootstrap/certificate/certificate_rotation.go
@@ -24,7 +24,6 @@ import (
"time"
corev1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -58,7 +57,6 @@ type Manager struct {
gardenClientConnection *config.GardenClientConnection
targetClusterName string
seedName string
- seedSelector *metav1.LabelSelector
}
// NewCertificateRotation creates a certificate manager that can be used to rotate gardenlet's client certificate for the Garden cluster
@@ -73,7 +71,6 @@ func NewCertificateManager(clientMap clientmap.ClientMap, seedClient client.Clie
gardenClientConnection: config.GardenClientConnection,
seedName: seedName,
targetClusterName: gardenletTargetClusterName,
- seedSelector: config.SeedSelector,
}
}
@@ -103,14 +100,12 @@ func (cr *Manager) ScheduleCertificateRotation(ctx context.Context, gardenletCan
if err != nil {
msg := fmt.Sprintf("Failed to rotate the kubeconfig for the Garden API Server. Certificate expires in %s (%s): %v", certificateExpirationTime.UTC().Sub(time.Now().UTC()).Round(time.Second).String(), certificateExpirationTime.Round(time.Second).String(), err)
cr.logger.Error(msg)
- seeds, err := cr.getTargetedSeeds(ctx)
+ seed, err := cr.getTargetedSeed(ctx)
if err != nil {
- cr.logger.Warnf("failed to record event on seeds announcing the failed certificate rotation: %v", err)
+ cr.logger.Warnf("failed to record event on seed announcing the failed certificate rotation: %v", err)
return
}
- for _, seed := range seeds {
- recorder.Event(&seed, corev1.EventTypeWarning, EventGardenletCertificateRotationFailed, msg)
- }
+ recorder.Event(seed, corev1.EventTypeWarning, EventGardenletCertificateRotationFailed, msg)
return
}
@@ -119,6 +114,21 @@ func (cr *Manager) ScheduleCertificateRotation(ctx context.Context, gardenletCan
}, time.Second, ctx.Done())
}
+// getTargetedSeed returns the Seed that this Gardenlet is reconciling
+func (cr *Manager) getTargetedSeed(ctx context.Context) (*gardencorev1beta1.Seed, error) {
+ gardenClient, err := cr.clientMap.GetClient(ctx, keys.ForGarden())
+ if err != nil {
+ return nil, err
+ }
+
+ seed := &gardencorev1beta1.Seed{}
+ if err := gardenClient.Client().Get(ctx, client.ObjectKey{Name: cr.seedName}, seed); err != nil {
+ return nil, err
+ }
+
+ return seed, nil
+}
+
// waitForCertificateRotation determines and waits for the certificate rotation deadline.
// Reschedules the certificate rotation in case the underlying certificate expiration date has changed in the meanwhile.
func waitForCertificateRotation(ctx context.Context, logger logrus.FieldLogger, seedClient client.Client, gardenClientConnection *config.GardenClientConnection, now func() time.Time) (*pkix.Name, []string, []net.IP, *time.Time, error) {
@@ -222,34 +232,3 @@ func rotateCertificate(ctx context.Context, logger logrus.FieldLogger, clientMap
return nil
}
-
-// getTargetedSeeds returns the Seeds that this Gardenlet is reconciling
-func getTargetedSeeds(ctx context.Context, gardenClient client.Client, seedSelector *metav1.LabelSelector, seedName string) ([]gardencorev1beta1.Seed, error) {
- if seedSelector != nil {
- seedLabelSelector, err := metav1.LabelSelectorAsSelector(seedSelector)
- if err != nil {
- return nil, err
- }
-
- seeds := &gardencorev1beta1.SeedList{}
- err = gardenClient.List(ctx, seeds, client.MatchingLabelsSelector{Selector: seedLabelSelector})
- if err != nil {
- return nil, err
- }
- return seeds.Items, nil
- }
-
- seed := &gardencorev1beta1.Seed{}
- if err := gardenClient.Get(ctx, client.ObjectKey{Name: seedName}, seed); err != nil {
- return nil, err
- }
- return []gardencorev1beta1.Seed{*seed}, nil
-}
-
-func (cr *Manager) getTargetedSeeds(ctx context.Context) ([]gardencorev1beta1.Seed, error) {
- gardenClient, err := cr.clientMap.GetClient(ctx, keys.ForGarden())
- if err != nil {
- return nil, err
- }
- return getTargetedSeeds(ctx, gardenClient.Client(), cr.seedSelector, cr.seedName)
-}
diff --git a/pkg/gardenlet/bootstrap/certificate/certificate_rotation_test.go b/pkg/gardenlet/bootstrap/certificate/certificate_rotation_test.go
index 3ca80d3a271..78c3d6f703a 100644
--- a/pkg/gardenlet/bootstrap/certificate/certificate_rotation_test.go
+++ b/pkg/gardenlet/bootstrap/certificate/certificate_rotation_test.go
@@ -345,57 +345,6 @@ users:
})
})
- Describe("#getTargetedSeeds", func() {
- It("should return a single Seed", func() {
- mockSeedClient.EXPECT().Get(ctx, kutil.Key(seedName), gomock.AssignableToTypeOf(&gardencorev1beta1.Seed{})).DoAndReturn(func(_ context.Context, _ client.ObjectKey, seed *gardencorev1beta1.Seed) error {
- seed.ObjectMeta = metav1.ObjectMeta{
- Name: seedName,
- }
- return nil
- })
-
- seeds, err := getTargetedSeeds(ctx, mockSeedClient, nil, seedName)
- Expect(err).ToNot(HaveOccurred())
- Expect(seeds).To(HaveLen(1))
- Expect(seeds[0]).To(Equal(gardencorev1beta1.Seed{
- ObjectMeta: metav1.ObjectMeta{
- Name: seedName,
- },
- }))
- })
-
- It("should return all Seed matched by seedSelector", func() {
- items := []gardencorev1beta1.Seed{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "seed-one",
- },
- },
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "seed-two",
- },
- },
- }
-
- seedSelector := &metav1.LabelSelector{MatchLabels: map[string]string{
- "seed-kind": "promiscuous",
- }}
-
- seedLabelSelector, err := metav1.LabelSelectorAsSelector(seedSelector)
- Expect(err).To(BeNil())
- mockSeedClient.EXPECT().List(ctx, gomock.AssignableToTypeOf(&gardencorev1beta1.SeedList{}), client.MatchingLabelsSelector{Selector: seedLabelSelector}).DoAndReturn(func(_ context.Context, list *gardencorev1beta1.SeedList, _ ...client.ListOption) error {
- *list = gardencorev1beta1.SeedList{Items: items}
- return nil
- })
-
- seeds, err := getTargetedSeeds(ctx, mockSeedClient, seedSelector, seedName)
- Expect(err).ToNot(HaveOccurred())
- Expect(seeds).To(HaveLen(2))
- Expect(seeds).To(Equal(items))
- })
- })
-
Describe("#waitForCertificateRotation", func() {
var (
testKubeconfig string
diff --git a/pkg/gardenlet/controller/backupbucket/backup_bucket.go b/pkg/gardenlet/controller/backupbucket/backup_bucket.go
index 98189357d44..be59725743b 100644
--- a/pkg/gardenlet/controller/backupbucket/backup_bucket.go
+++ b/pkg/gardenlet/controller/backupbucket/backup_bucket.go
@@ -82,7 +82,7 @@ func NewBackupBucketController(ctx context.Context, clientMap clientmap.ClientMa
}
controller.backupBucketInformer.AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.BackupBucketFilterFunc(ctx, controller.gardenClient, confighelper.SeedNameFromSeedConfig(controller.config.SeedConfig), controller.config.SeedSelector),
+ FilterFunc: controllerutils.BackupBucketFilterFunc(confighelper.SeedNameFromSeedConfig(controller.config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: controller.backupBucketAdd,
UpdateFunc: controller.backupBucketUpdate,
diff --git a/pkg/gardenlet/controller/backupentry/backup_entry.go b/pkg/gardenlet/controller/backupentry/backup_entry.go
index c2aa0f2a93d..e015e9b4d2a 100644
--- a/pkg/gardenlet/controller/backupentry/backup_entry.go
+++ b/pkg/gardenlet/controller/backupentry/backup_entry.go
@@ -77,7 +77,7 @@ func NewBackupEntryController(ctx context.Context, clientMap clientmap.ClientMap
}
controller.backupEntryInformer.AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.BackupEntryFilterFunc(ctx, controller.gardenClient, confighelper.SeedNameFromSeedConfig(controller.config.SeedConfig), controller.config.SeedSelector),
+ FilterFunc: controllerutils.BackupEntryFilterFunc(confighelper.SeedNameFromSeedConfig(controller.config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: controller.backupEntryAdd,
UpdateFunc: controller.backupEntryUpdate,
diff --git a/pkg/gardenlet/controller/backupentry/backup_entry_reconciler.go b/pkg/gardenlet/controller/backupentry/backup_entry_reconciler.go
index 9601fc3a726..49e9f27d337 100644
--- a/pkg/gardenlet/controller/backupentry/backup_entry_reconciler.go
+++ b/pkg/gardenlet/controller/backupentry/backup_entry_reconciler.go
@@ -85,7 +85,7 @@ func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) (
return r.migrateBackupEntry(ctx, gardenClient, be)
}
- if !controllerutils.BackupEntryIsManagedByThisGardenlet(ctx, gardenClient.Client(), be, r.config) {
+ if !controllerutils.BackupEntryIsManagedByThisGardenlet(be, r.config) {
r.logger.Debugf("Skipping because BackupEntry is not managed by this gardenlet in seed %s", *be.Spec.SeedName)
return reconcile.Result{}, nil
}
diff --git a/pkg/gardenlet/controller/bastion/bastion.go b/pkg/gardenlet/controller/bastion/bastion.go
index 33f2317b574..7ea669cfef4 100644
--- a/pkg/gardenlet/controller/bastion/bastion.go
+++ b/pkg/gardenlet/controller/bastion/bastion.go
@@ -76,7 +76,7 @@ func NewBastionController(ctx context.Context, clientMap clientmap.ClientMap, co
}
bastionInformer.AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.BastionFilterFunc(ctx, gardenClient.Client(), confighelper.SeedNameFromSeedConfig(config.SeedConfig), config.SeedSelector),
+ FilterFunc: controllerutils.BastionFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: controller.bastionAdd,
UpdateFunc: controller.bastionUpdate,
diff --git a/pkg/gardenlet/controller/bastion/bastion_reconciler.go b/pkg/gardenlet/controller/bastion/bastion_reconciler.go
index d76824554b5..4e4ea27033a 100644
--- a/pkg/gardenlet/controller/bastion/bastion_reconciler.go
+++ b/pkg/gardenlet/controller/bastion/bastion_reconciler.go
@@ -88,7 +88,7 @@ func (r *reconciler) Reconcile(ctx context.Context, request reconcile.Request) (
return reconcile.Result{}, err
}
- if !controllerutils.BastionIsManagedByThisGardenlet(ctx, gardenClient.Client(), bastion, r.config) {
+ if !controllerutils.BastionIsManagedByThisGardenlet(bastion, r.config) {
logger.WithField("bastion-seed", *bastion.Spec.SeedName).Debug("Skipping because Bastion is not managed by this gardenlet")
return reconcile.Result{}, nil
}
diff --git a/pkg/gardenlet/controller/controllerinstallation/controllerinstallation.go b/pkg/gardenlet/controller/controllerinstallation/controllerinstallation.go
index df32ad56923..61936b734d5 100644
--- a/pkg/gardenlet/controller/controllerinstallation/controllerinstallation.go
+++ b/pkg/gardenlet/controller/controllerinstallation/controllerinstallation.go
@@ -99,7 +99,7 @@ func NewController(clientMap clientmap.ClientMap, gardenCoreInformerFactory gard
}
controllerInstallationInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.ControllerInstallationFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig), seedLister, config.SeedSelector),
+ FilterFunc: controllerutils.ControllerInstallationFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: controller.controllerInstallationAdd,
UpdateFunc: controller.controllerInstallationUpdate,
@@ -108,7 +108,7 @@ func NewController(clientMap clientmap.ClientMap, gardenCoreInformerFactory gard
})
controllerInstallationInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.ControllerInstallationFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig), seedLister, config.SeedSelector),
+ FilterFunc: controllerutils.ControllerInstallationFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: controller.controllerInstallationCareAdd,
},
diff --git a/pkg/gardenlet/controller/factory.go b/pkg/gardenlet/controller/factory.go
index df3bd7cd5f1..70712c618b4 100644
--- a/pkg/gardenlet/controller/factory.go
+++ b/pkg/gardenlet/controller/factory.go
@@ -115,11 +115,9 @@ func (f *GardenletControllerFactory) Run(ctx context.Context) error {
return fmt.Errorf("timed out waiting for Garden core caches to sync")
}
- // Register Seed object if desired
- if f.cfg.SeedConfig != nil {
- if err := f.registerSeed(ctx, k8sGardenClient); err != nil {
- return fmt.Errorf("failed to register the seed: %+v", err)
- }
+ // Register Seed object
+ if err := f.registerSeed(ctx, k8sGardenClient); err != nil {
+ return fmt.Errorf("failed to register the seed: %+v", err)
}
imageVector, err := imagevector.ReadGlobalImageVectorWithEnvOverride(filepath.Join(charts.Path, DefaultImageVector))
diff --git a/pkg/gardenlet/controller/federatedseed/seed_control.go b/pkg/gardenlet/controller/federatedseed/seed_control.go
index 7b28de3e2ab..191ab18fc98 100644
--- a/pkg/gardenlet/controller/federatedseed/seed_control.go
+++ b/pkg/gardenlet/controller/federatedseed/seed_control.go
@@ -138,7 +138,7 @@ func (c *Controller) seedDelete(obj interface{}) {
// Run starts the FederatedSeed Controller
func (c *Controller) Run(ctx context.Context, workers int) {
c.seedInformer.AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.SeedFilterFunc(confighelper.SeedNameFromSeedConfig(c.config.SeedConfig), c.config.SeedSelector),
+ FilterFunc: controllerutils.SeedFilterFunc(confighelper.SeedNameFromSeedConfig(c.config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: c.seedAdd,
UpdateFunc: c.seedUpdate,
diff --git a/pkg/gardenlet/controller/managedseed/managedseed.go b/pkg/gardenlet/controller/managedseed/managedseed.go
index 2bafdb5aa0d..fb55dde7d89 100644
--- a/pkg/gardenlet/controller/managedseed/managedseed.go
+++ b/pkg/gardenlet/controller/managedseed/managedseed.go
@@ -110,7 +110,7 @@ func (c *Controller) Run(ctx context.Context, workers int) {
var waitGroup sync.WaitGroup
c.managedSeedInformer.AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.ManagedSeedFilterFunc(ctx, c.gardenClient.Cache(), confighelper.SeedNameFromSeedConfig(c.config.SeedConfig), c.config.SeedSelector),
+ FilterFunc: controllerutils.ManagedSeedFilterFunc(ctx, c.gardenClient.Cache(), confighelper.SeedNameFromSeedConfig(c.config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: c.managedSeedAdd,
UpdateFunc: c.managedSeedUpdate,
@@ -120,7 +120,7 @@ func (c *Controller) Run(ctx context.Context, workers int) {
// Add event handler for controlled seeds
c.seedInformer.AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.SeedOfManagedSeedFilterFunc(ctx, c.gardenClient.Cache(), confighelper.SeedNameFromSeedConfig(c.config.SeedConfig), c.config.SeedSelector),
+ FilterFunc: controllerutils.SeedOfManagedSeedFilterFunc(ctx, c.gardenClient.Cache(), confighelper.SeedNameFromSeedConfig(c.config.SeedConfig)),
Handler: &kutils.ControlledResourceEventHandler{
ControllerTypes: []kutils.ControllerType{
{
diff --git a/pkg/gardenlet/controller/managedseed/managedseed_actuator.go b/pkg/gardenlet/controller/managedseed/managedseed_actuator.go
index 77eb4218ab2..8eb4de402d2 100644
--- a/pkg/gardenlet/controller/managedseed/managedseed_actuator.go
+++ b/pkg/gardenlet/controller/managedseed/managedseed_actuator.go
@@ -633,9 +633,6 @@ func (a *actuator) prepareGardenletChartValues(
// Set the seed name
gardenletConfig.SeedConfig.SeedTemplate.Name = objectMeta.Name
- // Ensure seed selector is not set
- gardenletConfig.SeedSelector = nil
-
// Get gardenlet chart values
return a.vp.GetGardenletChartValues(
ensureGardenletEnvironment(deployment, shoot.Spec.DNS),
diff --git a/pkg/gardenlet/controller/managedseed/managedseed_actuator_test.go b/pkg/gardenlet/controller/managedseed/managedseed_actuator_test.go
index 269a43fb9b8..8ea3f592464 100644
--- a/pkg/gardenlet/controller/managedseed/managedseed_actuator_test.go
+++ b/pkg/gardenlet/controller/managedseed/managedseed_actuator_test.go
@@ -490,7 +490,6 @@ var _ = Describe("Actuator", func() {
Kubeconfig: "kubeconfig",
},
}
- mergedGardenletConfig.SeedSelector = &metav1.LabelSelector{}
vh.EXPECT().MergeGardenletDeployment(managedSeed.Spec.Gardenlet.Deployment, shoot).Return(mergedDeployment, nil)
vh.EXPECT().MergeGardenletConfiguration(managedSeed.Spec.Gardenlet.Config.Object).Return(mergedGardenletConfig, nil)
@@ -552,7 +551,7 @@ var _ = Describe("Actuator", func() {
},
Spec: seedTemplate.Spec,
}))
- Expect(gc.SeedSelector).To(BeNil())
+
return gardenletChartValues, nil
},
)
diff --git a/pkg/gardenlet/controller/seed/seed.go b/pkg/gardenlet/controller/seed/seed.go
index e84f699dcb7..cb1bb103fd8 100644
--- a/pkg/gardenlet/controller/seed/seed.go
+++ b/pkg/gardenlet/controller/seed/seed.go
@@ -20,9 +20,7 @@ import (
"time"
"github.com/prometheus/client_golang/prometheus"
- apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
@@ -64,9 +62,6 @@ type Controller struct {
workerCh chan int
numberOfRunningWorkers int
-
- lock sync.Mutex
- leaseMap map[string]bool
}
// NewSeedController takes a Kubernetes client for the Garden clusters , a struct
@@ -106,11 +101,10 @@ func NewSeedController(
seedLeaseQueue: workqueue.NewNamedRateLimitingQueue(workqueue.NewItemExponentialFailureRateLimiter(time.Millisecond, 2*time.Second), "seed-lease"),
seedExtensionCheckQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "seed-extension-check"),
workerCh: make(chan int),
- leaseMap: make(map[string]bool),
}
seedInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.SeedFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig), config.SeedSelector),
+ FilterFunc: controllerutils.SeedFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: seedController.seedAdd,
UpdateFunc: seedController.seedUpdate,
@@ -119,14 +113,14 @@ func NewSeedController(
})
seedInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.SeedFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig), config.SeedSelector),
+ FilterFunc: controllerutils.SeedFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: seedController.seedLeaseAdd,
},
})
controllerInstallationInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.ControllerInstallationFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig), seedLister, config.SeedSelector),
+ FilterFunc: controllerutils.ControllerInstallationFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: seedController.controllerInstallationOfSeedAdd,
UpdateFunc: seedController.controllerInstallationOfSeedUpdate,
@@ -167,9 +161,6 @@ func (c *Controller) Run(ctx context.Context, workers int) {
controllerutils.DeprecatedCreateWorker(ctx, c.seedExtensionCheckQueue, "Seed Extension Check", c.reconcileSeedExtensionCheckKey, &waitGroup, c.workerCh)
}
- // health management
- go c.startHealthManagement(ctx)
-
// Shutdown handling
<-ctx.Done()
c.seedQueue.ShutDown()
@@ -188,71 +179,6 @@ func (c *Controller) Run(ctx context.Context, workers int) {
waitGroup.Wait()
}
-func (c *Controller) startHealthManagement(ctx context.Context) {
- var (
- seedName = confighelper.SeedNameFromSeedConfig(c.config.SeedConfig)
- seedLabelSelector labels.Selector
- expectedHealthReports int
- err error
- )
-
- if seedName != "" {
- expectedHealthReports = 1
- } else {
- seedLabelSelector, err = metav1.LabelSelectorAsSelector(c.config.SeedSelector)
- if err != nil {
- panic(err)
- }
- }
-
- for {
- select {
- case <-ctx.Done():
- return
- case <-time.After(LeaseResyncGracePeriodSeconds / 2 * time.Second):
-
- isHealthy := true
-
- if len(seedName) > 0 {
- if _, err := c.k8sGardenCoreInformers.Core().V1beta1().Seeds().Lister().Get(seedName); err != nil {
- if apierrors.IsNotFound(err) {
- // the Seed configured for the Gardenlet does not exist.
- // Do not expect an existing lease
- expectedHealthReports = 0
- } else {
- logger.Logger.Errorf("error when getting the seed %q for health management: %+v", seedName, err)
- isHealthy = false
- }
- }
- } else {
- seedList, err := c.k8sGardenCoreInformers.Core().V1beta1().Seeds().Lister().List(seedLabelSelector)
- if err != nil {
- logger.Logger.Errorf("error while listing seeds for health management: %+v", err)
- isHealthy = false
- }
- expectedHealthReports = len(seedList)
- }
-
- c.lock.Lock()
-
- if len(c.leaseMap) != expectedHealthReports {
- isHealthy = false
- } else {
- for _, status := range c.leaseMap {
- if !status {
- isHealthy = false
- break
- }
- }
- }
-
- c.leaseMap = make(map[string]bool)
- c.lock.Unlock()
- c.healthManager.Set(isHealthy)
- }
- }
-}
-
// RunningWorkers returns the number of running workers.
func (c *Controller) RunningWorkers() int {
return c.numberOfRunningWorkers
diff --git a/pkg/gardenlet/controller/seed/seed_lease_control.go b/pkg/gardenlet/controller/seed/seed_lease_control.go
index 100e998792a..2b779d4ac75 100644
--- a/pkg/gardenlet/controller/seed/seed_lease_control.go
+++ b/pkg/gardenlet/controller/seed/seed_lease_control.go
@@ -71,9 +71,7 @@ func (c *Controller) reconcileSeedLeaseKey(key string) error {
}
if err := c.checkSeedConnection(ctx, seed); err != nil {
- c.lock.Lock()
- c.leaseMap[seed.Name] = false
- c.lock.Unlock()
+ c.healthManager.Set(false)
return fmt.Errorf("[SEED LEASE] cannot establish connection with Seed %s: %v", key, err)
}
@@ -83,9 +81,7 @@ func (c *Controller) reconcileSeedLeaseKey(key string) error {
)
if err := c.seedLeaseControl.Sync(seedCopy.Name, *seedOwnerReference); err != nil {
- c.lock.Lock()
- c.leaseMap[seed.Name] = false
- c.lock.Unlock()
+ c.healthManager.Set(false)
return err
}
@@ -94,9 +90,7 @@ func (c *Controller) reconcileSeedLeaseKey(key string) error {
return fmt.Errorf("failed to get garden client: %w", err)
}
- c.lock.Lock()
- c.leaseMap[seed.Name] = true
- c.lock.Unlock()
+ c.healthManager.Set(true)
bldr, err := helper.NewConditionBuilder(gardencorev1beta1.SeedGardenletReady)
if err != nil {
diff --git a/pkg/gardenlet/controller/seed/seed_lease_control_test.go b/pkg/gardenlet/controller/seed/seed_lease_control_test.go
index 15c44acf145..4e4bcf47afb 100644
--- a/pkg/gardenlet/controller/seed/seed_lease_control_test.go
+++ b/pkg/gardenlet/controller/seed/seed_lease_control_test.go
@@ -27,6 +27,7 @@ import (
"github.com/gardener/gardener/pkg/client/kubernetes/clientmap/keys"
mock "github.com/gardener/gardener/pkg/client/kubernetes/mock"
"github.com/gardener/gardener/pkg/gardenlet/apis/config"
+ "github.com/gardener/gardener/pkg/healthz"
"github.com/gardener/gardener/pkg/logger"
mockrest "github.com/gardener/gardener/pkg/mock/client-go/rest"
mockio "github.com/gardener/gardener/pkg/mock/go/io"
@@ -111,6 +112,9 @@ var _ = Describe("SeedLeaseControlReconcile", func() {
err: syncFail,
}
+ healthManager := healthz.NewDefaultHealthz()
+ healthManager.Start()
+
clientMap := fakeclientmap.NewClientMap().
AddClient(keys.ForGarden(), k8sGardenClient).
AddClient(keys.ForSeed(seed), k8sGardenClient)
@@ -120,7 +124,7 @@ var _ = Describe("SeedLeaseControlReconcile", func() {
seedLeaseQueue: seedLeaseQueue,
config: gardenletConfig,
seedLeaseControl: seedLeaseControl,
- leaseMap: make(map[string]bool),
+ healthManager: healthManager,
}
Expect(indexer.Add(seed)).NotTo(HaveOccurred())
})
@@ -149,7 +153,7 @@ var _ = Describe("SeedLeaseControlReconcile", func() {
It("returns error if connection to Seed is unsuccessful", func() {
err := controller.reconcileSeedLeaseKey(seedName)
Expect(err).To(HaveOccurred())
- Expect(controller.leaseMap).To(HaveKeyWithValue(seedName, false))
+ Expect(controller.healthManager.Get()).To(BeFalse())
})
})
@@ -161,7 +165,7 @@ var _ = Describe("SeedLeaseControlReconcile", func() {
It("propagates the error when lease fails to update", func() {
err := controller.reconcileSeedLeaseKey(seedName)
Expect(err).To(HaveOccurred())
- Expect(controller.leaseMap).To(HaveKeyWithValue(seedName, false))
+ Expect(controller.healthManager.Get()).To(BeFalse())
})
})
@@ -169,7 +173,7 @@ var _ = Describe("SeedLeaseControlReconcile", func() {
It("updates the lease without error", func() {
err := controller.reconcileSeedLeaseKey(seedName)
Expect(err).NotTo(HaveOccurred())
- Expect(controller.leaseMap).To(HaveKeyWithValue(seedName, true))
+ Expect(controller.healthManager.Get()).To(BeTrue())
})
})
@@ -186,7 +190,7 @@ var _ = Describe("SeedLeaseControlReconcile", func() {
It("updated seed Condition if already exists", func() {
err := controller.reconcileSeedLeaseKey(seedName)
Expect(err).NotTo(HaveOccurred())
- Expect(controller.leaseMap).To(HaveKeyWithValue(seedName, true))
+ Expect(controller.healthManager.Get()).To(BeTrue())
})
})
})
diff --git a/pkg/gardenlet/controller/shoot/shoot.go b/pkg/gardenlet/controller/shoot/shoot.go
index cee8942fe10..8725d0b24a3 100644
--- a/pkg/gardenlet/controller/shoot/shoot.go
+++ b/pkg/gardenlet/controller/shoot/shoot.go
@@ -111,7 +111,7 @@ func NewShootController(clientMap clientmap.ClientMap, k8sGardenCoreInformers ga
}
shootInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.ShootFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig), seedLister, config.SeedSelector),
+ FilterFunc: controllerutils.ShootFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
shootController.shootAdd(obj, false)
@@ -122,7 +122,7 @@ func NewShootController(clientMap clientmap.ClientMap, k8sGardenCoreInformers ga
})
shootInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.ShootFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig), seedLister, config.SeedSelector),
+ FilterFunc: controllerutils.ShootFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: shootController.shootCareAdd,
UpdateFunc: shootController.shootCareUpdate,
@@ -130,7 +130,7 @@ func NewShootController(clientMap clientmap.ClientMap, k8sGardenCoreInformers ga
})
shootInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
- FilterFunc: controllerutils.ShootFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig), seedLister, config.SeedSelector),
+ FilterFunc: controllerutils.ShootFilterFunc(confighelper.SeedNameFromSeedConfig(config.SeedConfig)),
Handler: cache.ResourceEventHandlerFuncs{
AddFunc: shootController.seedRegistrationAdd,
UpdateFunc: shootController.seedRegistrationUpdate,
@@ -168,7 +168,7 @@ func (c *Controller) Run(ctx context.Context, shootWorkers, shootCareWorkers int
}
// Update Shoots before starting the workers.
- shootFilterFunc := controllerutils.ShootFilterFunc(confighelper.SeedNameFromSeedConfig(c.config.SeedConfig), c.seedLister, c.config.SeedSelector)
+ shootFilterFunc := controllerutils.ShootFilterFunc(confighelper.SeedNameFromSeedConfig(c.config.SeedConfig))
shoots, err := c.shootLister.List(labels.Everything())
if err != nil {
logger.Logger.Errorf("Failed to fetch shoots resources: %v", err.Error())
diff --git a/pkg/gardenlet/controller/shoot/shoot_care_control.go b/pkg/gardenlet/controller/shoot/shoot_care_control.go
index d7fc819dd77..b99bbe3c155 100644
--- a/pkg/gardenlet/controller/shoot/shoot_care_control.go
+++ b/pkg/gardenlet/controller/shoot/shoot_care_control.go
@@ -198,7 +198,7 @@ func (s *careReconciler) Reconcile(ctx context.Context, req reconcile.Request) (
}
// if shoot is no longer managed by this gardenlet (e.g., due to migration to another seed) then don't requeue
- if !controllerutils.ShootIsManagedByThisGardenlet(shootObj, s.config, s.k8sGardenCoreInformers.Seeds().Lister()) {
+ if !controllerutils.ShootIsManagedByThisGardenlet(shootObj, s.config) {
return reconcile.Result{}, nil
}
diff --git a/pkg/gardenlet/controller/shoot/shoot_control.go b/pkg/gardenlet/controller/shoot/shoot_control.go
index c68cae7ba60..da080bfd38a 100644
--- a/pkg/gardenlet/controller/shoot/shoot_control.go
+++ b/pkg/gardenlet/controller/shoot/shoot_control.go
@@ -234,7 +234,7 @@ func (c *Controller) reconcileShootRequest(ctx context.Context, req reconcile.Re
}
// if shoot is no longer managed by this gardenlet (e.g., due to migration to another seed) then don't requeue
- if !controllerutils.ShootIsManagedByThisGardenlet(shoot, c.config, c.seedLister) {
+ if !controllerutils.ShootIsManagedByThisGardenlet(shoot, c.config) {
log.Debugf("Skipping because Shoot is not managed by this gardenlet in seed %s", *shoot.Spec.SeedName)
return reconcile.Result{}, nil
}