*Make pylint less strict by adding F0401 (unable to import...) as an exception
[shinken.git] / libexec / link_vmware_host_vm.py
blob05a5d9b1486060344ce43500183bf872384fa2ba
1 #!/usr/bin/env python
2 #Copyright (C) 2009-2010 :
3 # Gabes Jean, naparuba@gmail.com
4 # Gerhard Lausser, Gerhard.Lausser@consol.de
5 # Gregory Starck, g.starck@gmail.com
7 #This file is part of Shinken.
9 #Shinken is free software: you can redistribute it and/or modify
10 #it under the terms of the GNU Affero General Public License as published by
11 #the Free Software Foundation, either version 3 of the License, or
12 #(at your option) any later version.
14 #Shinken is distributed in the hope that it will be useful,
15 #but WITHOUT ANY WARRANTY; without even the implied warranty of
16 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 #GNU Affero General Public License for more details.
19 #You should have received a copy of the GNU Affero General Public License
20 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
22 import os
23 import sys
24 import shlex
25 import shutil
26 import getopt
27 # Try to load the json (2.5 and higer) or
28 # the simplejson if failed (python2.4)
29 try:
30 import json
31 except ImportError:
32 # For old Python version, load
33 # simple json (it can be hard json?! It's 2 functions guy!)
34 try:
35 import simplejson as json
36 except ImportError:
37 print "Error : you need the json or simplejson module for this script"
38 sys.exit(2)
39 from subprocess import Popen, PIPE
42 # Split and clean the rules from a string to a list
43 def split_rules(rules):
44 t = rules.split('|')
45 new_rules = []
46 for e in t:
47 new_rules.append(e.strip())
48 rules = new_rules
49 return rules
51 # Apply all rules on the objects names
52 def _apply_rules(name, rules):
53 r = name
54 if 'lower' in rules:
55 r = r.lower()
56 if 'nofqdn' in rules:
57 r = r.split('.')[0]
58 return r
60 # Get all vmware hosts from a VCenter and return the list
61 def get_vmware_hosts(check_esx_path, vcenter, user, password):
62 list_host_cmd_s = '%s -D %s -u %s -p %s -l runtime -s listhost' % (check_esx_path, vcenter, user, password)
63 list_host_cmd = shlex.split(list_host_cmd_s)
65 hosts = []
67 output = Popen(list_host_cmd, stdout=PIPE).communicate()
69 parts = output[0].split(':')
70 hsts_raw = parts[1].split('|')[0]
71 hsts_raw_lst = hsts_raw.split(',')
73 for hst_raw in hsts_raw_lst:
74 hst_raw = hst_raw.strip()
75 # look as server4.mydomain(UP)
76 elts = hst_raw.split('(')
77 hst = elts[0]
78 hosts.append(hst)
80 return hosts
83 # For a specific host, ask all VM on it to the VCenter
84 def get_vm_of_host(check_esx_path, vcenter, h, user, password):
85 lst = []
86 print "Listing host", h
87 list_vm_cmd_s = '%s -D %s -H %s -u %s -p %s -l runtime -s list' % (check_esx_path, vcenter, h, user, password)
88 list_vm_cmd = shlex.split(list_vm_cmd_s)
89 output = Popen(list_vm_cmd, stdout=PIPE).communicate()
90 parts = output[0].split(':')
91 # Maybe we got a 'CRITICAL - There are no VMs.' message,
92 # if so, we bypass this host
93 if len(parts) < 2:
94 return []
96 vms_raw = parts[1].split('|')[0]
97 vms_raw_lst = vms_raw.split(',')
99 for vm_raw in vms_raw_lst:
100 vm_raw = vm_raw.strip()
101 # look as MYVM(UP)
102 elts = vm_raw.split('(')
103 vm = elts[0]
104 lst.append(vm)
105 return lst
108 # Create all tuples of the links for the hosts
109 def create_all_links(res, rules):
110 r = []
111 for host in res:
112 for vm in res[host]:
113 # First we apply rules on the names
114 host_name = _apply_rules(host, rules)
115 vm_name = _apply_rules(vm, rules)
116 v = (('host', host_name),('host', vm_name))
117 r.append(v)
118 return r
121 def write_output(r, path):
122 try:
123 f = open(path+'.tmp', 'wb')
124 buf = json.dumps(r)
125 f.write(buf)
126 f.close()
127 shutil.move(path+'.tmp', path)
128 print "File %s wrote" % path
129 except IOError, exp:
130 print "Error writing the file %s : %s" % (path, exp)
131 sys.exit(2)
134 def main(check_esx_path, vcenter, user, password, output, rules):
135 rules = split_rules(rules)
136 res = {}
137 hosts = get_vmware_hosts(check_esx_path, vcenter, user, password)
139 for h in hosts:
140 lst = get_vm_of_host(check_esx_path, vcenter, h, user, password)
141 if lst != []:
142 res[h] = lst
144 r = create_all_links(res, rules)
145 print "Created %d links" % len(r)
147 write_output(r, output)
148 print "Finished!"
149 sys.exit(0)
152 VERSION = '0.1'
153 def usage(name):
154 print "Shinken VMware links dumping script version %s from :" % VERSION
155 print " Gabes Jean, naparuba@gmail.com"
156 print " Gerhard Lausser, Gerhard.Lausser@consol.de"
157 print "Usage: %s -V vcenter-ip -u USER -p PASSWORD -o /tmp/vmware_link.json [--esx3-path /full/path/check_esx3.pl --rules RULES" % name
158 print "Options:"
159 print " -V, --Vcenter"
160 print "\tThe IP/DNS address of your Vcenter host."
161 print " -u, --user"
162 print "\tUser name to connect to this Vcenter"
163 print " -p, --password"
164 print "\tThe password of this user"
165 print " -o, --output"
166 print "\tPath of the generated mapping file."
167 print " -x, --esx3-path"
168 print "\tFull path of the check_esx3.pl script. By default /usr/local/nagios/libexec/check_esx3.pl"
169 print " -r, --rules"
170 print "\t Rules of name transformation:"
171 print "\t\t lower : to lower names"
172 print "\t\t nofqdn : keep only the first name (server.mydomain.com -> server)"
173 print "\t\t you can use several rules like 'lower|nofqdn'"
174 print " -h, --help"
175 print "\tPrint detailed help screen"
176 print "\n"
177 print "Example :"
178 print "\t %s -V vcenter.google.com -user MySuperUser -password secret --esx3-path /usr/local/nagios/libexec/check_esx3.pl --rules 'lower|nofqdn'" % name
181 def check_args(check_esx_path, vcenter, user, password, output, rules):
182 error = False
183 if vcenter == None:
184 error = True
185 print "Error : missing -V or -Vcenter option for the vcenter IP/DNS address"
186 if user == None:
187 error = True
188 print "Error : missing -u or -user option for the vcenter username"
189 if password == None:
190 error = True
191 print "Error : missing -p or -password option for the vcenter password"
192 if not os.path.exists(check_esx_path):
193 error = True
194 print "Error : the path %s for the check_esx3.pl script is wrong, missing file"
195 if output == None:
196 error = True
197 print "Error : missing -o or -output option for the output mapping file"
199 if error:
200 print " ^"
201 print " |"
202 print " |"
203 print " |"
204 usage(sys.argv[0])
205 sys.exit(2)
207 # Here we go!
208 if __name__ == "__main__":
209 print sys.argv[1:]
210 # Manage the options
211 try:
212 opts, args = getopt.getopt(sys.argv[1:], "ho:x:V:u:p:r:", ["help", "output", "esx3-path", "Vcenter", "user", "password", "rules"])
213 except getopt.GetoptError, err:
214 # print help information and exit:
215 print str(err) # will print something like "option -a not recognized"
216 usage(sys.argv[0])
217 sys.exit(2)
218 print opts
219 # Default params
220 check_esx_path = '/usr/local/nagios/libexec/check_esx3.pl'
221 vcenter = None
222 user = None
223 password = None
224 rules = ''
225 output = None
226 for o, a in opts:
227 if o in ("-h", "--help"):
228 usage(sys.argv[0])
229 sys.exit()
230 elif o in ("-o", "--output"):
231 print "Got output", a
232 output = a
233 elif o in ("-x", "--esx3-path"):
234 check_esx_path = a
235 elif o in ("-V", "--Vcenter"):
236 vcenter = a
237 elif o in ("-u", "--user"):
238 user = a
239 elif o in ("-p", "--password"):
240 password = a
241 elif o in ('-r', '--rules'):
242 rules = a
243 else:
244 print "Sorry, the option", o, a, "is unknown"
245 usage(sys.argv[0])
246 sys.exit()
248 print "Got", check_esx_path, vcenter, user, password, output, rules
249 check_args(check_esx_path, vcenter, user, password, output, rules)
250 main(check_esx_path, vcenter, user, password, output, rules)