#!/usr/bin/python # # vsys_vnet_admin.py - basic command-line client to show assigned network # segments to the vsys_vnet tag in PlanetLab, and to assign new vsys_vnet tags # using available segments # # Author: Alina Quereilhac # import ipaddr from optparse import OptionParser import os import pprint import sys import xmlrpclib def plapi(url): """ Returns a XMLRPC proxy to the PLAPI service on the given url """ return xmlrpclib.ServerProxy(url, allow_none = True) def get_assigned(plapi, auth): """ Returns a dictionary with the assigned network segments as key and the slice name as value""" info = plapi.GetSliceTags(auth, {'tagname': 'vsys_vnet'}, ('name', 'value')) return dict((d['value'], d['name']) for d in info) def get_next_available(assigned, base, prefix): """ Returns the next available network segment to be assigned to a new vsys_vnet tag """ net = ipaddr.IPNetwork(base) iter_sub = net.iter_subnets(new_prefix=prefix) try: while True: sub = iter_sub.next() if not [ s for s in map(ipaddr.IPNetwork, assigned.keys()) \ if sub == s or s in sub or sub in s]: return sub.exploded except StopIteration: pass return None def assign_vsys_vent(plapi, auth, vsys_vnet, pl_slice): return plapi.AddSliceTag(auth, pl_slice, 'vsys_vnet', vsys_vnet) if __name__ == "__main__": pl_user = os.environ.get('PL_USER') pl_pwd = os.environ.get('PL_PASS') pl_url = "https://www.planet-lab.eu:443/PLCAPI/" pl_slice = os.environ.get('PL_SLICE') usage = """Usage: %prog : displays and check current assignments or %prog -a -S : assigns a range to slice """ parser = OptionParser(usage=usage) parser.add_option("-u", "--user", dest="pl_user", help="PlanetLab account user name", default=pl_user) parser.add_option("-p", "--password", dest="pl_pwd", help="PlanetLab account password", default=pl_pwd) parser.add_option("-l", "--url", dest="pl_url", help="PlanetLab XMLRPC url", default=pl_url) parser.add_option("-b", "--base", dest="basenet", help="Base network address to perform assignment (defaults to 10.0.0.0/8)", default="10.0.0.0/8") parser.add_option("-n", "--prefix", dest="prefix", help="Network prefix for segments (defaults to 21)", default = "21") parser.add_option("-a", "--assign", action="store_true", dest="assign", default=False, help="If specified, assign next available network segment as a vsys_vnet tag to the target slice") parser.add_option("-S", "--slice", dest="pl_slice", default=pl_slice, help="target PlanetLab slice name, for --assign", ) (options, args) = parser.parse_args() if not options.pl_user or not options.pl_pwd: print "Error: PlanetLab user and password are required to proceed." sys.exit(1) api = plapi(options.pl_url) auth = dict(AuthMethod='password', Username=options.pl_user, AuthString=options.pl_pwd) assigned = get_assigned(api, auth) if options.assign: vsys_vnet = get_next_available(assigned, options.basenet, int(options.prefix)) if not vsys_vnet: print "Error: There are no available network segments at the moment to assign" sys.exit(1) print "The next available network segment is %s." % vsys_vnet proceed = raw_input ("Do you wish to proceed with the assignment of the vsys_vnet tag? [y/N] ") if proceed.lower() in ['yes', 'y']: pl_slice = options.pl_slice if not pl_slice: pl_slice = raw_input ("Please, enter your slice name \n") if pl_slice in assigned.values(): print "Error: This slice already has a tag vsys_vnet assigned!!!" sys.exit(1) slice_tag_id = assign_vsys_vent(api, auth, vsys_vnet, pl_slice) if slice_tag_id and slice_tag_id > 0: print "Success: the new slice tag id is %d" % slice_tag_id else: print "Error: Something wrong happened!" else: pp = pprint.PrettyPrinter(indent=4) pp.pprint(assigned)