import logging
import time
import traceback
+from monitor import database
+
try:
- import config
+ from monitor import config
debug = config.debug
+ XMLRPC_SERVER=config.API_SERVER
except:
debug = False
+ # NOTE: this host is used by default when there are no auth files.
+ XMLRPC_SERVER="https://boot.planet-lab.org/PLCAPI/"
+
logger = logging.getLogger("monitor")
class Auth:
- def __init__(self):
- self.auth = {'AuthMethod': "anonymous"}
+ def __init__(self, username=None, password=None, **kwargs):
+ if 'session' in kwargs:
+ self.auth= { 'AuthMethod' : 'session',
+ 'session' : kwargs['session'] }
+ else:
+ if username==None and password==None:
+ self.auth = {'AuthMethod': "anonymous"}
+ else:
+ self.auth = {'Username' : username,
+ 'AuthMethod' : 'password',
+ 'AuthString' : password}
-# NOTE: this host is used by default when there are no auth files.
-XMLRPC_SERVER="https://boot.planet-lab.org/PLCAPI/"
# NOTE: by default, use anonymous access, but if auth files are
# configured, use them, with their auth definitions.
auth = Auth()
auth.server = XMLRPC_SERVER
-api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
+global_error_count = 0
class PLC:
def __init__(self, auth, url):
if method is None:
raise AssertionError("method does not exist")
- return lambda *params : method(self.auth, *params)
+ try:
+ return lambda *params : method(self.auth, *params)
+ except xmlrpclib.ProtocolError:
+ traceback.print_exc()
+ global_error_count += 1
+ if global_error_count >= 10:
+ print "maximum error count exceeded; exiting..."
+ sys.exit(1)
+ else:
+ print "%s errors have occurred" % global_error_count
+ raise Exception("ProtocolError continuing")
def __repr__(self):
return self.api.__repr__()
+
+class CachedPLC(PLC):
+
+ def _param_to_str(self, name, *params):
+ fields = len(params)
+ retstr = ""
+ retstr += "%s-" % name
+ for x in params:
+ retstr += "%s-" % x
+ return retstr[:-1]
+
+ def __getattr__(self, name):
+ method = getattr(self.api, name)
+ if method is None:
+ raise AssertionError("method does not exist")
+
+ def run_or_returncached(*params):
+ cachename = self._param_to_str(name, *params)
+ #print "cachename is %s" % cachename
+ if hasattr(config, 'refresh'):
+ refresh = config.refresh
+ else:
+ refresh = False
+
+ if 'Get' in name:
+ if not database.cachedRecently(cachename):
+ load_old_cache = False
+ try:
+ values = method(self.auth, *params)
+ except:
+ print "Call %s FAILED: Using old cached data" % cachename
+ load_old_cache = True
+
+ if load_old_cache:
+ values = database.dbLoad(cachename)
+ else:
+ database.dbDump(cachename, values)
+
+ return values
+ else:
+ values = database.dbLoad(cachename)
+ return values
+ else:
+ return method(self.auth, *params)
+
+ return run_or_returncached
+
+api = PLC(auth.auth, auth.server)
+cacheapi = CachedPLC(auth.auth, auth.server)
+
+
def getAPI(url):
return xmlrpclib.Server(url, verbose=False, allow_none=True)
-def getAuthAPI():
- return PLC(auth.auth, auth.server)
+def getNodeAPI(session):
+ nodeauth = Auth(session=session)
+ return PLC(nodeauth.auth, auth.server)
+
+def getAuthAPI(url=None):
+ if url:
+ return PLC(auth.auth, url)
+ else:
+ return PLC(auth.auth, auth.server)
+
+def getCachedAuthAPI():
+ return CachedPLC(auth.auth, auth.server)
+
+def getSessionAPI(session, server):
+ nodeauth = Auth(session=session)
+ return PLC(nodeauth.auth, server)
+def getUserAPI(username, password, server):
+ auth = Auth(username,password)
+ return PLC(auth.auth, server)
+
+def getTechEmails(loginbase):
+ """
+ For the given site, return all user email addresses that have the 'tech' role.
+ """
+ api = getAuthAPI()
+ # get site details.
+ s = api.GetSites(loginbase)[0]
+ # get people at site
+ p = api.GetPersons(s['person_ids'])
+ # pull out those with the right role.
+ emails = [ person['email'] for person in filter(lambda x: 'tech' in x['roles'], p) ]
+ return emails
+
+def getPIEmails(loginbase):
+ """
+ For the given site, return all user email addresses that have the 'tech' role.
+ """
+ api = getAuthAPI()
+ # get site details.
+ s = api.GetSites(loginbase)[0]
+ # get people at site
+ p = api.GetPersons(s['person_ids'])
+ # pull out those with the right role.
+ emails = [ person['email'] for person in filter(lambda x: 'pi' in x['roles'], p) ]
+ return emails
+
+def getSliceUserEmails(loginbase):
+ """
+ For the given site, return all user email addresses that have the 'tech' role.
+ """
+ api = getAuthAPI()
+ # get site details.
+ s = api.GetSites(loginbase)[0]
+ # get people at site
+ slices = api.GetSlices(s['slice_ids'])
+ people = []
+ for slice in slices:
+ people += api.GetPersons(slice['person_ids'])
+ # pull out those with the right role.
+ emails = [ person['email'] for person in filter(lambda x: 'pi' in x['roles'], people) ]
+ unique_emails = [ x for x in set(emails) ]
+ return unique_emails
'''
Returns list of nodes in dbg as reported by PLC
Returns loginbase for given nodename
'''
def siteId(nodename):
- api = xmlrpclib.Server(auth.server, verbose=False)
- anon = {'AuthMethod': "anonymous"}
- site_id = api.GetNodes (anon, {"hostname": nodename}, ['site_id'])
+ api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
+ site_id = api.GetNodes (auth.auth, {"hostname": nodename}, ['site_id'])
if len(site_id) == 1:
- loginbase = api.GetSites (anon, site_id[0], ["login_base"])
+ loginbase = api.GetSites (auth.auth, site_id[0], ["login_base"])
return loginbase[0]['login_base']
+ else:
+ print "Not nodes returned!!!!"
'''
Returns list of slices for a site.
'''
def slices(loginbase):
siteslices = []
- api = xmlrpclib.Server(auth.server, verbose=False)
+ api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
sliceids = api.GetSites (auth.auth, {"login_base" : loginbase}, ["slice_ids"])[0]['slice_ids']
for slice in api.GetSlices(auth.auth, {"slice_id" : sliceids}, ["name"]):
siteslices.append(slice['name'])
Returns dict of PCU info of a given node.
'''
def getpcu(nodename):
- api = xmlrpclib.Server(auth.server, verbose=False)
+ api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
anon = {'AuthMethod': "anonymous"}
nodeinfo = api.GetNodes(auth.auth, {"hostname": nodename}, ["pcu_ids", "ports"])[0]
if nodeinfo['pcu_ids']:
+ print nodeinfo
sitepcu = api.GetPCUs(auth.auth, nodeinfo['pcu_ids'])[0]
+ print sitepcu
+ print nodeinfo["ports"]
sitepcu[nodename] = nodeinfo["ports"][0]
return sitepcu
else:
print "getSiteNodes: %s" % exc
return nodelist
+
def getPersons(filter=None, fields=None):
api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
persons = []
def getNodeNetworks(filter=None):
api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
- nodenetworks = api.GetNodeNetworks(auth.auth, filter, None)
+ nodenetworks = api.GetInterfaces(auth.auth, filter, None)
return nodenetworks
def getNodes(filter=None, fields=None):
api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
nodes = api.GetNodes(auth.auth, filter, fields)
#['boot_state', 'hostname',
- #'site_id', 'date_created', 'node_id', 'version', 'nodenetwork_ids',
+ #'site_id', 'date_created', 'node_id', 'version', 'interface_ids',
#'last_updated', 'peer_node_id', 'ssh_rsa_key' ])
return nodes
except Exception, exc:
logger.info("nodePOD: %s" % exc)
+'''
+Freeze all site slices.
+'''
+def suspendSiteSlices(loginbase):
+ api = xmlrpclib.Server(auth.server, verbose=False)
+ for slice in slices(loginbase):
+ logger.info("Suspending slice %s" % slice)
+ try:
+ if not debug:
+ api.AddSliceAttribute(auth.auth, slice, "enabled", "0")
+ except Exception, exc:
+ logger.info("suspendSlices: %s" % exc)
+
'''
Freeze all site slices.
'''
except Exception, exc:
logger.info("suspendSlices: %s" % exc)
+def enableSiteSlices(loginbase):
+ api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
+ for slice in slices(loginbase):
+ logger.info("Enabling slices %s" % slice)
+ try:
+ if not debug:
+ slice_list = api.GetSlices(auth.auth, {'name': slice}, None)
+ if len(slice_list) == 0:
+ return
+ slice_id = slice_list[0]['slice_id']
+ l_attr = api.GetSliceAttributes(auth.auth, {'slice_id': slice_id}, None)
+ for attr in l_attr:
+ if "enabled" == attr['name'] and attr['value'] == "0":
+ logger.info("Deleted enable=0 attribute from slice %s" % slice)
+ api.DeleteSliceAttribute(auth.auth, attr['slice_attribute_id'])
+ except Exception, exc:
+ logger.info("enableSiteSlices: %s" % exc)
+ print "exception: %s" % exc
+
def enableSlices(nodename):
api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
for slice in slices(siteId(nodename)):
# logger.info("Suspending slice %s" % slice)
# api.SliceAttributeAdd(auth.auth, slice, "plc_slice_state", {"state" : "suspended"})
#
+def enableSiteSliceCreation(loginbase):
+ api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
+ try:
+ logger.info("Enabling slice creation for site %s" % loginbase)
+ if not debug:
+ logger.info("\tcalling UpdateSite(%s, enabled=True)" % loginbase)
+ api.UpdateSite(auth.auth, loginbase, {'enabled': True})
+ except Exception, exc:
+ print "ERROR: enableSiteSliceCreation: %s" % exc
+ logger.info("ERROR: enableSiteSliceCreation: %s" % exc)
+
def enableSliceCreation(nodename):
api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
try:
print "ERROR: enableSliceCreation: %s" % exc
logger.info("ERROR: enableSliceCreation: %s" % exc)
+'''
+Removes site's ability to create slices. Returns previous max_slices
+'''
+def removeSiteSliceCreation(sitename):
+ print "removeSiteSliceCreation(%s)" % sitename
+ api = xmlrpclib.Server(auth.server, verbose=False)
+ try:
+ logger.info("Removing slice creation for site %s" % sitename)
+ if not debug:
+ api.UpdateSite(auth.auth, sitename, {'enabled': False})
+ except Exception, exc:
+ logger.info("removeSiteSliceCreation: %s" % exc)
+
'''
Removes ability to create slices. Returns previous max_slices
'''