Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: run.py

Issue 4810150141493248: Issue 122 - Puppet ENC via Hiera (Closed)
Patch Set: Puppet ENC via Hiera Created March 4, 2015, 5:59 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # coding: utf-8 2 # coding: utf-8
3 3
4 import sys 4 import sys
5 import os 5 import os
6 import re 6 import re
7 import subprocess 7 import subprocess
8 import getopt 8 import getopt
9 import yaml 9 import yaml
10 10
(...skipping 23 matching lines...) Expand all
34 for option, value in options: 34 for option, value in options:
35 if option == '-u': 35 if option == '-u':
36 user = value 36 user = value
37 elif option == '-h': 37 elif option == '-h':
38 hosts.append(value) 38 hosts.append(value)
39 elif option == '-i': 39 elif option == '-i':
40 ignore_errors = True 40 ignore_errors = True
41 41
42 return user, hosts, ignore_errors, args 42 return user, hosts, ignore_errors, args
43 43
44 def readMonitoringConfig():
45 # Use Puppet's parser to convert monitoringserver.pp into YAML
46 manifest = os.path.join(os.path.dirname(__file__), 'manifests', 'monitoringser ver.pp')
47 parseScript = '''
48 require 'puppet'
49 require 'puppet/parser'
50 parser = Puppet::Parser::Parser.new(Puppet[:environment])
51 Puppet.settings[:ignoreimport] = true
52 parser.file = ARGV[0]
53 print ZAML.dump(parser.parse)
54 '''
55 data, dummy = subprocess.Popen(['ruby', '', manifest],
56 stdin=subprocess.PIPE,
57 stdout=subprocess.PIPE).communicate(parseScript)
58
59 # See http://stackoverflow.com/q/8357650/785541 on parsing Puppet's YAML
60 yaml.add_multi_constructor(u"!ruby/object:", lambda loader, suffix, node: load er.construct_yaml_map(node))
61 yaml.add_constructor(u"!ruby/sym", lambda loader, node: loader.construct_yaml_ str(node))
62 return yaml.load(data)
63 44
64 def getValidHosts(): 45 def getValidHosts():
65 def processNode(node, hosts=None, groups=None): 46 dirname = os.path.dirname(sys.argv[0])
66 if hosts == None: 47 path_name = os.path.join(dirname, "hiera", "private", "hosts.yaml")
67 hosts = set() 48 with open(path_name, 'rb') as handle:
68 if groups == None: 49 config = yaml.load(handle)
69 groups = {} 50 servers = config.get('servers', {})
70 51 return servers
71 if 'context' in node and 'code' in node['context']:
72 node = node['context']['code']
73
74 if node.get('type', None) == 'nagios_hostgroup':
75 data = node['instances']['children'][0]
76 title = data['title']['value']
77 members = filter(lambda c: c['param'] == 'members', data['parameters']['ch ildren'])[0]['value']['value']
78 members = re.split(r'\s*,\s*', members)
79 groups[title] = members
80 elif node.get('type', None) == 'nagios_host':
81 data = node['instances']['children'][0]
82 title = data['title']['value']
83 hosts.add(title)
84
85 for child in node['children']:
86 processNode(child, hosts, groups)
87 return hosts, groups
88
89 monitoringConfig = readMonitoringConfig()
90 if not monitoringConfig:
91 print >>sys.stderr, "Failed to parse monitoring configuration"
92 return [[], []]
93 # Extract hosts and groups from monitoring config
94 return processNode(monitoringConfig)
95 52
96 def resolveHostList(hosts): 53 def resolveHostList(hosts):
97 validHosts, validGroups = getValidHosts()
98 if not validHosts:
99 print >>sys.stderr, "Warning: No valid hosts found, not validating"
100 return hosts
101 54
102 result = set() 55 result = set()
103 for param in hosts: 56
104 if param in validGroups: 57 try:
105 for host in validGroups[param]: 58 valid_hosts = getValidHosts()
106 if host == '*': 59 except Warning as error:
107 result = result | validHosts 60 print >>sys.stderr, 'Warning: failed to determine valid hosts:', error
108 else: 61 result.update(hosts)
109 result.add(host) 62 else:
110 elif param in validHosts: 63 for name in hosts:
111 result.add(param) 64 chunk = [
112 elif '%s.adblockplus.org' % param in validHosts: 65 value.get('dns', key) for (key, value) in valid_hosts.items()
113 result.add('%s.adblockplus.org' % param) 66
114 else: 67 if name == key
115 print >>sys.stderr, 'Warning: failed to recognize host or group %s' %param 68 or name == '*'
69 or name == value.get('dns', None)
70 or name in value.get('groups', ())
71 ]
72
73 if len(chunk) == 0:
74 print >>sys.stderr, 'Warning: failed to recognize host or group', name
75 else:
76 result.update(chunk)
77
116 return result 78 return result
117 79
118 def runCommand(user, host, command, ignore_errors=False): 80 def runCommand(user, host, command, ignore_errors=False):
119 if not isinstance(command, list): 81 if not isinstance(command, list):
120 command = [command] 82 command = [command]
121 command = ["ssh"] + (["-l", user] if user else []) + [host] + command 83 command = ["ssh"] + (["-l", user] if user else []) + [host] + command
122 if ignore_errors: 84 if ignore_errors:
123 subprocess.call(command) 85 subprocess.call(command)
124 else: 86 else:
125 subprocess.check_call(command) 87 subprocess.check_call(command)
126 88
127 if __name__ == "__main__": 89 if __name__ == "__main__":
128 user, hosts, ignore_errors, args = parseOptions(sys.argv[1:]) 90 user, hosts, ignore_errors, args = parseOptions(sys.argv[1:])
129 selectedHosts = resolveHostList(hosts) 91 selectedHosts = resolveHostList(hosts)
130 if len(selectedHosts) == 0: 92 if len(selectedHosts) == 0:
131 print >>sys.stderr, 'No valid hosts or groups specified, nothing to do' 93 print >>sys.stderr, 'No valid hosts or groups specified, nothing to do'
132 sys.exit(0) 94 sys.exit(0)
133 for host in selectedHosts: 95 for host in selectedHosts:
134 print >>sys.stderr, 'Running on %s...' % host 96 print >>sys.stderr, 'Running on %s...' % host
135 runCommand(user, host, args, ignore_errors=ignore_errors) 97 runCommand(user, host, args, ignore_errors=ignore_errors)
OLDNEW
« modules/statsmaster/manifests/init.pp ('K') | « modules/statsmaster/manifests/init.pp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld