Search code examples
jsonkubernetesjqkubernetes-secrets

transforming configMapKeyRef into secretKeyRef with jq


Here is my deploy input

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "spec": {
    "replicas": 1,
    "selector": {
      "matchLabels": {
        "io.kompose.service": "item-api"
      }
    },
    "strategy": {
      "type": "Recreate"
    },
    "template": {
      "spec": {
        "containers": [
          {
            "env": [
              {
                "name": "APP_JWTSECRET",
                "valueFrom": {
                  "configMapKeyRef": {
                    "key": "APP_JWTSECRET",
                    "name": "item-api-env"
                  }
                }
              },
              {
                "name": "SPRING_DATASOURCE_BASEXML_JDBCURL",
                "valueFrom": {
                  "configMapKeyRef": {
                    "key": "SPRING_DATASOURCE_BASEXML_JDBCURL",
                    "name": "item-api-env"
                  }
                }
              }
...

For each item into env, I'd like to transform the configMapKeyRef into secretKeyRefif name contains (SECRET|PASSWORD|KEY) pattern and then replace the secretKeyRef name by the key name into lowcase.

for example:

                "name": "APP_JWTSECRET",
                "valueFrom": {
                  "configMapKeyRef": {
                    "key": "APP_JWTSECRET",
                    "name": "item-api-env"
                  }
                }
              }

would be transformed into

                "name": "APP_JWTSECRET",
                "valueFrom": {
                  "secretKeyRef": {
                    "key": "APP_JWTSECRET",
                    "name": "app-jwtsecret"
                  }
                }
              }

I tried some kind of manipulation with with_entries without any success:

jq -r '.spec.template.spec.containers[].env[]|with_entries(.key |test(PASSWORD|SECRET))'

Solution

  • Here's one way you could do it. The containers and env array are rewritten with the desired modification, or kept "as is" if the condition isn't met.

    .spec.template.spec.containers
    |= map(
        (.env
         |= map(
              if (.name|test("SECRET|PASSWORD|KEY"))
              then .valueFrom
                |= with_entries(.key="secretKeyRef"
                     |.value.name=(.value.key|ascii_downcase|gsub("_";"-"))
                   )
              else .
              end
            )
        )? // .
    )
    

    Try it on jqplay.org.