How to access information in ansible yum list result? - ansible

could you help me accessing some information in the result of the yum list module?
This is my task:
- name: check if lgto networker is installed
yum:
list: "{{ (item | basename | splitext)[0] }}"
state: present
register: yum_result
with_fileglob:
- "lgt*.rpm"
When i debug my registered var yum_result i got this output:
ok: [XX.XX.XX.XXX] => {
"yum_result": [
{
"_ansible_ignore_errors": null,
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"allow_downgrade": false,
"conf_file": null,
"disable_gpg_check": false,
"disablerepo": null,
"enablerepo": null,
"exclude": null,
"install_repoquery": true,
"installroot": "/",
"list": "lgtoclnt-8.2.4.9-1.x86_64",
"name": null,
"security": false,
"skip_broken": false,
"state": "installed",
"update_cache": false,
"validate_certs": true
}
},
"item": "/data/playbooks/roles/backup_networker/files/lgtoclnt-8.2.4.9-1.x86_64.rpm",
"results": [
{
"arch": "x86_64",
"envra": "0:lgtoclnt-8.2.4.9-1.x86_64",
"epoch": "0",
"name": "lgtoclnt",
"release": "1",
"repo": "installed",
"version": "8.2.4.9",
"yumstate": "installed"
}
]
}
How can i access the information in the last results block?
"arch": "x86_64",
"envra": "0:lgtoclnt-8.2.4.9-1.x86_64",
"epoch": "0",
"name": "lgtoclnt",
"release": "1",
"repo": "installed",
"version": "8.2.4.9",
"yumstate": "installed"
I've tried something like yum_result.results.yumstate or yum_result[2].yumstate, but nothing works.

You can access the result with
yum_result.results[0].yumstate

Use:
yum_result to access registered dictionary
yum_result.results to access the list of registered iterations
yum_result.results[-1] to access result of last iteration
yum_result.results[-1].yumstate to access it's yumstate status

Related

Getting a value out of registered variable in Ansible

So, I'm provisioning an EC2 instance using the ec2 module. At the end I'm using register: ec2info, so, I can later reference values inside, such as instance ID and Public DNS.
- name: Print the results
debug:
var: ec2info
Gets me
TASK [Print the results] ***********************************************************************************************************************
ok: [localhost] => {
"ec2info": {
"changed": true,
"deprecations": [
{
"collection_name": "amazon.aws",
"msg": "The 'ec2' module has been deprecated and replaced by the 'ec2_instance' module'",
"version": "4.0.0"
}
],
"failed": false,
"instance_ids": [
"i-0e9de15eb82eda3ad"
],
"instances": [
{
"ami_launch_index": "0",
"architecture": "x86_64",
"block_device_mapping": {
"/dev/sda1": {
"delete_on_termination": true,
"status": "attached",
"volume_id": "vol-066bb2dd4d14bdcac"
}
},
"dns_name": "ec2-35-173-126-60.compute-1.amazonaws.com",
"ebs_optimized": false,
"groups": {
"sg-0a732c6cbeb3f1025": "launch-wizard-39"
},
"hypervisor": "xen",
"id": "i-0e9de15eb82eda3ad",
"image_id": "ami-06644055bed38ebd9",
"instance_type": "t2.micro",
"kernel": null,
"key_name": "daro.io",
"launch_time": "2022-02-01T02:05:22.000Z",
"placement": "us-east-1c",
"private_dns_name": "ip-172-31-90-87.ec2.internal",
"private_ip": "172.31.90.87",
"public_dns_name": "ec2-35-173-126-60.compute-1.amazonaws.com",
"public_ip": "35.173.126.60",
"ramdisk": null,
"region": "us-east-1",
"root_device_name": "/dev/sda1",
"root_device_type": "ebs",
"state": "running",
"state_code": 16,
"tags": {
"Name": "new_demo_template"
},
"tenancy": "default",
"virtualization_type": "hvm"
}
],
"tagged_instances": []
}
}
I would like to get the value of Public DNS I have tried
- name: Print the results
debug:
var: ec2info.instances.public_dns_name
## AND
var: ec2info.instances['public_dns_name']
## AND
var: '{{ec2info.instances.public_dns_name}}'
If you could also point out to the part of the documentation that covers this?
So, I figured it out
var: ec2info.instances[0].public_dns_name

