Reputation: 1101
I'm currently working with Ansible inventory hosts and my script needs to parse them in order to complete some tasks.
The issue here is converting the string patterns to an array or a string that can be iterated over, for example:
x="mymachine[1:2]cluster[1:2]"
for host in `parse_ansible_hosts $x`; do
echo $host
Which should print:
mymachine1cluster1
mymachine1cluster2
mymachine2cluster1
mymachine2cluster2
Is there a way to accomplish this via regex or similar? The syntax cannot be changed, since it parses directly from ansible inventory.
Upvotes: 0
Views: 1003
Reputation:
If I understand you correctly, you want a hostname generator. If this is correct, and the pattern is as simple as your example, bash already has you covered:
$ for host in mymachine{1,2}cluster{1,2}; do
> echo $host
> done
mymachine1cluster1
mymachine1cluster2
mymachine2cluster1
mymachine2cluster2
Ranges are supported, too:
$ for host in mymachine{1..3}cluster{1..3}; do echo $host; done
mymachine1cluster1
mymachine1cluster2
mymachine1cluster3
mymachine2cluster1
mymachine2cluster2
mymachine2cluster3
mymachine3cluster1
mymachine3cluster2
mymachine3cluster3
To get from your example pattern to shell-expansion might be one of the seldom cases where an eval
is safe to use -- use this only if the pattern source is safe and trusted, not e.g. a web-interface:
$ x="mymachine[1:2]cluster[1:2]"
$ for host in $(eval \
echo $(sed 's/\[/{/g' <<<${x} | \
sed 's/]/}/g' | \
sed 's/:/,/g' )); do
echo $host
done
mymachine1cluster1
mymachine1cluster2
mymachine2cluster1
mymachine2cluster2
For ranges this would read
$ for host in $(eval \
echo $(sed 's/\[/{/g' <<<${x} | \
sed 's/]/}/g' | \
sed 's/:/../g' )); do
echo $host
done
Nota Bene:
If you have the possibility to use other tools like python or ruby, there are 'reverse regexp' implementations available. E.g. 'regex-examples' as ruby-gem:
irb(main):003:0> require 'regexp-examples'
=> true
irb(main):004:0> /a[bc]/.examples()
=> ["ab", "ac"]
irb(main):005:0> /mymachine[12]cluster[12]/.examples()
=> ["mymachine1cluster1", "mymachine1cluster2", "mymachine2cluster1", "mymachine2cluster2"]
Upvotes: 1
Reputation: 2179
I'm sure the ansible Classes when it is installed on your host are publicy available so you could use them as ansible do to parse the inventory. I think the interesting parts are in https://github.com/ansible/ansible/tree/devel/lib/ansible/inventory
Upvotes: 0
Reputation: 195259
if your machine/cluster count < 10, replace the :
by -
in your x
variable, it would be the regex to use.
Upvotes: 0