# Gardener Controller Manager

The Gardener Controller Manager (often refered to as "GCM") is a component that runs next to the Gardener API server, similar to the Kubernetes Controller Manager.
It runs several control loops that do not require talking to any seed or shoot cluster.
Also, as of today it exposes a HTTPS server that is serving several endpoints for webhooks for certain resources.

This document explains the various functionalities of the Gardener Controller Manager and their purpose.

## Control Loops

### `Project` Controller

This controller consists out of two reconciliation loops:
The main loop is reconciling `Project` resources while the second loop is controlling the necessary actions for stale projects.

### "Main" Reconciler

This reconciler will create a dedicated `Namespace` prefixed with `garden-` for each `Project` resource.
The name of the namespace can either be stated in the `.spec.namespace`, or it will be auto-generated by the reconciler.
If `.spec.namespace` is set then it creates it if it does not exist yet.
Otherwise, it tries to adopt it.
This will only succeed if the `Namespace` was previously labeled with `gardener.cloud/role=project` and `project.gardener.cloud/name=<project-name>`.
This is to prevent that end-users can adopt arbitrary namespaces and escalate their privileges, e.g. the `kube-system` namespace.

After the namespace was created/adopted the reconciler creates several `ClusterRole`s and `ClusterRoleBinding`s that allow the project members to access related resources based on their roles.
These RBAC resources are prefixed with `gardener.cloud:system:project{-member,-viewer}:<project-name>`.
Gardener administrators and extension developers can define their own roles, see [this document](../extensions/project-roles.md) for more information.

The `.status.phase` of the `Project` resources will be set to `Ready` or `Failed` by the reconciler to indicate whether the reconciliation loop was performed successfully.
Also, it will generate `Event`s to provide further information about its operations.

### "Stale Projects" Reconciler

As Gardener is a large-scale Kubernetes as a Service it is designed for being used by a large amount of end-users.
Over time, it is likely to happen that some of the hundreds or thousands of `Project` resources are no longer actively used.

Gardener offers the "stale projects" reconciler which will take care of identifying such stale projects, marking them with a "warning", and eventually deleting them after a certain time period.
This reconciler is enabled by default and works as following:

1. Projects are considered as "stale"/not actively used when all of the following conditions apply: The namespace associated with the `Project` does not have any...
    1. `Shoot` resources.
    1. `Plant` resources.
    1. `BackupEntry` resources.
    1. `Secret` resources that are referenced by a `SecretBinding` that is in use by a `Shoot` (not necessarily in the same namespace).
    1. `Quota` resources that are referenced by a `SecretBinding` that is in use by a `Shoot` (not necessarily in the same namespace).

If a project is considered "stale" then its `.status.staleSinceTimestamp` will be set to the time when it was first detected to be stale.
If it gets actively used again this timestamp will be removed.
After some time the `.status.staleAutoDeleteTimestamp` will be set to a timestamp after which Gardener will auto-delete the `Project` resource if it still is not actively used.

The component configuration of the Gardener Controller Manager offers to configure the following options:

* `minimumLifetimeDays`: Don't consider newly created `Project`s as "stale" too early to give people/end-users some time to onboard and get familiar with the system. The "stale project" reconciler won't set any timestamp for `Project`s younger than `minimumLifetimeDays`. When you change this value then projects marked as "stale" may be no longer marked as "stale" in case they are young enough, or vice versa.
* `staleGracePeriodDays`: Don't compute auto-delete timestamps for stale `Project`s that are unused for only less than `staleGracePeriodDays`. This is to not unnecessarily make people/end-users nervous "just because" they haven't actively used their `Project` for a given amount of time. When you change this value then already assigned auto-delete timestamps may be removed again if the new grace period is not yet exceeded.
* `staleExpirationTimeDays`: Expiration time after which stale `Project`s are finally auto-deleted (after `.status.staleSinceTimestamp`). If this value is changed and an auto-delete timestamp got already assigned to the projects then the new value will only take effect if it's increased. Hence, decreasing the `staleExpirationTimeDays` will not decrease already assigned auto-delete timestamps.

### Event Controller

With the Gardener Event Controller you can prolong the lifespan of events related to Shoot clusters.
This is an optional controller which will become active once you provide the below mentioned configuration.

All events in K8s are deleted after a configurable time-to-live (controlled via a [kube-apiserver argument](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/) called `--event-ttl` (defaulting to 1 hour)).
The need to prolong the time-to-live for Shoot cluster events frequently arises when debugging customer issues on live systems.
This controller leaves events involving Shoots untouched while deleting all other events after a configured time.
In order to activate it, provide the following configuration:

* `concurrentSyncs`: The amount of goroutines scheduled for reconciling events.
* `ttlNonShootEvents`: When an event reaches this time-to-live it gets deleted unless it is a Shoot-related event (defaults to `1h`, equivalent to the `event-ttl` default).

> :warning: In addition, you should also configure the `--event-ttl` for the kube-apiserver to define an upper-limit of how long Shoot-related events should be stored.
The `--event-ttl` should be larger than the `ttlNonShootEvents` or this controller will have no effect.
