2017-09-12 3 views
0

J'ai un tableau d'objets de différents types qui se réfèrent les uns aux autres avec des UUID (un fichier terraform.tfstate). Je voudrais sélectionner une valeur d'un tel objet basé sur l'apparition d'une valeur différente dans un autre objet, où les deux objets sont liés par l'un de ces UUID.jq: recherche par valeur à partir d'un autre élément de tableau

A titre d'exemple, je peux le faire:

$ jq '.modules[].resources[] 
| select(.type == "openstack_compute_instance_v2" and 
     .primary.attributes.name == "jumpbox").primary.id' terraform.tfstate 
"5edfe2bf-94df-49d5-8118-3e91fb52946b" 
$ jq '.modules[].resources[] 
| select(.type =="openstack_compute_floatingip_associate_v2" and 
     .primary.attributes.instance_id == "5edfe2bf-94df-49d5-8118-3e91fb52946b").primary.attributes.floating_ip' terraform.tfstate 
"10.120.241.21" 

me donner l'adresse IP flottante externe de la machine virtuelle « de JumpBox » basée sur son nom.

Je voudrais faire que tout un appel de jq. Est-ce possible?

Répondre

0

Ce serait plus facile de répondre si vous avez fourni des données plus d'échantillons, mais travaillant à rebours à partir des commandes (avec quelques reformatage)

$ jq ' 
     .modules[].resources[] 
    | select(.type == "openstack_compute_instance_v2" and .primary.attributes.name == "jumpbox") 
    | .primary.id 
' terraform.tfstate 
"5edfe2bf-94df-49d5-8118-3e91fb52946b" 

$ jq ' 
     .modules[].resources[] 
    | select(.type =="openstack_compute_floatingip_associate_v2" and .primary.attributes.instance_id == "5edfe2bf-94df-49d5-8118-3e91fb52946b") 
    | .primary.attributes.floating_ip 
' terraform.tfstate 
"10.120.241.21" 

nous pouvons vous déduire avez des données qui ressemble à

{ 
    "modules": [ 
    { 
     "resources": [ 
     { 
      "type": "openstack_compute_instance_v2", 
      "primary": { 
      "id": "5edfe2bf-94df-49d5-8118-3e91fb52946b", 
      "attributes": { 
       "name": "jumpbox" 
      } 
      } 
     }, 
     { 
      "type": "openstack_compute_floatingip_associate_v2", 
      "primary": { 
      "attributes": { 
       "instance_id": "5edfe2bf-94df-49d5-8118-3e91fb52946b", 
       "floating_ip": "10.120.241.21" 
      } 
      } 
     } 
     ] 
    } 
    ] 
} 

Le filtre suivant illustre une solution utilisant functions, variables et parenthesis():

def get_primary_id($name): 
    select(.type == "openstack_compute_instance_v2" 
     and .primary.attributes.name == $name) 
    | .primary.id 
; 
def get_floating_ip($id): 
    select(.type =="openstack_compute_floatingip_associate_v2" 
     and .primary.attributes.instance_id == $id) 
    | .primary.attributes.floating_ip 
; 
    .modules[] 
| (.resources[] | get_primary_id("jumpbox")) as $id 
| (.resources[] | get_floating_ip($id)  ) as $fip 
| ($id, $fip) 

si ce filtre est en filter.jq et data.json contient les données d'échantillons ci-dessus puis

$ jq -M -f filter.jq data.json 

produit la sortie:

"5edfe2bf-94df-49d5-8118-3e91fb52946b" 
"10.120.241.21" 
+0

Merci beaucoup! Cela a du sens. – dhaines