mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2025-10-26 21:59:38 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			206 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			206 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| # (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
 | |
| #
 | |
| # 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 <http://www.gnu.org/licenses/>.
 | |
| 
 | |
| import ansible.constants as C
 | |
| from ansible.inventory.host import Host
 | |
| from ansible.inventory.group import Group
 | |
| from ansible import errors
 | |
| from ansible import utils
 | |
| import os
 | |
| import yaml
 | |
| import sys
 | |
| 
 | |
| class InventoryParserYaml(object):
 | |
|     ''' Host inventory parser for ansible '''
 | |
| 
 | |
|     def __init__(self, filename=C.DEFAULT_HOST_LIST):
 | |
| 
 | |
|         sys.stderr.write("WARNING: YAML inventory files are deprecated in 0.6 and will be removed in 0.7, to migrate" +
 | |
|             " download and run https://github.com/ansible/ansible/blob/devel/examples/scripts/yaml_to_ini.py\n")
 | |
| 
 | |
|         fh = open(filename)
 | |
|         data = fh.read()
 | |
|         fh.close()
 | |
|         self._hosts = {}
 | |
|         self._parse(data)
 | |
| 
 | |
|     def _make_host(self, hostname):
 | |
| 
 | |
|         if hostname in self._hosts:
 | |
|             return self._hosts[hostname]
 | |
|         else:
 | |
|             host = Host(hostname)
 | |
|             self._hosts[hostname] = host
 | |
|             return host
 | |
| 
 | |
|     # see file 'test/yaml_hosts' for syntax
 | |
| 
 | |
|     def _parse(self, data):
 | |
|         # FIXME: refactor into subfunctions
 | |
| 
 | |
|         all = Group('all')
 | |
| 
 | |
|         ungrouped = Group('ungrouped')
 | |
|         all.add_child_group(ungrouped)
 | |
| 
 | |
|         self.groups = dict(all=all, ungrouped=ungrouped)
 | |
|         grouped_hosts = []
 | |
| 
 | |
|         yaml = utils.parse_yaml(data)
 | |
| 
 | |
|         # first add all groups
 | |
|         for item in yaml:
 | |
|             if type(item) == dict and 'group' in item:
 | |
|                 group = Group(item['group'])
 | |
| 
 | |
|                 for subresult in item.get('hosts',[]):
 | |
| 
 | |
|                     if type(subresult) in [ str, unicode ]:
 | |
|                         host = self._make_host(subresult)
 | |
|                         group.add_host(host)
 | |
|                         grouped_hosts.append(host)
 | |
|                     elif type(subresult) == dict:
 | |
|                         host = self._make_host(subresult['host'])
 | |
|                         vars = subresult.get('vars',{})
 | |
|                         if type(vars) == list:
 | |
|                             for subitem in vars:
 | |
|                                 for (k,v) in subitem.items():
 | |
|                                     host.set_variable(k,v)
 | |
|                         elif type(vars) == dict:
 | |
|                             for (k,v) in subresult.get('vars',{}).items():
 | |
|                                 host.set_variable(k,v)
 | |
|                         else:
 | |
|                             raise errors.AnsibleError("unexpected type for variable")
 | |
|                         group.add_host(host)
 | |
|                         grouped_hosts.append(host)
 | |
| 
 | |
|                 vars = item.get('vars',{})
 | |
|                 if type(vars) == dict:
 | |
|                     for (k,v) in item.get('vars',{}).items():
 | |
|                         group.set_variable(k,v)
 | |
|                 elif type(vars) == list:
 | |
|                     for subitem in vars:
 | |
|                         if type(subitem) != dict:
 | |
|                             raise errors.AnsibleError("expected a dictionary")
 | |
|                         for (k,v) in subitem.items():
 | |
|                             group.set_variable(k,v)
 | |
| 
 | |
|                 self.groups[group.name] = group
 | |
|                 all.add_child_group(group)
 | |
| 
 | |
|         # add host definitions
 | |
|         for item in yaml:
 | |
|             if type(item) in [ str, unicode ]:
 | |
|                 host = self._make_host(item)
 | |
|                 if host not in grouped_hosts:
 | |
|                     ungrouped.add_host(host)
 | |
| 
 | |
|             elif type(item) == dict and 'host' in item:
 | |
|                 host = self._make_host(item['host'])
 | |
