Search code examples
kubernetesformattingkubectljsonpath

kubectl jsonpath query and output multiple object values


Below is my output of kubectl get deploy --all-namespaces:

{
    "apiVersion": "v1",
    "items": [
        {
            "apiVersion": "apps/v1",
            "kind": "Deployment",
            "metadata": {
                "annotations": {
                    "downscaler/uptime": "Mon-Fri 07:00-23:59 Australia/Sydney",
                "name": "actiontest-v2.0.9",
                "namespace": "actiontest",
            },
            "spec": {
        ......
        ......
        },
        {
            "apiVersion": "apps/v1",
            "kind": "Deployment",
            "metadata": {
                "annotations": {
                    "downscaler/uptime": "Mon-Fri 07:00-21:00 Australia/Sydney",
                "name": "anotherapp-v0.1.10",
                "namespace": "anotherapp",
            },
            "spec": {
        ......
        ......
        }
}

I need to find the name of the deployment and its namespace if the annotation "downscaler/uptime" matches the value "Mon-Fri 07:00-21:00 Australia/Sydney". I am expecting an output like below:

deployment_name,namespace

If I am running below query against a single deployment, I get the required output.

#kubectl get deploy -n anotherapp -o jsonpath='{range .[*]}{.items[?(@.metadata.annotations.downscaler/uptime=="Mon-Fri 07:00-21:00 Australia/Sydney")].metadata.name}{","}{.items[?(@.metadata.annotations.downscaler/uptime=="Mon-Fri 07:00-21:00 Australia/Sydney")].metadata.namespace}{"\n"}'

anotherapp-v0.1.10,anotherapp

But when I run it against all namespaces, I am getting an output like below:

#kubectl get deploy --all-namespaces -o jsonpath='{range .[*]}{.items[?(@.metadata.annotations.downscaler/uptime=="Mon-Fri 07:00-21:00 Australia/Sydney")].metadata.name}{","}{.items[?(@.metadata.annotations.downscaler/uptime=="Mon-Fri 07:00-21:00 Australia/Sydney")].metadata.namespace}{"\n"}'


actiontest-v2.0.9 anotherapp-v0.1.10, actiontest anotherapp

Solution

  • This is quite short answer, however you can use this option:

    kubectl get deploy --all-namespaces -o jsonpath='{range .items[?(.metadata.annotations.downscaler/uptime=="Mon-Fri 07:00-21:00 Australia/Sydney")]}{.metadata.name}{"\t"}{.metadata.namespace}{"\n"}'
    

    What I changed is logic how to work with data:

    First thing what happens is getting into range list of elements we need to work on, not everything. I used filter expression - see Jsonpath notation - syntax elements.

    And once we have already filtered entities in the list, we can easily retrieve other fields we need.