from the json below I need to gather the interface name and the unit name value in a loop.
This is partial output of my json:
{
"configuration": {
"#": {
"junos:changed-localtime": "2021-04-30 12:47:05 PDT",
"junos:changed-seconds": "1619812025",
"xmlns": "http://xml.juniper.net/xnm/1.1/xnm"
},
"interfaces": {
"interface": [
{
"name": "irb",
"unit": [
{
"family": {
"inet": {
"address": [
{
"name": "100.111.10.4/24"
}
],
"mtu": 9100
}
},
"name": 4010
},
{
"family": {
"inet": {
"address": [
{
"name": "100.127.9.2/31"
}
]
}
},
"name": 4093
}
]
},
{
"name": "lo0",
"unit": [
{
"family": {
"inet": {
"address": [
{
"name": "100.127.0.32/32"
}
],
}
},
"name": 0
}
]
}
]
}
}
}
The playbook I'm using is below:
- name: Print response
debug:
msg: "{{item.name}}.{{item|json_query('unit[*].name')}}"
loop: "{{ test.parsed_output.configuration.interfaces.interface}}"
ignore_errors: yes
The problem that I'm having is this:
"msg": "lo0.[0]"
"msg": "irb.[4010, 4093]"
What I want to get is:
"msg": "lo0.0"
"msg": "irb.4010"
"msg": "irb.4093"
Same outside name with each unit.name, but I don't know how to do this.
Thanks.
Iterate with_subelements, e.g.
- debug:
msg: "{{ item.0.name }} {{ item.1.name }}"
with_subelements:
- "{{ test.parsed_output.configuration.interfaces.interface }}"
- unit
gives
msg: irb 4010
msg: irb 4093
msg: lo0 0
I have this following playbook, which gather facts in google cloud and filter instance names we want.
tasks:
- name: get tags
delegate_to: localhost
gcp_compute_instance_info:
auth_kind: serviceaccount
service_account_file: "xxx"
zone: "xxx"
filters:
- "name:{{ names }}*"
project: "{{ project }}"
register: ilist
- name: Display output
debug: var=ilist['items']
- set_fact:
instances: "{{ instances|default([]) + [ item.name ] }}"
loop: "{{ ilist['items']}}"
when: item.name is regex(".*"+tag+"-[a-z0-9]{4}$")
- debug:
var: instances
I'm getting following error in the loop task
Invalid data passed to 'loop', it requires a list, got this instead:
<built-in method items of dict object at 0x7fe0f370aa70>. Hint: If you
passed a list/dict of just one element, try adding wantlist=True to
your lookup invocation or use q/query instead of lookup.
what I'm doing wrong here? thanks
and this is the output of ilist
{
"changed":false,
"failed":false,
"resources":[
{
"canIpForward":false,
"cpuPlatform":"Intel Haswell",
"creationTimestamp":"2020-09-14T04:05:58.316-07:00",
"deletionProtection":false,
"disks":[
{
"autoDelete":true,
"boot":true,
"deviceName":"persistent-disk-0",
"diskSizeGb":"10",
"guestOsFeatures":[
{
"type":"VIRTIO_SCSI_MULTIQUEUE"
}
],
"index":0,
"interface":"SCSI",
"kind":"compute#attachedDisk",
"licenses":[
"xxxx"
],
"mode":"READ_WRITE",
"source":"xxxx",
"type":"PERSISTENT"
}
],
"fingerprint":"3yOdLl6Hp8g=",
"id":"3503717950118097018",
"kind":"compute#instance",
"labelFingerprint":"IP52FxBvsW0=",
"labels":{
"block":"internal",
"component":"dev",
"function":"internal"
},
"lastStartTimestamp":"2020-09-14T04:06:26.016-07:00",
"machineType":"xxxx",
"metadata":{
"fingerprint":"sTp1wPeotCo=",
"items":[
{
"key":"instance-template",
"value":"xxxx
},
{
"key":"created-by",
"value":"xxxx"
}
],
"kind":"compute#metadata"
},
"name":"test-vm",
"networkInterfaces":[
{
"fingerprint":"ae26IqBpxVo=",
"kind":"compute#networkInterface",
"name":"nic0",
"network":"xxxx",
"networkIP":"xxxx"
}
],
"scheduling":{
"automaticRestart":true,
"onHostMaintenance":"MIGRATE",
"preemptible":false
},
"selfLink":"xxxxx",
"serviceAccounts":[
{
"email":"xxxx",
"scopes":[
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
"https://www.googleapis.com/auth/pubsub",
"https://www.googleapis.com/auth/service.management.readonly",
"https://www.googleapis.com/auth/servicecontrol",
"https://www.googleapis.com/auth/trace.append"
]
}
],
"startRestricted":false,
"status":"RUNNING",
"tags":{
"fingerprint":"Oyf1u-BGqNA=",
"items":[
"no-ip-b"
]
},
"zone":"xxxx"
},
{
"canIpForward":false,
"cpuPlatform":"Intel Haswell",
"creationTimestamp":"2020-10-15T06:59:52.505-07:00",
"deletionProtection":false,
"disks":[
{
"autoDelete":true,
"boot":true,
"deviceName":"persistent-disk-0",
"diskSizeGb":"10",
"guestOsFeatures":[
{
"type":"VIRTIO_SCSI_MULTIQUEUE"
}
],
"index":0,
"interface":"SCSI",
"kind":"compute#attachedDisk",
"licenses":[
"xxxx"
],
"mode":"READ_WRITE",
"source":"xxxxx",
"type":"PERSISTENT"
}
],
"fingerprint":"-E0UpLFggow=",
"id":"5900118287465179960",
"kind":"compute#instance",
"labelFingerprint":"IP52FxBvsW0=",
"labels":{
"block":"internal",
"component":"dev",
"function":"internal"
},
"lastStartTimestamp":"2020-10-15T07:00:37.895-07:00",
"machineType":"xxxxx",
"metadata":{
"fingerprint":"05Oj3Bq6zb4=",
"items":[
{
"key":"instance-template",
"value":"xxxx"
},
{
"key":"created-by",
"value":"xxxx"
}
],
"kind":"compute#metadata"
},
"name":"test-vm",
"networkInterfaces":[
{
"fingerprint":"H24HFGkCFNg=",
"kind":"compute#networkInterface",
"name":"nic0",
"network":"xxxx",
"networkIP":"xxxx"
}
],
"scheduling":{
"automaticRestart":true,
"onHostMaintenance":"MIGRATE",
"preemptible":false
},
"selfLink":"xxxx",
"serviceAccounts":[
{
"email":"xxxx",
"scopes":[
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
"https://www.googleapis.com/auth/pubsub",
"https://www.googleapis.com/auth/service.management.readonly",
"https://www.googleapis.com/auth/servicecontrol",
"https://www.googleapis.com/auth/trace.append"
]
}
],
"startRestricted":false,
"status":"RUNNING",
"tags":{
"fingerprint":"Oyf1u-BGqNA=",
"items":[
"no-ip-b"
]
},
"zone":"xxxx"
}
]
}
You can try with the query function
loop: {{ query('dict', ilist.items) }}
What the syntax would be to pull the "members" value out of this JSON where the name value is "PROD_poolgroup".
I think it should be [?config.name == "PROD_poolgroup"].config.members
I've tried other variations without success also.
"all_members": [
{
"config": {
"_last_modified": "1594434546441212",
"cloud_ref": "https://192.168.86.20/api/cloud/cloud-5a7a41cb-156e-43f4-ad28-031b27dac813",
"implicit_priority_labels": false,
"members": [{
"pool_ref": "https://192.168.86.20/api/pool/pool-cb436bba-000a-4d72-8ff5-7d6cdf1ac2fa",
"ratio": 1
}],
"min_servers": 0,
"name": "PROD_poolgroup",
"tenant_ref": "https://192.168.86.20/api/tenant/admin",
"url": "https://192.168.86.20/api/poolgroup/poolgroup-e08933c0-d142-4787-9990-45f94dfc6b89",
"uuid": "poolgroup-e08933c0-d142-4787-9990-45f94dfc6b89"
},
"uuid": "poolgroup-e08933c0-d142-4787-9990-45f94dfc6b89"},
{
"config": {
"_last_modified": "1594404797173635",
"cloud_ref": "https://192.168.86.20/api/cloud/cloud-5a7a41cb-156e-43f4-ad28-031b27dac813",
"implicit_priority_labels": false,
"members": [{
"pool_ref": "https://192.168.86.20/api/pool/pool-f98ed65c-00b2-4638-83df-8b89df79deec",
"ratio": 1
}],
"min_servers": 0,
"name": "QA_poolgroup",
"tenant_ref": "https://192.168.86.20/api/tenant/admin",
"url": "https://192.168.86.20/api/poolgroup/poolgroup-0b19b515-9ae6-41ef-9111-00e61470e615",
"uuid": "poolgroup-0b19b515-9ae6-41ef-9111-00e61470e615"},
"uuid": "poolgroup-0b19b515-9ae6-41ef-9111-00e61470e615"
}
]
Use either single quote or backquote for using literal expression to compare value of name. Below are two working examples:
Using single quote:
- debug:
msg: "{{ all_members | json_query(query) | list }}"
vars:
query: "[?config.name == 'PROD_poolgroup'].config.members"
Using literal expression:
- debug:
msg: "{{ all_members | json_query(query) | list }}"
vars:
query: '[?config.name == `"PROD_poolgroup"`].config.members'
I am getting the below dictionary from calling python library called from Ansible.
{
"replication_detail": [
{
"name": "xxx.203.server:11111",
"self": true,
"state": 1,
"stateStr": "PRIMARY",
"syncSourceHost": "",
"syncingTo": ""
},
{
"name": "xxx.204.server:11111",
"state": 2,
"stateStr": "SECONDARY",
"syncSourceHost": "xxx.203,server:11111",
"syncingTo": "xxx.203,server:11111"
},
{
"name": "xxx.205,server:11111"
"state": 8,
"stateStr": "(not reachable/healthy)",
"syncSourceHost": "",
"syncingTo": ""
}
]
}
I wanted to have a filter which look into another element which is "StateStr" should be in ["PRIMARY","SECONDARY"] and return the "name"
I tried match or equalto but they all take only one value. Is there other any function which can look into multiple search values.
I am trying to get the data using map in single line rather than with_loop.
the code like
"select name from replication_detail where sateStr in (PRIMARY, SECONDARY)"
replication_detail| stateStr in (PRIMARY, SECONDARY)) | map(attribute="name"|list
You can use the selectattr filter to filter a list of dictionaries by an attribute. For example, if the data in your question is contained in a variable named data, then the following task:
- debug:
msg: "name: {{ item }}"
loop: "{{ data.replication_detail|selectattr('stateStr', 'match', 'SECONDARY|PRIMARY')|map(attribute='name')|list }}"
Would output:
TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => (item=xxx.203.server:11111) => {
"msg": "name: xxx.203.server:11111"
}
ok: [localhost] => (item=xxx.204.server:11111) => {
"msg": "name: xxx.204.server:11111"
}
Would output:
I'm trying to parse json in ansible and I got the value I need but the output is an array. How can I get just the value?
Example json:
{
"Version": "2015-08-13",
"Accounts": [{
"AccountName": "account1",
"Regions": [{
"RegionName": "region1",
"RegionId": "region1",
"RegionDetails": [{
"id": "id1",
"version": "v1"
}, {
"id": "id2",
"version": "v2"
}]
}]
}, {
"AccountName": "account2",
"Regions": [{
"RegionName": "region1",
"RegionId": "region1",
"RegionDetails": [{
"id": "id1",
"version": "v1"
}, {
"id": "id2",
"version": "v2"
}]
}]
}]
}
Ansible playbook example:
- name: Set Global Vars
hosts: localhost
tasks:
- name: print json file
debug:
msg: "{{ (lookup('file','./example.json') | from_json) | json_query(query) }}"
vars:
query: "Accounts[?AccountName=='account1'][Regions[?RegionName=='region1'].RegionId]"
register: region_id
Ansible output:
TASK [print json file] *********************************************************
ok: [localhost] => {
"msg": [
[
[
"region1"
]
]
]
}
As you can see the value 'region1' is still nested. How can I get just the value out?
Thanks!
Your original data has nested lists: Accounts is a list, each account contains Regions list.
With your JMESPath query you filter lists by some criteria, but result is still a list, because your data may have more then one account with name AccountName=='account1'.
If you are interested only in first found account and first found region of that account, you can modify query as follows:
Accounts[?AccountName=='account1'] | [0].Regions[?RegionName=='region1'] | [0].RegionId