| 
 | |
|                 vars = item.get('vars', {})
 | |
|                 if type(vars)==list:
 | |
|                     varlist, vars = vars, {}
 | |
|                     for subitem in varlist:
 | |
|                         vars.update(subitem)
 | |
|                 for (k,v) in vars.items():
 | |
|                     host.set_variable(k,v)
 | |
| 
 | |
|                 groups = item.get('groups', {})
 | |
|                 if type(groups) in [ str, unicode ]:
 | |
|                     groups = [ groups ]
 | |
|                 if type(groups)==list:
 | |
|                     for subitem in groups:
 | |
|                         if subitem in self.groups:
 | |
|                             group = self.groups[subitem]
 | |
|                         else:
 | |
|                             group = Group(subitem)
 | |
|                             self.groups[group.name] = group
 | |
|                             all.add_child_group(group)
 | |
|                         group.add_host(host)
 | |
|                         grouped_hosts.append(host)
 | |
| 
 | |
|                 if host not in grouped_hosts:
 | |
|                     ungrouped.add_host(host)
 | |
| 
 | |
|         # make sure ungrouped.hosts is the complement of grouped_hosts
 | |
|         ungrouped_hosts = [host for host in ungrouped.hosts if host not in grouped_hosts]
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     if len(sys.argv) != 2:
 | |
|         print "usage: yaml_to_ini.py /path/to/ansible/hosts"
 | |
|         sys.exit(1)
 | |
| 
 | |
|     result = ""
 | |
| 
 | |
|     original = sys.argv[1]
 | |
|     yamlp = InventoryParserYaml(filename=sys.argv[1])
 | |
|     dirname = os.path.dirname(original)
 | |
| 
 | |
|     group_names = [ g.name for g in yamlp.groups.values() ]
 | |
| 
 | |
|     for group_name in sorted(group_names):
 | |
| 
 | |
|         record = yamlp.groups[group_name]
 | |
| 
 | |
|         if group_name == 'all':
 | |
|             continue
 | |
| 
 | |
|         hosts = record.hosts
 | |
|         result = result + "[%s]\n" % record.name
 | |
|         for h in hosts:
 | |
|             result = result + "%s\n" % h.name
 | |
|         result = result + "\n"
 | |
| 
 | |
|         groupfiledir = os.path.join(dirname, "group_vars")
 | |
|         if not os.path.exists(groupfiledir):
 | |
|             print "* creating: %s" % groupfiledir
 | |
|             os.makedirs(groupfiledir)
 | |
|         groupfile = os.path.join(groupfiledir, group_name)
 | |
|         print "* writing group variables for %s into %s" % (group_name, groupfile)
 | |
|         groupfh = open(groupfile, 'w')
 | |
|         groupfh.write(yaml.dump(record.get_variables()))
 | |
|         groupfh.close()
 | |
| 
 | |
|     for (host_name, host_record) in yamlp._hosts.iteritems():
 | |
|         hostfiledir = os.path.join(dirname, "host_vars")
 | |
|         if not os.path.exists(hostfiledir):
 | |
|             print "* creating: %s" % hostfiledir
 | |
|             os.makedirs(hostfiledir)
 | |
|         hostfile = os.path.join(hostfiledir, host_record.name)
 | |
|         print "* writing host variables for %s into %s" % (host_record.name, hostfile)
 | |
|         hostfh = open(hostfile, 'w')
 | |
|         hostfh.write(yaml.dump(host_record.get_variables()))
 | |
|         hostfh.close()
 | |
| 
 | |
| 
 | |
|     # also need to keep a hash of variables per each host
 | |
|     # and variables per each group
 | |
|     # and write those to disk
 | |
| 
 | |
|     newfilepath = os.path.join(dirname, "hosts.new")
 | |
|     fdh = open(newfilepath, 'w')
 | |
|     fdh.write(result)
 | |
|     fdh.close()
 | |
| 
 | |
|     print "* COMPLETE: review your new inventory file and replace your original when ready"
 | |
|     print "*           new inventory file saved as %s" % newfilepath
 | |
|     print "*           edit group specific variables in %s/group_vars/" % dirname
 | |
|     print "*           edit host specific variables in %s/host_vars/" % dirname
 | |
| 
 | |
|     # now need to write this to disk as (oldname).new
 | |
|     # and inform the user
 |