bashshellyamlkustomize

How can I inject content from one YAML file into a nested position in another YAML file using yq?


I have a file which i read using yq and I have to use the config in a kustomization template as yaml format. So, the way I am reading the config from a file is below:

istio_ns_scoping_labels=$(yq -r '.cluster.config.istio_ns_scoping_labels' "$config_file" 2>/dev/null)
echo "$istio_ns_scoping_labels"
#istio_ns_scoping_labels
    [
  {
    "istio-discovery": "enabled"
  },
  {
    "kubernetes.io/metadata.name": "keycloak-idc-identity-broker"
  },
  {
    "kubernetes.io/metadata.name": "keycloak-idc-identity-broker-2"
  },
  {
    "kubernetes.io/metadata.name": "keycloak-idc-identity-broke-3"
  }
]

Now I want to format this as yaml so that I can substitute this into a yaml template as shown below

      discoverySelectors:
        - matchLabels:
            istio-discovery: enabled
        - matchLabels:
            kubernetes.io/metadata.name: keycloak-idc-identity-broker
        - matchLabels:
            kubernetes.io/metadata.name: keycloak-idc-identity-broker-2
        - matchLabels:
            kubernetes.io/metadata.name: keycloak-idc-identity-broker-3

I have to make sure that $labels is formatted properly as yaml format because I use envsubst to substitute the block as it is inside the template like below

    meshConfig:
      accessLogFile: /dev/stdout
      discoverySelectors:
        - matchLabels:
          ${MATCH_LABELS_BLOCK}

I am using yq to read the config of labels from a config.yml file as

config_file=cluster.yml
istio_ns_scoping_labels=$(yq -r '.cluster.config.istio_ns_scoping_labels' "$config_file" 2>/dev/null)
#cluster.yml
cluster:
  config:
    istio_ns_scoping_labels: 
      istio-discovery: enabled
      kubernetes.io/metadata.name: keycloak-idc-identity-broker

Solution

  • Given the jq-wrapper version of yq (which is the one you're working with),

    yq -Y --argjson istio_ns_scoping_labels "$istio_ns_scoping_labels" '
      .spec.values.meshConfig.discoverySelectors = (
        $istio_ns_scoping_labels | map({matchLabels: .})
      )' - <cluster.yml
    

    ...properly emits output containing something like:

    spec:
      values:
        meshConfig:
          discoverySelectors:
            - matchLabels:
                istio-discovery: enabled
            - matchLabels:
                kubernetes.io/metadata.name: keycloak-idc-identity-broker
            - matchLabels:
                kubernetes.io/metadata.name: keycloak-idc-identity-broker-2
            - matchLabels:
                kubernetes.io/metadata.name: keycloak-idc-identity-broke-3