explicity don't check for the server vertificate in plcapi_urls
[tests.git] / system / PlcapiUrlScanner.py
1 #!/usr/bin/env python
2 #
3 # this checks various forms of URLS for reaching a PLCAPI
4 # i.e. with http:// or https:// (only the latter is expected to work)
5 # with or without a trailing slash
6 # using a hostname or an IP
7
8 import socket
9 import xmlrpc.client
10 import traceback
11 import ssl
12
13 class PlcapiUrlScanner:
14
15     # turns out the config has an ip but no name..
16     def __init__ (self, auth, hostname=None, ip=None, verbose=False):
17         self.auth = auth
18         if not hostname and not ip:
19             raise Exception("PlcapiUrlScanner needs _some_ input")
20         if hostname:
21             if not ip: 
22                 try:
23                     ip = socket.gethostbyname(hostname)
24                 except: 
25                     hostname = "{}.pl.sophia.inria.fr".format(hostname)
26                     ip = socket.gethostbyname(hostname)
27         else:
28             hostname=socket.gethostbyaddr(ip)[0]
29         self.hostname = hostname
30         self.ip = ip
31         self.verbose = verbose
32         
33     def try_url (self, url):
34         try:
35             proxy = xmlrpc.client.ServerProxy(url, verbose=self.verbose, allow_none=True,
36                                               context=ssl._create_unverified_context())
37             nodes = proxy.GetNodes(self.auth)
38             print('YES', url)
39             return True
40         except xmlrpc.client.ProtocolError as e:
41             print('... (http error {})'.format(e.errcode), url)
42             return False
43         except Exception as e:
44             print('---', type(e).__name__, url, e)
45             if self.verbose:
46                 traceback.print_exc()
47             return False
48
49     def try_url_required (self, url, required):
50         result = self.try_url(url)
51         if required and not result:
52             return False
53         else:
54             return True
55
56     def scan(self):
57         overall = True
58         for protocol in ['http','https']:
59             for dest in [ self.hostname, self.ip ]:
60                 for port in [ '', ':80', ':443']:
61                     for path in ['PLCAPI', 'PLCAPI/']:
62                         if protocol=='http' and port==':443':
63                             continue
64                         if protocol=='https' and port==':80':
65                             continue
66                         required = (protocol=='https') and (path=='PLCAPI/')
67                         url="{}://{}{}/{}".format(protocol, dest, port, path)
68                         if not self.try_url_required (url,required):
69                             overall=False
70         return overall
71
72 from optparse import OptionParser
73 import sys
74
75 auth={'AuthMethod':'password','Username':'root@test.onelab.eu','AuthString':'test++'}
76
77 def main ():
78     usage = "%prog hostname"
79     parser = OptionParser()
80     parser.add_option("-v", "--verbose", dest='verbose', action='store_true', default=False)
81     (options,args) = parser.parse_args()
82     if len(args) != 1:
83         parser.print_help()
84         sys.exit(1)
85     hostname = args[0]
86     success = PlcapiUrlScanner (auth=auth, hostname=hostname,verbose=options.verbose).scan()
87     sys.exit(0 if success else -1)
88
89 if __name__ == '__main__':
90     main()