operator-framework / ansible-operator-plugins

Experimental extraction/refactoring of the Operator SDK's ansible operator plugin
Apache License 2.0
9 stars 20 forks source link

replace all ${VAR} references with env var values in watches yaml #45

Closed jmazzitelli closed 9 months ago

jmazzitelli commented 9 months ago

Description of the change:

For any ${VAR} references in the watches yaml, this replaces those env vars with their values before the watches yaml is processed. If there is no ${VAR} defined, the "${VAR}" remains as-is in the watches yaml.

Motivation for the change:

There are times when a user wants to customize what an operator will watch. Right now, watches.yaml is fixed and cannot be customized or configured. This feature at least allows the operator to be somewhat configurable by passing in env vars in the operator's subscription or directly in its Deployment.

For one such example, I may have an operator that can be deployed on OpenShift and non-OpenShift environments. I therefore could have two different sets of playbooks in my operator container - one for OpenShift and one for non-OpenShift. I could define a set of ${WATCH_PLAYBOOK_XYZ} env vars and point to cluster-specific playbooks in the watches.yaml:

- version: v1
  group: bar.example.com
  kind: Bar
  playbook: ${WATCH_PLAYBOOK_BAR}

When deployed on OpenShift, my OLM CSV could define that env var to "playbook-bar-openshift.yml" and on non-OpenShift, I have its OLM CSV define the env var to "playbook-bar-kubernetes.yml".

Another example. I want my operator to watch Bar objects, but I do NOT want the operator to run my playbook reconciliation on every Bar in the cluster - I only want to run a reconciliation when a Bar with a specific selector. But! (and here's the important part), this selector can be different depending on what the admin wants (the admin being the person who installed the operator). With this PR, this can be accomplished like this:

watches.yaml:

- version: v1
  group: bar.example.com
  kind: Bar
  playbook: playbook.yml
  selector:
    matchLabels:
      ${SPECIAL_BAR_NAME}: ${SPECIAL_BAR_VAL}

Operator Subscription:

kind: Subscription
metadata:
  name: my-operator
spec:
  package: my-operator
  channel: stable
  config:
    env:
    - name: SPECIAL_BAR_NAME
      value: "special-bar-name"
    - name: SPECIAL_BAR_VAL
      value: "special-bar-value"
jmazzitelli commented 9 months ago

Addressed all the suggestions.

As for release notes, I would say we need to mention that odd edge case where $FOO (without braces) will be replaced with ${FOO} (with braces) if FOO env var is not set in the operator. So the release notes should say something like:

Environment variable references of the form `$ENV` or `${ENV}` found in
watches.yaml will be replaced with the values of those environment variables
if they are set in the operator. If the environment variable is not set in the operator,
the watches.yaml will keep the string `${ENV}` as-is. Take note that if your
watches.yaml has a string in the form `$FOO` (without braces) and you do
not have an environment variable named FOO set in the operator, then the
watches.yaml will effectively replace `$FOO` with the string `${FOO}` (i.e. with
braces surrounding the name).
everettraven commented 9 months ago

We currently have autogenerated release notes in this repository, but once the changes are pulled into the Operator-SDK we can provide a more detailed release note entry. Thanks for the contribution @jmazzitelli !