RFC 3158 - Working Examples

Gating Flux

Relates to https://github.com/fluxcd/flux2/pull/3158.
Note that all types are subject to change.

Example of a Gating mechanism to control when a GitRepository would be allowed
to pull the latest sources in order to deploy into a given environment.

On this example there will be two Gates change-freeze and bypass-signoff.
At least one of them must be opened for the release to go ahead.

Static Gates

Both Gates are created statically, but a GateKeeper will be used to manage
change-freeze's state.

The change-freeze Gate represents the time window in which a change freeze
is defined, and no releases can be deployed into the environment:

apiVersion: gating.toolkit.fluxcd.io/v1alpha1
kind: Gate
metadata:
  name: change-freeze
  namespace: flux-system
spec:
  closed: true

The bypass-signoff Gate represents manual overrides, in which management
allowed for a release to take place:

apiVersion: gating.toolkit.fluxcd.io/v1alpha1
kind: Gate
metadata:
  name: bypass-signoff
  namespace: flux-system
spec:
  closed: true

GitRepository using both gates

apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
  name: flux-system
  namespace: flux-system
spec:
  gates:
    # all (default): all gates must be open for the reconciliation to go ahead.
    # oneOf: at least one of the gates must be open for the reconciliation to go ahead.
    require: oneOf # <all|oneOf>
    refs:
    - change-freeze # gate that enforces a change freeze time window
    - bypass-signoff # gate that allows other gates to be overriden.

GateKeeper

A GateKeeper adds dynamic behavior to Gates. In this example, one GateKeeper will
be used to keep change-freeze closed two change freeze windows: Black Friday
and Xmas.

apiVersion: gating.toolkit.fluxcd.io/v1alpha1
kind: GateKeeper
metadata:
  name: change-freeze-gatekeeper
  namespace: flux-system
spec:
  gate: change-freeze
  type: cronexpression # cronjob/cronexpression?
  cronjob:
    closed:
    - '* * 20-30 11 *' # Black Friday: 20th-30th November
    - '* * 15-31 12 *' # Xmas: 15th-31st December

Override Gates

The Gate bypass-signoff is always closed. The Gate change-freeze is only
closed during the change freezes defined by change-freeze-gatekeeper.

To allow a new release during a change freeze period, users
can temporarily open
the Gate bypass-signoff, force a reconciliation and then close it again.

flux gate open bypass-signoff "Patching a CVE: Signed off by Bob the builder"
flux reconcile flux-system
flux gate close bypass-signoff

As a result, GitRepository will fetch the latest version of its source and make
it available to the other Flux controllers, which will then apply it to the cluster.

The message used on the command flux gate open will appear on Gate Controller's
logs, highlighting the change of state:

{
    "level":"info",
    "ts":"2022-12-21T15:59:44.928Z",
    "msg":"opening gate: 'Patching a CVE: Signed off by Bob the builder'",
    "closed":"false",
    "controller":"gatecontroller",
    "controllerGroup":"gating.toolkit.fluxcd.io",
    "controllerKind":"Gate",
    "Gate":{
        "namespace":"flux-system","name":"bypass-signoff"
    },
    "namespace":"flux-system",
    "name":"bypass-signoff"
}

Source Controller will also output the considered gates, their status:

{
    "level":"info",
    "ts":"2022-12-21T16:02:54.971Z",
    "msg":"artifact up-to-date with remote revision: 'HEAD/0ee437c33f499e2f588f60e6a92a547f6d5845f8'",
    "gates":{
        "require": "oneOf",
        "status": [
            {"gate": "change-freeze", "closed": "true"},
            {"gate": "bypass-signoff", "closed": "false"}
        ]
    },
    "controller":"gitrepository",
        "controllerGroup":"source.toolkit.fluxcd.io",
    "controllerKind":"GitRepository",
    "GitRepository":{
        "name":"flux-system",
        "namespace":"flux-system"
    },
    "namespace":"flux-system",
    "name":"flux-system"
}

Follow-up

Auditing

Further discussions are needed around log and auditing, to ensure the correct level
of assurance and cross-references amongst the different states that may lead to a
reconciliation to pass through gates.

Edge Cases

The gating mechanism should not yield corrupt state, however that could happen when
multiple sources depend on each other, and a Gate only allows one to be reconciled.
Therefore, it is vital that when gating is in place, users take special care around
not creating dependencies across Flux Sources that have different gating rules.

Select a repo