diff --git a/examples/playbooks/group_by.yml b/examples/playbooks/group_by.yml new file mode 100644 index 0000000000..d08f260bd0 --- /dev/null +++ b/examples/playbooks/group_by.yml @@ -0,0 +1,23 @@ +--- +# Example playbook to demonstrate the group_by action plugin. + +- hosts: all + # This runs the setup module to gather facts + tasks: + # Use the ansible_machine variable to create a group for every value, + # prefix the group name with 'ansible-' + - action: group_by key=ansible-${ansible_machine} + +- hosts: ansible-x86_64 + tasks: + # Run ping on all x86_64 machines + - action: ping + +- hosts: all + tasks: + # Create a group of all kvm hosts + - action: group_by key=${ansible_virtualization_type}-${ansible_virtualization_role} + +- hosts: kvm-host + tasks: + - action: ping diff --git a/lib/ansible/runner/action_plugins/group_by.py b/lib/ansible/runner/action_plugins/group_by.py new file mode 100644 index 0000000000..d65ec24dd0 --- /dev/null +++ b/lib/ansible/runner/action_plugins/group_by.py @@ -0,0 +1,71 @@ +# Copyright 2012, Jeroen Hoekx +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +import ansible + +from ansible.callbacks import vv +from ansible.errors import AnsibleError as ae +from ansible.runner.return_data import ReturnData +from ansible.utils import parse_kv, template + +class ActionModule(object): + ''' Create inventory groups based on variables ''' + + ### We need to be able to modify the inventory + BYPASS_HOST_LOOP = True + + def __init__(self, runner): + self.runner = runner + + def run(self, conn, tmp, module_name, module_args, inject): + args = parse_kv(self.runner.module_args) + if not 'key' in args: + raise ae("'key' is a required argument.") + + vv("created 'group_by' ActionModule: key=%s"%(args['key'])) + + inventory = self.runner.inventory + + result = {'changed': False} + + ### find all groups + groups = {} + for host in self.runner.host_set: + data = inject['hostvars'][host] + group_name = template(self.runner.basedir, args['key'], data) + group_name = group_name.replace(' ','-') + if group_name not in groups: + groups[group_name] = [] + groups[group_name].append(host) + + result['groups'] = groups + + ### add to inventory + for group, hosts in groups.items(): + inv_group = inventory.get_group(group) + if not inv_group: + inv_group = ansible.inventory.Group(name=group) + inventory.add_group(inv_group) + for host in hosts: + inv_host = inventory.get_host(host) + if not inv_host: + inv_host = ansible.inventory.Host(name=host) + if inv_group not in inv_host.get_groups(): + result['changed'] = True + inv_group.add_host(inv_host) + + return ReturnData(conn=conn, comm_ok=True, result=result) diff --git a/library/group_by b/library/group_by new file mode 100644 index 0000000000..4a1609ec55 --- /dev/null +++ b/library/group_by @@ -0,0 +1,23 @@ +# -*- mode: python -*- + +DOCUMENTATION = ''' +--- +module: group_by +short_description: Create Ansible groups based on facts +description: + - Use facts to create ad-hoc groups that can be used later in a playbook. +version_added: 0.9 +options: + key: + description: + - The variables whose values will be used as groups + required: true +author: Jeroen Hoekx +examples: + - description: Create groups based on the machine architecture + code: group_by key=${ansible_machine} + - description: Create groups like 'kvm-host' + code: group_by key=${ansible_virtualization_type}-${ansible_virtualization_role} +notes: + - Spaces in group names are converted to dashes '-'. +'''