Anlible. How do I add a condition to a loop operation?

How can I get from this data only the value ("subclientName": "test") where "count" = 1
"subclientName": "start9pm" should not be in the selection
{
"countbackupsetName": {
"results": [
{
"actions": {
"xpath": "//subClientProperties[subClientEntity[#subclientName=\"test\"]]/vmContent/children",
"namespaces": {},
"state": "present"
},
"changed": false,
"count": 2,
"msg": "found 2 nodes",
"invocation": {
"module_args": {
"path": "/var/lib/awx/projects/commv/parse/get_subclient2.xml",
"xpath": "//subClientProperties[subClientEntity[#subclientName=\"test\"]]/vmContent/children",
"count": true,
"namespaces": {},
"state": "present",
"print_match": false,
"pretty_print": false,
"input_type": "yaml",
"backup": false,
"strip_cdata_tags": false,
"insertbefore": false,
"insertafter": false,
"xmlstring": null,
"value": null,
"attribute": null,
"add_children": null,
"set_children": null,
"content": null
}
},
"failed": false,
"item": {
"appName": "Virtual Server",
"backupsetName": "backupset-test",
"clientName": "name05-vcagent",
"displayName": "name05-VCAgent",
"instanceName": "VC01",
"subclientName": "test"
},
"ansible_loop_var": "item"
},
{
"actions": {
"xpath": "//subClientProperties[subClientEntity[#subclientName=\"start9pm\"]]/vmContent/children",
"namespaces": {},
"state": "present"
},
"changed": false,
"count": 2,
"msg": "found 2 nodes",
"invocation": {
"module_args": {
"path": "/var/lib/awx/projects/commv/parse/get_subclient2.xml",
"xpath": "//subClientProperties[subClientEntity[#subclientName=\"start9pm\"]]/vmContent/children",
"count": true,
"namespaces": {},
"state": "present",
"print_match": false,
"pretty_print": false,
"input_type": "yaml",
"backup": false,
"strip_cdata_tags": false,
"insertbefore": false,
"insertafter": false,
"xmlstring": null,
"value": null,
"attribute": null,
"add_children": null,
"set_children": null,
"content": null
}
},
"failed": false,
"item": {
"appName": "Virtual Server",
"backupsetName": "Test01",
"clientName": "name05-vcagent",
"displayName": "name05-VCAgent",
"instanceName": "VC01",
"subclientName": "start9pm"
},
"ansible_loop_var": "item"
}
],
"msg": "All items completed",
"changed": false
},
"_ansible_verbose_always": true,
"_ansible_no_log": false,
"changed": false
}
This is how I managed to select everything, without the condition operation:
- debug:
msg: "{{ item.subclientName }}"
loop: "{{ countbackupsetName.results|map(attribute='item')|list }}"
result:
{
"msg": "test",
"_ansible_verbose_always": true,
"_ansible_no_log": false,
"changed": false,
"item": {
"appName": "Virtual Server",
"backupsetName": "backupset-test",
"clientName": "name05-vcagent",
"displayName": "name05-VCAgent",
"instanceName": "VC01",
"subclientName": "test"
},
"ansible_loop_var": "item",
"_ansible_item_label": {
"appName": "Virtual Server",
"backupsetName": "backupset-test",
"clientName": "name05-vcagent",
"displayName": "name05-VCAgent",
"instanceName": "VC01",
"subclientName": "test"
}
}
This is how I get to the data I need, but the number of lines is always different.
I also don't need lines where count ":" 2 "
code:
- name: Show value in countbackupsetName.results.0.count
debug:
var: countbackupsetName.results.0.count
- debug:
var: countbackupsetName.results.0.item.subclientName
- name: Show value in countbackupsetName.results.1.count
debug:
var: countbackupsetName.results.1.count
- debug:
var: countbackupsetName.results.1.item.subclientName
result:
TASK [Show value in countbackupsetName.results.0.count] ************************
ok: [localhost] => {
"countbackupsetName.results.0.count": "1"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"countbackupsetName.results.0.item.subclientName": "test"
}
TASK [Show value in countbackupsetName.results.1.count] ************************
ok: [localhost] => {
"countbackupsetName.results.1.count": "2"
}
code:
- name: debug jinja
debug:
msg: |
[
{% for p in countbackupsetName.results %}
{% for o in countbackupsetName.results[p].item %}
{
"count": "{{ countbackupsetName.results[p].count }}",
"key": "{{ o }}",
"value": "{{ countbackupsetName.results[p].item[o] }}"
},
{% endfor %}
{% endfor %}
]
result:
line 112, column 9, but may\nbe elsewhere in the file depending on the exact syntax problem.
Not sure I've got properly what is desired output. But idea should be the same regardless: loop through results checking for condition and printing matching items. Here you go:
- hosts: localhost
become: false
tasks:
- set_fact:
data: {
"countbackupsetName": {
"results": [
{
"actions": {
"xpath": "//subClientProperties[subClientEntity[#subclientName=\"test\"]]/vmContent/children",
"namespaces": {},
"state": "present"
},
"changed": false,
"count": 2,
"msg": "found 2 nodes",
"invocation": {
"module_args": {
"path": "/var/lib/awx/projects/commv/parse/get_subclient2.xml",
"xpath": "//subClientProperties[subClientEntity[#subclientName=\"test\"]]/vmContent/children",
"count": true,
"namespaces": {},
"state": "present",
"print_match": false,
"pretty_print": false,
"input_type": "yaml",
"backup": false,
"strip_cdata_tags": false,
"insertbefore": false,
"insertafter": false,
"xmlstring": null,
"value": null,
"attribute": null,
"add_children": null,
"set_children": null,
"content": null
}
},
"failed": false,
"item": {
"appName": "Virtual Server",
"backupsetName": "backupset-test",
"clientName": "name05-vcagent",
"displayName": "name05-VCAgent",
"instanceName": "VC01",
"subclientName": "test"
},
"ansible_loop_var": "item"
},
{
"actions": {
"xpath": "//subClientProperties[subClientEntity[#subclientName=\"start9pm\"]]/vmContent/children",
"namespaces": {},
"state": "present"
},
"changed": false,
"count": 2,
"msg": "found 2 nodes",
"invocation": {
"module_args": {
"path": "/var/lib/awx/projects/commv/parse/get_subclient2.xml",
"xpath": "//subClientProperties[subClientEntity[#subclientName=\"start9pm\"]]/vmContent/children",
"count": true,
"namespaces": {},
"state": "present",
"print_match": false,
"pretty_print": false,
"input_type": "yaml",
"backup": false,
"strip_cdata_tags": false,
"insertbefore": false,
"insertafter": false,
"xmlstring": null,
"value": null,
"attribute": null,
"add_children": null,
"set_children": null,
"content": null
}
},
"failed": false,
"item": {
"appName": "Virtual Server",
"backupsetName": "Test01",
"clientName": "name05-vcagent",
"displayName": "name05-VCAgent",
"instanceName": "VC01",
"subclientName": "start9pm"
},
"ansible_loop_var": "item"
}
],
"msg": "All items completed",
"changed": false
},
"_ansible_verbose_always": true,
"_ansible_no_log": false,
"changed": false
}
- debug:
var: result
# check for condition in result
when: result['item']['subclientName'] == "test"
# iterate over result list
loop: "{{ data['countbackupsetName']['results'] }}"
# set loop_var to not confuse ansible's "item" var with "item" key in data
loop_control:
loop_var: result
Was able to solve the problem using json_query!
code:
- set_fact:
add_filter: "{{ countbackupsetName|json_query(query2) }}"
vars:
query2: "results[?count==`1`].item.subclientName"
- name: debug json_query(query2)
debug:
var: add_filter
result:
TASK [debug json_query(query2)] ************************************************
ok: [localhost] => {
"add_filter": [
"test"
]
}
code:
- set_fact:
add_filter: "{{ count_add_hostname.results|json_query(_query) }}"
vars:
_query: "[].{subclientName: '[?count==`1`]'.item.subclientName,
backupsetName: '[?count==`1`]'.item.backupsetName}"
- name: debug json_query(add_filter)
debug:
var: add_filter
I try to execute in a loop
result:
TASK [debug json_query(add_filter) var=add_filter] *****************************
ok: [localhost] => {
"add_filter": [
{
"backupsetName": null,
"subclientName": null
},
{
"backupsetName": null,
"subclientName": null
},
{
"backupsetName": null,
"subclientName": null
}
]
}
is the empty result related to a conflict in the loop item and the dictionary name item ...

