|
- #!/usr/bin/env python3
- import sys
- import os
- import yaml
- import json
-
-
- class YamlReaderError(Exception):
- pass
-
-
- #**********************************
- def static_to_dynamic_inventory(inputdict, hosts={}, groups={}, position='top'):
- '''{
- "_meta": {
- "hostvars": {}
- },
- "all": {
- "children": [
- "ungrouped"
- ]
- },
- "ungrouped": {
- "children": [
- ]
- }
- }
- '''
-
- outputdict = {'_meta': {'hostvars': {} }}
- newhosts = {}
- newgroups = {}
- for k,v in inputdict.items():
- if k == 'groups' or k == 'children':
- for group in v:
- if group not in groups:
- groups.update({group: {}})
- if isinstance(v, dict):
- if 'children' in v:
- if not k in newgroups:
- newgroups = { k: { 'children': [] }}
- for group in v['children']:
- newgroups[k]['children'].append(group)
- groups.update(newgroups)
- if 'groups' in v:
- if not k in newgroups:
- newgroups = { k: { 'children': [] }}
- for group in v['groups']:
- newgroups[k]['children'].append(group)
- groups.update(newgroups)
- if 'hosts' in v:
- if isinstance(v['hosts'], list):
- msg = """
- Hosts should not be define as a list:
- Error appear on v['hosts']
- Do this:
- hosts:
- host1:
- host2:
- Instead of this:
- hosts:
- - host1
- - host2
- Exit on Error (1)
- """
- sys.stderr.write(msg)
- exit(1)
- for host in list(v['hosts']):
- if k in groups:
- if 'hosts' in groups[k]:
- groups[k]['hosts'].append(host)
- else:
- groups[k]['hosts'] = [host]
- else:
- groups.update({k: {'hosts': [host]}})
- if v['hosts'][host] is None:
- if not host in newhosts:
- newhosts[host] = {}
- elif 'vars' in v['hosts'][host]:
- newhosts.update({host: v['hosts'][host]})
- else:
- for key,val in v['hosts'][host].items():
- if host in newhosts:
- newhosts[host].update({key: val})
- else:
- newhosts[host] = {key: val}
- hosts.update(newhosts)
- if 'vars' in v:
- if position == 'group':
- if k in newgroups:
- newgroups[k].update({'vars': v['vars']})
- else:
- newgroups[k] = {'vars': v['vars']}
- groups.update(newgroups)
- if k == 'groups' or k == 'children':
- newposition = 'group'
- elif k == 'hosts':
- newposition = 'host'
- else:
- newposition = 'data'
- valid_group_syntax = ['children', 'groups', 'hosts', 'vars', '', None]
- if position == 'group':
- for word in v:
- if not word in valid_group_syntax:
- print("Syntax error in definition of group: {}".format(k))
- print("\"{}\" is not a valid syntax key in group".format(word))
- exit(1)
- outputdict.update(static_to_dynamic_inventory(v, hosts, groups, newposition))
- outputdict['_meta']['hostvars'].update(hosts)
- outputdict.update(groups)
- return outputdict
-
- #**********************************
- def data_merge(inst1, inst2):
-
- try:
- if (inst1 is None or isinstance(inst1, str)
- or isinstance(inst1, int)
- or isinstance(inst1, float)
- ):
- inst1 = inst2
- elif isinstance(inst1, list):
- if isinstance(inst2, list):
- inst1 = inst1 + inst2
- else:
- inst1.append(inst2)
- elif isinstance(inst1, dict):
- if isinstance(inst2, dict):
- inst1.update(inst2)
- else:
- raise YamlReaderError('Cannot merge non-dict "%s" into dict "%s"' % (inst2, inst1))
- except TypeError as e:
- raise YamlReaderError('TypeError "%s" when merging "%s" into "%s"' %
- (e, inst1, inst2))
- return inst1
-
- #**********************************
- def load_static_inventory(path, static):
-
- ##- load static
- #add filename to dir
- files = {}
- files['static'] = {}
- files['static']['dir'] = path + '/static'
- files['static']['files'] = []
-
- static_hosts = []
- #get all *.yml files
- for root, directory, filename in sorted(os.walk(path)):
- for file in filename:
- if file.endswith(('.yml', '.yaml')):
- files['static']['files'].append(os.path.join(root, file))
- filecontent = None
- filecontent = yaml.load(
- open(os.path.join(root, file), "rb").read(),
- Loader=yaml.FullLoader
- )
- if type(filecontent) == dict:
- filecontent = static_to_dynamic_inventory(filecontent)
- if 'hostvars' in filecontent['_meta']:
- for hostname in filecontent['_meta']['hostvars']:
- static_hosts.append(hostname)
- static.update(filecontent)
- static_hosts = sorted(set(static_hosts))
- return static, static_hosts
-
- #**********************************
- def main():
- static = {'_meta': {'hostvars': {}}}
-
- static, static_hosts = load_static_inventory(os.path.dirname(__file__), static)
- print(format(json.dumps(static, indent=2)))
- #print(format(json.dumps(static_hosts, indent=2)))
-
- if __name__ == '__main__':
- main()
-
|