f37 -> f39
[infrastructure.git] / scripts / vsys_vnet_admin.py
1 #!/usr/bin/python
2
3 # vsys_vnet_admin.py - basic command-line client to show assigned network
4 # segments to the vsys_vnet tag in PlanetLab, and to assign new vsys_vnet tags
5 # using available segments
6
7 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
8 #
9
10 import ipaddr
11 from optparse import OptionParser
12 import os
13 import pprint
14 import sys
15 import xmlrpclib
16
17 def plapi(url):
18     """ Returns a XMLRPC proxy to the PLAPI service on the given url """
19     return xmlrpclib.ServerProxy(url, allow_none = True)
20
21 def get_assigned(plapi, auth):
22     """ Returns a dictionary with the assigned network segments as key
23     and the slice name as value"""
24     info = plapi.GetSliceTags(auth, {'tagname': 'vsys_vnet'}, ('name', 'value'))
25     return dict((d['value'], d['name']) for d in info)
26
27 def get_next_available(assigned, base, prefix):
28     """ Returns the next available network segment to be assigned to a 
29     new vsys_vnet tag """
30     net = ipaddr.IPNetwork(base)
31     iter_sub = net.iter_subnets(new_prefix=prefix)
32
33     try:
34         while True:
35             sub = iter_sub.next()
36             if not [ s for s in map(ipaddr.IPNetwork, assigned.keys()) \
37                     if sub == s or s in sub or sub in s]:
38                return sub.exploded 
39     except StopIteration:
40         pass
41
42     return None
43
44 def assign_vsys_vent(plapi, auth, vsys_vnet, pl_slice):
45     return plapi.AddSliceTag(auth, pl_slice, 'vsys_vnet', vsys_vnet)
46
47 if __name__ == "__main__":
48     pl_user = os.environ.get('PL_USER')
49     pl_pwd = os.environ.get('PL_PASS')
50     pl_url = "https://www.planet-lab.eu:443/PLCAPI/"
51     pl_slice = os.environ.get('PL_SLICE')
52
53     usage = """Usage: 
54    %prog : displays and check current assignments
55 or %prog -a -S <slicename> : assigns a range to slice <slicename>"""
56     parser = OptionParser(usage=usage)
57     parser.add_option("-u", "--user", dest="pl_user", help="PlanetLab account user name", default=pl_user)
58     parser.add_option("-p", "--password", dest="pl_pwd", help="PlanetLab account password", default=pl_pwd)
59     parser.add_option("-l", "--url", dest="pl_url", help="PlanetLab XMLRPC url", default=pl_url)
60     parser.add_option("-b", "--base", dest="basenet",
61                       help="Base network address to perform assignment (defaults to 10.0.0.0/8)", default="10.0.0.0/8")
62     parser.add_option("-n", "--prefix", dest="prefix", help="Network prefix for segments (defaults to 21)", default = "21")
63     parser.add_option("-a", "--assign", action="store_true", dest="assign", default=False,
64                       help="If specified, assign next available network segment as a vsys_vnet tag to the target slice")
65     parser.add_option("-S", "--slice", dest="pl_slice", default=pl_slice,
66                       help="target PlanetLab slice name, for --assign", )
67
68     (options, args) = parser.parse_args()
69    
70     if not options.pl_user or not options.pl_pwd:
71         print "Error: PlanetLab user and password are required to proceed."
72         sys.exit(1)
73
74     api = plapi(options.pl_url)
75     
76     auth = dict(AuthMethod='password', Username=options.pl_user, AuthString=options.pl_pwd)
77     assigned = get_assigned(api, auth)
78    
79     if options.assign:
80         vsys_vnet = get_next_available(assigned, options.basenet, int(options.prefix))
81         if not vsys_vnet:
82             print "Error: There are no available network segments at the moment to assign"
83             sys.exit(1)
84
85         print "The next available network segment is %s." % vsys_vnet
86         proceed = raw_input ("Do you wish to proceed with the assignment of the vsys_vnet tag? [y/N] ")
87         if proceed.lower() in ['yes', 'y']:
88             pl_slice = options.pl_slice
89             if not pl_slice:
90                 pl_slice = raw_input ("Please, enter your slice name \n")
91
92             if pl_slice in assigned.values():
93                 print "Error: This slice already has a tag vsys_vnet assigned!!!"
94                 sys.exit(1)
95
96             slice_tag_id = assign_vsys_vent(api, auth, vsys_vnet, pl_slice)
97
98             if slice_tag_id and slice_tag_id > 0:
99                 print "Success: the new slice tag id is %d" % slice_tag_id
100             else:
101                 print "Error: Something wrong happened!"
102
103     else:
104         pp = pprint.PrettyPrinter(indent=4)
105         pp.pprint(assigned)
106
107