skip to Main Content

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))'

3

Answers


  1. One way to use jq would be to do below.

    .spec.template.spec.containers[].env[] |= {name} + 
    if .name | test("SECRET|PASSWORD|KEY") then 
        .valueFrom |= ( 
            with_entries(
                if .key == "configMapKeyRef" then .key = "secretKeyRef" end | 
                    .value |= {key} + {name: .key|ascii_downcase}
            )
        )
    end
    

    jqplay demo – https://jqplay.org/s/UfYQYpJIa6o

    Login or Signup to reply.
    • Navigate to the desired locations: .spec.template.spec.containers[].env[]?
    • Filter for those matching your criteria: select(.name | test("SECRET|PASSWORD|KEY"))
    • Take those results and go deeper: (…).valueFrom
    • Update it with access to .key and .value: |= with_entries(…)
    • Only if the key matches that name: select(.key == "configMapKeyRef") |= …
    • By redefining key and value: {key: "secretKeyRef", value: …}
    • The new value is based on the previous value, and assigns the lowercase key to name: .value | .name = (.key | ascii_downcase)
    (
        .spec.template.spec.containers[].env[]?
        | select(.name | test("SECRET|PASSWORD|KEY"))
    )
    
    .valueFrom |= with_entries(select(.key == "configMapKeyRef") |= {
        key: "secretKeyRef", value: (.value | .name = (.key | ascii_downcase))
    })
    
    {
      "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": {
                      "secretKeyRef": {
                        "key": "APP_JWTSECRET",
                        "name": "app_jwtsecret"
                      }
                    }
                  },
                  {
                    "name": "SPRING_DATASOURCE_BASEXML_JDBCURL",
                    "valueFrom": {
                      "configMapKeyRef": {
                        "key": "SPRING_DATASOURCE_BASEXML_JDBCURL",
                        "name": "item-api-env"
                      }
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
    

    Demo

    Note: I regarded the change from app_jwtsecret to app-jwtsecret a typo.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search