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/>.
28 from subprocess
import Popen
, PIPE
30 # Try to load json (2.5 and higer) or simplejson if failed (python2.4)
34 # For old Python version, load
35 # simple json (it can be hard json?! It's 2 functions guy!)
37 import simplejson
as json
39 sys
.exit("Error : you need the json or simplejson module for this script")
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
:
57 print "Found a check_esx3.pl at", p
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
):
69 name
= name
.split('.', 1)[0]
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']
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
86 print "Error : the check_esx3.pl return in error :", output
89 parts
= output
[0].split(':')
90 hsts_raw
= parts
[1].split('|')[0]
91 hsts_raw_lst
= hsts_raw
.split(',')
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('(')
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
119 parts
= output
[0].split(':')
120 # Maybe we got a 'CRITICAL - There are no VMs.' message,
121 # if so, we bypass this host
125 vms_raw
= parts
[1].split('|')[0]
126 vms_raw_lst
= vms_raw
.split(',')
129 for vm_raw
in vms_raw_lst
:
130 vm_raw
= vm_raw
.strip()
132 elts
= vm_raw
.split('(')
138 # Create all tuples of the links for the hosts
139 def print_all_links(res
, rules
):
142 host_name
= _apply_rules(host
, rules
)
143 print "%s::isesxhost=1" % host_name
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
)
154 def write_output(r
, path
):
156 f
= open(path
+'.tmp', 'wb')
160 shutil
.move(path
+'.tmp', path
)
161 print "File %s wrote" % path
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
)
169 hosts
= get_vmware_hosts(check_esx_path
, vcenter
, user
, password
)
172 lst
= get_vm_of_host(check_esx_path
, vcenter
, host
, user
, password
)
177 print_all_links(res
, rules
)
179 #write_output(r, output)
184 if __name__
== "__main__":
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()
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:
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
)
217 # Not given, try to find one
218 p
= search_for_check_esx3()
220 parser
.error("Sorry, I cannot find check_esx3.pl, please specify it with -x")
222 opts
.check_esx_path
= p
224 main(**opts
.__dict
__)