I want to use Ansible to install the appropriate RAID controller utility for every server but work in a fairly mixed environment with different vendors and different RAID controllers. I think the best way to handle this is by writing a custom module that provides a raid_controller_manufacturer fact, but before I do I wanted to see if it would be possible to just do some fuzzy matching on nested elements in the ansible_devices fact.
Here's a partial snippet from running setup against a SuperMicro server with an LSI controller:
"ansible_devices": {
"sda": {
"host": "RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS 2108 [Liberator] (rev 04)"
}
}
Here's a partial snippet from running setup against another SuperMicro with an Adaptec controller:
"ansible_devices": {
"sda": {
"host": "RAID bus controller: Adaptec AAC-RAID (rev 09)"
}
}
And here's another partial snippet from running setup against an HP with an HP SmartArray controller:
"ansible_devices": {
"cciss!c0d0": {
"host": "RAID bus controller: Hewlett-Packard Company Smart Array Controller (rev 04)"
}
}
So, long story short is there a way to do something akin to the following:
- name: Install HP SmartArray util
yum: name=hpacucli state=latest
when: ansible_devices.*.host contains "Hewlett-Packard Company Smart Array Controller"
- name: Install LSI MegaRaid util
yum: name=MegaCli state=latest
when: ansible_devices.*.host contains "LSI Logic / Symbios Logic MegaRAID"
- name: Install Adaptec util
yum: name=aacraid state=latest
when: ansible_devices.*.host contains "Adaptec AAC-RAID"
maybe we should have the values of lspci (and lsusb) in setup?
Nothing presently doable as the “when” is more or less a Python expression.
(also this quickly spirals into complicated because you could have more than one raid card)
lspci data quickly bloats setup results, so it seems like a custom fact module may be best here.
lspci data quickly bloats setup results, so it seems like a custom fact
module may be best here.
Cool, thanks Serge and Michael for your responses!
(also this quickly spirals into complicated because you could have more
than one raid card)
lspci data quickly bloats setup results, so it seems like a custom fact
module may be best here.
Is there a way to access facts directly from a Python module?
I wrote the raid_controller_facts module today. I'm using the common module boilerplate as described in the docs. Rather than call lspci a second time and parse the output again (the first time being in the setup module) I'm cheating and passing ansible_devices as an argument to my module:
- name: Gather RAID controller facts
raid_controller_facts:
devices: "{{ ansible_devices }}"
And then in the implementation I iterate through module.params["devices"] and check if the host field contains the word RAID.
I've got it all working fine, but ansible_devices is being converted to a string value before being passed to my module so I use ast.literal_eval to convert it back to a hash. Besides avoiding the unnecessary conversion to string and back, I have a few servers with Python 2.4.2 so the ast module isn't available, and my module doesn't work on them.
So, long story short, if I could access the ansible_devices fact directly in my module then I could avoid a little busy work and work on systems with older Python installs.
Nope, you would have to pass them in.
If you are doing complex arguments, when you say " {{ foo }}" you are requesting a string.
This is the one case where the old style var is still useful, to indicate you want a reference, which I still think we need a syntax for.
raid_controller_facts:
devices: $devices
Should work for you.
This is the *one* case where the old style var is still useful, to indicate
you want a reference, which I still think we need a syntax for.
raid_controller_facts:
devices: $devices
Should work for you.
Yep, that worked perfectly. Thanks!