0

Consider this current namespace config in JSON format:

$ kubectl get configmap config -n metallb-system -o json
{
    "apiVersion": "v1",
    "data": {
        "config": "address-pools:\n- name: default\n  protocol: layer2\n  addresses:\n  - 192.168.0.105-192.168.0.105\n  - 192.168.0.110-192.168.0.111\n"
    },
    "kind": "ConfigMap",
    "metadata": {
        "annotations": {
            "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"data\":{\"config\":\"address-pools:\\n- name: default\\n  protocol: layer2\\n  addresses:\\n  - 192.168.0.105-192.168.0.105\\n  - 192.168.0.110-192.168.0.111\\n\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"config\",\"namespace\":\"metallb-system\"}}\n"
        },
        "creationTimestamp": "2020-07-10T08:26:21Z",
        "managedFields": [
            {
                "apiVersion": "v1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:data": {
                        ".": {},
                        "f:config": {}
                    },
                    "f:metadata": {
                        "f:annotations": {
                            ".": {},
                            "f:kubectl.kubernetes.io/last-applied-configuration": {}
                        }
                    }
                },
                "manager": "kubectl",
                "operation": "Update",
                "time": "2020-07-10T08:26:21Z"
            }
        ],
        "name": "config",
        "namespace": "metallb-system",
        "resourceVersion": "2086",
        "selfLink": "/api/v1/namespaces/metallb-system/configmaps/config",
        "uid": "c2cfd2d2-866c-466e-aa2a-f3f7ef4837ed"
    }
}

I am interested only in the address pools that are configured. As per the kubectl cheat sheet, I can do something like this to fetch the required address range:

$ kubectl get configmap config -n metallb-system -o jsonpath='{.data.config}'
address-pools:
- name: default
  protocol: layer2
  addresses:
  - 192.168.0.105-192.168.0.105
  - 192.168.0.110-192.168.0.111

However, my requirement is to use only a JSON parser throughout, and I cannot parse the above output since it is in YAML instead.

Since I'm not willing to accomodate the above yaml output for direct use ( or via format conversion operation ), is there any suitable way I can obtain the address range from the kubectl interface in a JSON format instead?

1
  • 1
    The content of the ConfigMap (the "data.address-pools") is yaml formated. For the kubectl it's ... well, data :), so it doesn't have support to re-formating it. It can be anything. I don't think you can reformat it without any external tool... Commented Jul 10, 2020 at 9:20

1 Answer 1

2

You need yq alongside kubectl ...

After inspecting your configmap, I understood the structure when I convert it to YAML :

---
apiVersion: v1
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.0.105-192.168.0.105
      - 192.168.0.110-192.168.0.111
kind: ConfigMap
metadata:
 name: config

And you can see clearly that .data.config is a multi-line string.. but it can be converted also to YAML.

  • parse the multi-line string with kubectl
  • treat this string as yaml using yq.

So This is what you are looking for :

# all addresses
kubectl -n metallb-system get cm config -o 'go-template={{index .data "config" }}' | \
    yq -r '.["address-pools"][0].addresses'

# first address only
kubectl -n metallb-system get cm config -o 'go-template={{index .data "config" }}' | \
    yq -r '.["address-pools"][0].addresses[0]'

# second address only
kubectl -n metallb-system get cm config -o 'go-template={{index .data "config" }}' | \
    yq -r '.["address-pools"][0].addresses[1]'

# so on ...
Sign up to request clarification or add additional context in comments.

2 Comments

I'm well aware it's in YAML format. In fact, I can use the -o yaml to achieve the same purpose. My requirement though is to parse it only as JSON content instead.
same concept.. but use jqinstead yq

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.