Combining json register results in ansible

I have searched for an answer to the following question. I could find some related answers but unfortunatly doesn't solve my issue.
i have this json out put from debugging a register in a win_find task:
- name: find docs older than 15 days
win_find:
paths: '{{ main_dir }}\{{ item }}\docs'
age: 15d
loop: '{{ all_folders}}'
register: register_files
- debug:
var: register_files
this is the debug output (i have removed some attributes to make the code shorter and easier to explain):
"register_files": {
"changed": false,
"msg": "All items completed",
"results": [
{
"_ansible_item_label": "folder_1",
"changed": false,
"examined": 378,
"files": [
{
"attributes": "Archive",
"checksum": "0351d8fffad7a16a5c21136ac5a77b33931237ad",
"creationtime": 1568633779.2339206,
},
{
"attributes": "Archive",
"checksum": "d25dd0915fe825790c8c3a27acdf6f5b34f6686b",
"creationtime": 1568633767.7103796,
"item": folder_1",
"matched": 302
},
"_ansible_item_label": "folder_2",
"changed": false,
"examined": 266,
"files": [
{
"attributes": "Archive",
"checksum": "0351d8fffad7a16a5c21136ac5a77b33931237ad",
"creationtime": 1568633779.2339206,
},
{
"attributes": "Archive",
"checksum": "d25dd0915fe825790c8c3a27acdf6f5b34f6686b",
"creationtime": 1568633767.7103796,
"item": folder_2",
"matched": 125
Because the code lookup two different folders i am getting the results back as two different dict lists. how can i combine those into one so i can get those results:
"files": [
{
"attributes": "Archive",
"checksum": "0351d8fffad7a16a5c21136ac5a77b33931237ad",
"creationtime": 1568633779.2339206,
},
{
"attributes": "Archive",
"checksum": "d25dd0915fe825790c8c3a27acdf6f5b34f6686b",
"creationtime": 1568633767.7103796,
{
"attributes": "Archive",
"checksum": "0351d8fffad7a16a5c21136ac5a77b33931237ad",
"creationtime": 1568633779.2339206,
},
{
"attributes": "Archive",
"checksum": "d25dd0915fe825790c8c3a27acdf6f5b34f6686b",
"creationtime": 1568633767.7103796,
Is this what you're looking for?
my_files: "{{ register_files.results|json_query('[].files')|flatten }}"
(not tested)
One easy way to get the result you want is to use the json_query filter with the correct jmespath expression
- name: Get file info
debug:
msg: "{{ register_files | json_query('results[].files[]') | list }}"
This was tested against the following data structure taken from your example and fixed to end up with a correct json.
"register_files": {
"changed": false,
"msg": "All items completed",
"results": [
{
"_ansible_item_label": "folder_1",
"changed": false,
"examined": 378,
"files": [
{
"attributes": "Archive",
"checksum": "0351d8fffad7a16a5c21136ac5a77b33931237ad",
"creationtime": 1568633779.2339206
},
{
"attributes": "Archive",
"checksum": "d25dd0915fe825790c8c3a27acdf6f5b34f6686b",
"creationtime": 1568633767.7103796
}
],
"item": folder_1",
"matched": 302
},
{
"_ansible_item_label": "folder_2",
"changed": false,
"examined": 266,
"files": [
{
"attributes": "Archive",
"checksum": "0351d8fffad7a16a5c21136ac5a77b33931237ad",
"creationtime": 1568633779.2339206
},
{
"attributes": "Archive",
"checksum": "d25dd0915fe825790c8c3a27acdf6f5b34f6686b",
"creationtime": 1568633767.7103796
}
],
"item": folder_2",
"matched": 125
}
]
}
Please make sure you check your MCVE in your future questions.

Is it possible to combine with_dict with with_items?

I have an output of a playbook and I want to debug a message based on a condition of the output. I need the key and value pairs of the item to match a when statement then I will print out the actual data.
ok: [pynet-sw5] => {
"loop_iterate": {
"changed": false,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "1.1.1.1",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"count": null,
"destination": "1.1.1.1",
"dev_os": "eos",
"hostname": "arista5.twb-tech.com",
"optional_args": null,
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"ping_timeout": null,
"provider": {
"dev_os": "eos",
"hostname": "arista5.twb-tech.com",
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"timeout": 60,
"username": "xxx"
},
"size": null,
"source": null,
"timeout": 60,
"ttl": null,
"username": "pyclass",
"vrf": null
}
},
"item": "1.1.1.1",
"results": {
"success": {
"packet_loss": 0,
"probes_sent": 5,
When I put the below statement it returns with item is not defined error.
- debug:
msg: "{{item[1].item}} is pingable from {{ansible_host}} with {{item[1].results.success.packet_loss}} out of 5 packets"
when: "item[0].key == 'packet_loss'"
with_sublements:
- "{{loop_iterate.results.results.success}}"
- "{{loop_iterate.results}}"
so is there a way of combining with_dict with with_items ? I want to use
- "{{loop_iterate.results.results.success}}" as with_dict iteration while using - "{{loop_iterate.results}}" as with_items

How to create a directory with particular SE Linux context on it

Here is what I have:
- name: Create directories that will be used as persistent volumes
become: yes
become_method: sudo
file:
path: /tmp/pv-{{ item }}
state: directory
mode: "g=rwx"
group: "root"
selevel: _default
seuser: _default
serole: _default
setype: svirt_sandbox_file_t
with_items:
- cassandra
- services
The two directories are correctly created, group a rights are ok. But the SE Linux context is wrong.
$ ll -dZ /tmp/pv-cassandra
drwxrwxr-x. 2 jkremser root unconfined_u:object_r:user_tmp_t:s0 40 Mar 9 15:19 /tmp/pv-cassandra
This is the part of the debugging output:
ok: [localhost] => (item=cassandra) => {
"changed": false,
"diff": {
"after": {
"path": "/tmp/pv-cassandra"
},
"before": {
"path": "/tmp/pv-cassandra"
}
},
"gid": 0,
"group": "root",
"invocation": {
"module_args": {
"backup": null,
"content": null,
"delimiter": null,
"diff_peek": null,
"directory_mode": null,
"follow": false,
"force": false,
"group": "root",
"mode": "g=rwx",
"original_basename": null,
"owner": null,
"path": "/tmp/pv-cassandra",
"recurse": false,
"regexp": null,
"remote_src": null,
"selevel": "_default",
"serole": "_default",
"setype": "svirt_sandbox_file_t",
"seuser": "_default",
"src": null,
"state": "directory",
"unsafe_writes": null,
"validate": null
},
"module_name": "file"
},
"item": "cassandra",
"mode": "0775",
"owner": "root",
"path": "/tmp/pv-cassandra",
"size": 80,
"state": "directory",
"uid": 0
}
What am I doing wrong? My OS is Fedora 25.
If I use the copy module, instead of the file, that has almost the same parameters, it throws this error:
Aborting, target uses selinux but python bindings (libselinux-python) aren't installed
After installing the libselinux-python package, it works! So it looks like the file module silently swallows the error and does what it can do :( I can't depend on the fact that user has the libselinux-python package installed.
I'll probably call the chcon myself as a shell command or add the package as a prerequisite:
- name: Install the libselinux-python package
package:
name: libselinux-python
state: present

Resources