vmware-archive / operator-builder

A Kubebuilder plugin to accelerate the development of Kubernetes operators
MIT License
41 stars 6 forks source link

Add prefix/suffix field to workload markers #6

Open scottd018 opened 3 years ago

scottd018 commented 3 years ago

One common pattern that we see is needing the ability to inject a value, but add a prefix or suffix:

Example 1 Prepend (cert-manager - truncated):

---
---
# Source: cert-manager/templates/webhook-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cert-manager-webhook #+workload:certManagerWebhookResourceName:default="cert-manager-webhook":type=string
  namespace: security-system #+workload:namespace:default="security-system":type=string
...
---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
  name: cert-manager-webhook #+workload:certManagerWebhookResourceName:default="cert-manager-webhook":type=string
  labels:
    app.kubernetes.io/name: webhook
    app.kubernetes.io/name: webhook
    app.kubernetes.io/instance: cert-manager #+workload:certManagerResourceName:default="cert-manager":type=string
    app.kubernetes.io/component: webhook
  annotations:
    cert-manager.io/inject-ca-from-secret: security-system/cert-manager-webhook-ca # <<<<<< THIS
...

In this example, my namespace is configurable, however I need to append a value to something that is configurable (e.g. security-system + /cert-manager-webhook-ca, where security-system is configured by the marker certManagerWebhookResourceName).

Example 2 Append (metallb) - truncated:

---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app.kubernetes.io/name: metallb #+workload:resourceName:default="metallb":type=string
    component: metallb-speaker #+workload:speakerResourceName:default="metallb-speaker":type=string
  name: metallb-speaker #+workload:speakerResourceName:default="metallb-speaker":type=string
  namespace: cnpo-service-routing-system #+workload:namespace:default="cnpo-service-routing-system":type=string
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: metallb #+workload:resourceName:default="metallb":type=string
      component: metallb-speaker #+workload:speakerResourceName:default="metallb-speaker":type=string
  template:
    metadata:
      annotations:
        prometheus.io/port: "7472"
        prometheus.io/scrape: "true"
      labels:
        app.kubernetes.io/name: metallb #+workload:resourceName:default="metallb":type=string
        component: metallb-speaker #+workload:speakerResourceName:default="metallb-speaker":type=string
    spec:
      containers:
        - args:
            - --port=7472
            - --config=$(METALLB_CONFIG_NAME)
          env:
            - name: METALLB_NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: METALLB_HOST
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: METALLB_ML_BIND_ADDR
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            # needed when another software is also using memberlist / port 7946
            # when changing this default you also need to update the container ports definition
            # and the PodSecurityPolicy hostPorts definition
            #- name: METALLB_ML_BIND_PORT
            #  value: "7946"
            - name: METALLB_ML_LABELS
              value: app=metallb,component=speaker # <<<<<<THIS
...

In this example, my label is configurable, however I need to prepend a value to something that is configurable (e.g. app= + metallb, where metallb is configured by the marker resourceName).

Proposal:

  1. add prefix and suffix fields to the markers.

Prefix Example Input:

            - name: METALLB_ML_LABELS
              value: app=metallb,component=speaker #+workload:resourceName:default="metallb":type=string:prefix=app=

Prefix Example Output (pseudo-code, showing the variable injection):

app=${resourceName}

Suffix Example Input:

  annotations:
    cert-manager.io/inject-ca-from-secret: security-system/cert-manager-webhook-ca #+workload:namespace:default="security-system":type=string:suffix=/cert-manager-webhook-ca

Suffix Example Output (pseudo-code, showing the variable injection):

  annotations:
    cert-manager.io/inject-ca-from-secret: ${namespace}/cert-manager-webhook-ca 
lander2k2 commented 3 years ago

Yeah - I can see how this will be essential in many cases. I'm wondering if we can just use go string formatting to provide prefix, suffix and other options.

scottd018 commented 3 years ago

@lander2k2 yeah, i think as simple as possible is probably better. The goal being to avoid a complete turn towards templating and provide simple use cases only.

JefeDavis commented 3 years ago

suggestion: we could do something like:

# +operator-builder:field:name=test,type=string,replace=testvalue, replaceWith="$0-dev"
option: testvalue