Plugins

A Plugin is an instance of a PluginDefinition and is used to deploy infrastructure components such as observability, compliance or system components to a Kubernetes cluster managed with Greenhouse. A Plugin provides the specific configuration for deploying the Helm chart associated with the referenced PluginDefinition to a specific cluster.

Example Plugin Spec

apiVersion: greenhouse.sap/v1alpha1
kind: Plugin
metadata:
  name: alerts-plugin
  namespace: example-organization
spec:
  clusterName: example-cluster
  displayName: Example Alerts Plugin
  optionValues:
  - name: image.tag
    value: foobar
  pluginDefinitionRef:
    kind: PluginDefinition
    name: alerts
  releaseName: alerts
  releaseNamespace: kube-monitoring

Writing a Plugin Spec

.spec.displayName is an optional human-readable name that is used to display the Plugin in the Greenhouse UI. If not provided, it defaults to the value of metadata.name.

.spec.clusterName is the name of the Cluster resource where the Helm chart associated with the PluginDefinition will be deployed.

.spec.pluginDefinitionRef is the required reference to a PluginDefinition resource that defines the Helm chart and UI application associated with this Plugin.

spec:
  pluginDefinitionRef:
    kind: PluginDefinition
    name: alerts

.spec.releaseName is the optional and immutable name of the Helm release that will be created when deploying the Plugin to the target cluster. If not provided it defaults to the name of the PluginDefinition’s Helm chart.

.spec.releaseNamespace is the optional and immutable Kubernetes namespace in the target cluster where the Helm release will be deployed. If not provided, it defaults to the name of the Organization.

.spec.optionValues is an optional list of Helm chart values that will be used to customize the deployment of the Helm chart associated with the PluginDefinition. These values are used to set Options required by the PluginDefinition or to override provided default values.

  optionValues:
  - name: image.tag
    value: foobar
  - name: secret
    valueFrom:
      secret:
        name: alerts-secret
        key: secret-key

ℹ️ A defaulting webhook automatically merges the OptionValues with the defaults set in the PluginDefinition. The defaulting does not update OptionValues when the defaults change and does not remove values when they are removed from the PluginDefinition. Only when the Plugin is managed via a PluginPreset, the OptionValues will be automatically updated when the defaults in the PluginDefinition change. Standalone Plugins will need to be reconciled by annotating with the reconcile annotation to apply the new defaults.

.spec.waitFor is an optional field that specifies PluginPresets or Plugins which have to be successfully deployed before this Plugin can be deployed. This can be used to express dependencies between Plugins. This can be useful if one Plugin depends on Custom Resource Definitions or other resources created by another Plugin.

spec:
  waitFor:
  - pluginRef:
      pluginPreset: ingress-nginx
  - pluginRef:
      name: cert-manager-example-cluster

ℹ️ The dependency on a PluginPreset ensures that a Plugin created by this PluginPreset has been deployed to the same cluster. The dependency on a Plugin is fulfilled if the referenced Plugin is deployed to the same cluster.

.spec.ignoreDifferences is an optional field that is used to suppress specific differences detected by the drift detection of the deployment tool. This can be useful to ignore differences in fields that are managed by other controllers or tools. Example configuration with Flux.

spec:
  ignoreDifferences:
  - group: apps
    version: v1
    kind: Deployment
    paths:
    - /spec/replicas

Injected Greenhouse Values

The defaulting webhook adds a set of global.greenhouse.* OptionValues to every Plugin. A PluginDefinition does not need to declare them as PluginOptions. They are passed to the Helm chart like any other OptionValue and can be referenced in PluginPreset expressions.

ValueDescriptionExample
global.greenhouse.organizationNameName of the Organizationmy-org
global.greenhouse.clusterNameName of the target Clustercluster-a
global.greenhouse.baseDomainBase domain of the Greenhouse installationgreenhouse.example.com
global.greenhouse.ownedByOwning Team of the Pluginteam-1
global.greenhouse.metadata.*Cluster metadata labelseu-de-1

clusterName and metadata.* are only set for Plugins targeting a Cluster, ownedBy only if the Plugin has the greenhouse.sap/owned-by label.

⚠️ global.greenhouse.clusterNames and global.greenhouse.teamNames held all Clusters and Teams of an Organization. They are no longer passed to the Helm chart, which takes effect on the next reconciliation of a Plugin, not only when it is edited. They are additionally removed from .spec.optionValues the next time the Plugin is created or updated. A PluginPreset .spec.plugin.optionValues[].expression still referencing either of them fails to evaluate and blocks the PluginPreset from rolling out its Plugins, so migrate those to global.greenhouse.clusterName and global.greenhouse.metadata.* first.

Working with Plugins

Suspending the Plugin’s reconciliation

The annotation greenhouse.sap/suspend can be added to a Plugin resource to temporarily suspend the reconciliation of the Plugin. This results in no changes on the Plugin or referenced resources being applied until the annotation is removed. This also includes upgrades of the Helm release on the target cluster. This also blocks the deletion of the Plugin resource until the annotation is removed.

Triggering reconciliation of the Plugin’s managed resources

The annotation greenhouse.sap/reconcile can be added to a Plugin resource to trigger a reconciliation of the Plugin and its managed resources. When the Plugin is deployed using FluxCD this annotation is propagated to the Flux HelmRelease resource and triggers a reconciliation of the Helm release on the target cluster. This can be useful to trigger a reconciliation even if no changes were made to the Plugin resource.

Exposed Services

The Plugin status contains .status.exposedServices which is a list of Service and Ingress resources that are annotated for exposure. In the case of Kubernetes Services they are exposed via the service-proxy. See disabling service-proxy for a Cluster for how to disable the service-proxy for a Cluster.

Next Steps