Sammitch
Sammitch

Reputation: 32272

jq filter on subkey existence

I've got some automations for setting up a clustered service [Galera] that uses etcd for service location. I've then got a load balancer that reads this information in order to initialize and run.

The trouble is that while testing autohealing I noticed that there are empty etcd 'directories' where the old nodes used to be, aka lacking a nodes subkey. This then causes trouble in the load balancer config.

Below is the result of curl http://etcd/... | jq .node.nodes[] which illustrates the problem.

How do I filter out the sub-objects that do not have a nodes key, eg: 172.17.0.16?

{
  "key": "/galera/mariadb_galera/172.17.0.8",
  "dir": true,
  "nodes": [
    {
      "key": "/galera/mariadb_galera/172.17.0.8/ipaddress",
      "value": "172.17.0.8",
      "modifiedIndex": 9,
      "createdIndex": 9
    },
    {
      "key": "/galera/mariadb_galera/172.17.0.8/wsrep_local_state_comment",
      "value": "Synced",
      "expiration": "2018-10-17T21:24:48.94524993Z",
      "ttl": 2,
      "modifiedIndex": 52905,
      "createdIndex": 52905
    },
    {
      "key": "/galera/mariadb_galera/172.17.0.8/seqno",
      "value": "1367",
      "expiration": "2018-10-17T21:24:49.213778533Z",
      "ttl": 2,
      "modifiedIndex": 52907,
      "createdIndex": 52907
    }
  ],
  "modifiedIndex": 9,
  "createdIndex": 9
}
{
  "key": "/galera/mariadb_galera/172.17.0.16",
  "dir": true,
  "modifiedIndex": 48,
  "createdIndex": 48
}
{
  "key": "/galera/mariadb_galera/172.17.0.17",
  "dir": true,
  "modifiedIndex": 111,
  "createdIndex": 111
}
{
  "key": "/galera/mariadb_galera/172.17.0.11",
  "dir": true,
  "nodes": [
    {
      "key": "/galera/mariadb_galera/172.17.0.11/wsrep_local_state_comment",
      "value": "Synced",
      "expiration": "2018-10-17T21:24:55.990291814Z",
      "ttl": 9,
      "modifiedIndex": 52909,
      "createdIndex": 52909
    },
    {
      "key": "/galera/mariadb_galera/172.17.0.11/seqno",
      "value": "1367",
      "expiration": "2018-10-17T21:24:56.113268568Z",
      "ttl": 9,
      "modifiedIndex": 52910,
      "createdIndex": 52910
    }
  ],
  "modifiedIndex": 50749,
  "createdIndex": 50749
}
{
  "key": "/galera/mariadb_galera/172.17.0.14",
  "dir": true,
  "nodes": [
    {
      "key": "/galera/mariadb_galera/172.17.0.14/wsrep_local_state_comment",
      "value": "Synced",
      "expiration": "2018-10-17T21:24:49.029444262Z",
      "ttl": 2,
      "modifiedIndex": 52906,
      "createdIndex": 52906
    },
    {
      "key": "/galera/mariadb_galera/172.17.0.14/seqno",
      "value": "1367",
      "expiration": "2018-10-17T21:24:49.358067474Z",
      "ttl": 2,
      "modifiedIndex": 52908,
      "createdIndex": 52908
    }
  ],
  "modifiedIndex": 52076,
  "createdIndex": 52076
}

Normally I would use jq .node.nodes[].key and the output would be as follows, representing live nodes:

"/galera/mariadb_galera/172.17.0.8"
"/galera/mariadb_galera/172.17.0.11"
"/galera/mariadb_galera/172.17.0.14"

But without filtering out the empty nodes it is this, which includes nodes that no longer exist:

"/galera/mariadb_galera/172.17.0.8"
"/galera/mariadb_galera/172.17.0.16"
"/galera/mariadb_galera/172.17.0.17"
"/galera/mariadb_galera/172.17.0.11"
"/galera/mariadb_galera/172.17.0.14"

Upvotes: 1

Views: 1063

Answers (1)

Jeff Mercado
Jeff Mercado

Reputation: 134491

Your original doesn't do any filtering, add it:

.node.nodes[] | select(.nodes != null).key

Upvotes: 3

Related Questions