Fix : fix hot module under windows test. (at leat I hope...)
[shinken.git] / libexec / vmware_discovery_runner.py
blob8f075d88933849810acb88e70281f4bf6b990692
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
6 # Hartmut Goebel <h.goebel@goebel-consult.de>
8 #This file is part of Shinken.
10 #Shinken is free software: you can redistribute it and/or modify
11 #it under the terms of the GNU Affero General Public License as published by
12 #the Free Software Foundation, either version 3 of the License, or
13 #(at your option) any later version.
15 #Shinken is distributed in the hope that it will be useful,
16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 #GNU Affero General Public License for more details.
20 #You should have received a copy of the GNU Affero General Public License
21 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
23 import os
24 import sys
25 import shlex
26 import shutil
27 import optparse
28 from subprocess import Popen, PIPE
30 # Try to load json (2.5 and higer) or simplejson if failed (python2.4)
31 try:
32 import json
33 except ImportError:
34 # For old Python version, load
35 # simple json (it can be hard json?! It's 2 functions guy!)
36 try:
37 import simplejson as json
38 except ImportError:
39 sys.exit("Error : you need the json or simplejson module for this script")
41 VERSION = '0.1'
43 # Search if we can findthe check_esx3.pl file somewhere
44 def search_for_check_esx3():
45 me = os.path.abspath( __file__ )
46 my_dir = os.path.dirname(me)
47 possible_paths = [os.path.join(my_dir, 'check_esx3.pl'),
48 '/var/lib/nagios/check_esx3.pl',
49 '/var/lib/shinken/check_esx3.pl',
50 '/usr/local/nagios/libexec/check_esx3.pl',
51 '/usr/local/shinken/libexec/check_esx3.pl',
52 'c:\\shinken\\libexec\\check_esx3.pl']
54 for p in possible_paths:
55 print "Look for", p
56 if os.path.exists(p):
57 print "Found a check_esx3.pl at", p
58 return p
59 return None
62 # Split and clean the rules from a string to a list
63 def _split_rules(rules):
64 return [r.strip() for r in rules.split('|')]
66 # Apply all rules on the objects names
67 def _apply_rules(name, rules):
68 if 'nofqdn' in rules:
69 name = name.split('.', 1)[0]
70 if 'lower' in rules:
71 name = name.lower()
72 return name
74 # Get all vmware hosts from a VCenter and return the list
75 def get_vmware_hosts(check_esx_path, vcenter, user, password):
76 list_host_cmd = [check_esx_path, '-D', vcenter, '-u', user, '-p', password,
77 '-l', 'runtime', '-s', 'listhost']
79 print "Got host list"
80 print ' '.join(list_host_cmd)
81 p = Popen(list_host_cmd, stdout=PIPE, stderr=PIPE)
82 output = p.communicate()
84 print "Exit status", p.returncode
85 if p.returncode == 2:
86 print "Error : the check_esx3.pl return in error :", output
87 sys.exit(2)
89 parts = output[0].split(':')
90 hsts_raw = parts[1].split('|')[0]
91 hsts_raw_lst = hsts_raw.split(',')
93 hosts = []
94 for hst_raw in hsts_raw_lst:
95 hst_raw = hst_raw.strip()
96 # look as server4.mydomain(UP)
97 elts = hst_raw.split('(')
98 hst = elts[0]
99 hosts.append(hst)
101 return hosts
104 # For a specific host, ask all VM on it to the VCenter
105 def get_vm_of_host(check_esx_path, vcenter, host, user, password):
106 print "Listing host", host
107 list_vm_cmd = [check_esx_path, '-D', vcenter, '-H', host,
108 '-u', user, '-p', password,
109 '-l', 'runtime', '-s', 'list']
110 print ' '.join(list_vm_cmd)
111 p = Popen(list_vm_cmd, stdout=PIPE)
112 output = p.communicate()
114 print "Exit status", p.returncode
115 if p.returncode == 2:
116 print "Error : the check_esx3.pl return in error :", output
117 sys.exit(2)
119 parts = output[0].split(':')
120 # Maybe we got a 'CRITICAL - There are no VMs.' message,
121 # if so, we bypass this host
122 if len(parts) < 2:
123 return None
125 vms_raw = parts[1].split('|')[0]
126 vms_raw_lst = vms_raw.split(',')
128 lst = []
129 for vm_raw in vms_raw_lst:
130 vm_raw = vm_raw.strip()
131 # look as MYVM(UP)
132 elts = vm_raw.split('(')
133 vm = elts[0]
134 lst.append(vm)
135 return lst
138 # Create all tuples of the links for the hosts
139 def print_all_links(res, rules):
140 r = []
141 for host in res:
142 host_name = _apply_rules(host, rules)
143 print "%s::isesxhost=1" % host_name
144 for vm in res[host]:
145 # First we apply rules on the names
146 vm_name = _apply_rules(vm, rules)
147 #v = (('host', host_name),('host', vm_name))
148 print "%s::isesxvm=1" % vm_name
149 print "%s::esxhost=%s" % (vm_name, host_name)
150 #r.append(v)
151 return r
154 def write_output(r, path):
155 try:
156 f = open(path+'.tmp', 'wb')
157 buf = json.dumps(r)
158 f.write(buf)
159 f.close()
160 shutil.move(path+'.tmp', path)
161 print "File %s wrote" % path
162 except IOError, exp:
163 sys.exit("Error writing the file %s : %s" % (path, exp))
166 def main(check_esx_path, vcenter, user, password, rules):
167 rules = _split_rules(rules)
168 res = {}
169 hosts = get_vmware_hosts(check_esx_path, vcenter, user, password)
171 for host in hosts:
172 lst = get_vm_of_host(check_esx_path, vcenter, host, user, password)
173 if lst:
174 res[host] = lst
177 print_all_links(res, rules)
179 #write_output(r, output)
180 print "Finished!"
183 # Here we go!
184 if __name__ == "__main__":
185 # Manage the options
186 parser = optparse.OptionParser(
187 version="Shinken VMware links dumping script version %s" % VERSION)
188 parser.add_option("-x", "--esx3-path", dest='check_esx_path',
189 default='/usr/local/nagios/libexec/check_esx3.pl',
190 help="Full path of the check_esx3.pl script (default: %default)")
191 parser.add_option("-V", "--vcenter", '--Vcenter',
192 help="tThe IP/DNS address of your Vcenter host.")
193 parser.add_option("-u", "--user",
194 help="User name to connect to this Vcenter")
195 parser.add_option("-p", "--password",
196 help="The password of this user")
197 parser.add_option('-r', '--rules', default='',
198 help="Rules of name transformation. Valid names are: "
199 "`lower`: to lower names, "
200 "`nofqdn`: keep only the first name (server.mydomain.com -> server)."
201 "You can use several rules like `lower|nofqdn`")
203 opts, args = parser.parse_args()
204 if args:
205 parser.error("does not take any positional arguments")
207 if opts.vcenter is None:
208 parser.error("missing -V or --Vcenter option for the vcenter IP/DNS address")
209 if opts.user is None:
210 parser.error("missing -u or --user option for the vcenter username")
211 if opts.password is None:
212 error = True
213 parser.error("missing -p or --password option for the vcenter password")
214 if not os.path.exists(opts.check_esx_path):
215 parser.error("the path %s for the check_esx3.pl script is wrong, missing file" % opts.check_esx_path)
216 else:
217 # Not given, try to find one
218 p = search_for_check_esx3()
219 if p is None:
220 parser.error("Sorry, I cannot find check_esx3.pl, please specify it with -x")
221 #else set it :)
222 opts.check_esx_path = p
224 main(**opts.__dict__)