82c7bf1be225fd3ce1111d5465a3c89395831808
[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
12 class PlcapiUrlScanner:
13
14     # turns out the config has an ip but no name..
15     def __init__ (self, auth, hostname=None, ip=None, verbose=False):
16         self.auth = auth
17         if not hostname and not ip:
18             raise Exception("PlcapiUrlScanner needs _some_ input")
19         if hostname:
20             if not ip: 
21                 try:
22                     ip = socket.gethostbyname(hostname)
23                 except: 
24                     hostname = "{}.pl.sophia.inria.fr".format(hostname)
25                     ip = socket.gethostbyname(hostname)
26         else:
27             hostname=socket.gethostbyaddr(ip)[0]
28         self.hostname = hostname
29         self.ip = ip
30         self.verbose = verbose
31         
32     def try_url (self, url):
33         try:
34             xmlrpc.client.ServerProxy (url, verbose=self.verbose, allow_none=True).GetNodes(self.auth)
35             print('YES', url)
36             return True
37         except xmlrpc.client.ProtocolError as e:
38             print('... (http error {})'.format(e.errcode), url)
39             return False
40         except Exception as e:
41             print('---', type(e).__name__, url, e)
42             if self.verbose:
43                 traceback.print_exc()
44             return False
45
46     def try_url_required (self, url, required):
47         result = self.try_url(url)
48         if required and not result:
49             return False
50         else:
51             return True
52
53     def scan(self):
54         overall = True
55         for protocol in ['http','https']:
56             for dest in [ self.hostname, self.ip ]:
57                 for port in [ '', ':80', ':443']:
58                     for path in ['PLCAPI', 'PLCAPI/']:
59                         if protocol=='http' and port==':443':
60                             continue
61                         if protocol=='https' and port==':80':
62                             continue
63                         required = (protocol=='https') and (path=='PLCAPI/')
64                         url="{}://{}{}/{}".format(protocol, dest, port, path)
65                         if not self.try_url_required (url,required):
66                             overall=False
67         return overall
68
69 from optparse import OptionParser
70 import sys
71
72 auth={'AuthMethod':'password','Username':'root@test.onelab.eu','AuthString':'test++'}
73
74 def main ():
75     usage = "%prog hostname"
76     parser = OptionParser()
77     parser.add_option("-v", "--verbose", dest='verbose', action='store_true', default=False)
78     (options,args) = parser.parse_args()
79     if len(args) != 1:
80         parser.print_help()
81         sys.exit(1)
82     hostname = args[0]
83     success = PlcapiUrlScanner (auth=auth, hostname=hostname,verbose=options.verbose).scan()
84     sys.exit(0 if success else -1)
85
86 if __name__ == '__main__':
87     main()