X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=monitor%2Fwrapper%2Fplc.py;h=15c64bb081c01c3ba62a6c22eea867f80c675fdb;hb=f6000cab85e17057d58e885c094f78167f307c43;hp=76db7d8699dd6052d43930d2b8f621d2550fa8fb;hpb=0fabfc8dbe8f1f2c0d12397e1bc8c6ed686fb5ed;p=monitor.git diff --git a/monitor/wrapper/plc.py b/monitor/wrapper/plc.py index 76db7d8..15c64bb 100644 --- a/monitor/wrapper/plc.py +++ b/monitor/wrapper/plc.py @@ -15,18 +15,29 @@ 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. @@ -45,7 +56,7 @@ except: 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): @@ -58,11 +69,22 @@ class PLC: 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): @@ -81,6 +103,11 @@ class CachedPLC(PLC): 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 @@ -104,16 +131,33 @@ class CachedPLC(PLC): 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. @@ -144,7 +188,7 @@ def getSliceUserEmails(loginbase): """ For the given site, return all user email addresses that have the 'tech' role. """ - #api = getAuthAPI() + api = getAuthAPI() # get site details. s = api.GetSites(loginbase)[0] # get people at site @@ -201,7 +245,10 @@ def getpcu(nodename): 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: @@ -266,17 +313,40 @@ def getSiteNodes2(loginbase): 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 + +# Check if the site is a pending site that needs to be approved. +def isPendingSite(loginbase): + api = xmlrpclib.Server(auth.server, verbose=False) + try: + site = api.GetSites(auth.auth, loginbase)[0] + except Exception, exc: + login.info("ERROR: No site %s" % loginbase) + return False + + def all_disabled(person_ids): + persons = api.GetPersons(auth.auth, person_ids) + for person in persons: + if person['enabled']: + return False + return True + + if not site['max_slices'] and not site['node_ids'] and all_disabled(site['person_ids']): + return True + + return False + + ''' Sets boot state of a node. ''' @@ -306,6 +376,19 @@ def nodePOD(nodename): 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. ''' @@ -319,8 +402,28 @@ def suspendSlices(nodename): 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("Enabling slices %s" % slice) try: @@ -338,6 +441,7 @@ def enableSlices(nodename): logger.info("enableSlices: %s" % exc) print "exception: %s" % exc + #I'm commenting this because this really should be a manual process. #''' #Enable suspended site slices. @@ -348,18 +452,45 @@ def enableSlices(nodename): # logger.info("Suspending slice %s" % slice) # api.SliceAttributeAdd(auth.auth, slice, "plc_slice_state", {"state" : "suspended"}) # -def enableSliceCreation(nodename): +def enableSiteSliceCreation(loginbase): + if isPendingSite(loginbase): + msg = "INFO: enableSiteSliceCreation: Pending Site (%s)" % loginbase + print msg + logger.info(msg) + return + api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True) try: - loginbase = siteId(nodename) 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: + loginbase = siteId(nodename) + enableSiteSliceCreation(loginbase) except Exception, exc: 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 '''