X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=monitor%2Fwrapper%2Fplc.py;h=ae378515838fd9503763e91b882d6ea51d4e1dd9;hb=HEAD;hp=f44abefebed06010ac14a581640ea8bec02b5e13;hpb=d37f2dbb7d89f898f2ad280472b1d71420b50612;p=monitor.git diff --git a/monitor/wrapper/plc.py b/monitor/wrapper/plc.py index f44abef..ae37851 100644 --- a/monitor/wrapper/plc.py +++ b/monitor/wrapper/plc.py @@ -12,7 +12,7 @@ import xml, xmlrpclib import logging import time import traceback -from monitor import database +from datetime import datetime # note: this needs to be consistent with the value in PLEWWW/planetlab/includes/plc_functions.php PENDING_CONSORTIUM_ID = 0 @@ -28,6 +28,21 @@ except: # NOTE: this host is used by default when there are no auth files. XMLRPC_SERVER="https://boot.planet-lab.org/PLCAPI/" +global_log_api = True +logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(levelname)s %(name)s : %(message)s', + datefmt='%s %Y-%m-%dT%H:%M:%S', + filename='/usr/share/monitor/myops-api-log.log', + filemode='a') +apilog = logging.getLogger("api") + +def log_api_call(name, *params): + logstr = "%s(" %name + for x in params: + logstr += "%s," % x + logstr = logstr[:-1] + ")" + if global_log_api: apilog.debug(logstr) + logger = logging.getLogger("monitor") class Auth: @@ -75,7 +90,11 @@ class PLC: raise AssertionError("method does not exist") try: - return lambda *params : method(self.auth, *params) + def call_method(aut, *params): + if global_log_api: log_api_call(name, *params) + return method(aut, *params) + return lambda *params : call_method(self.auth, *params) + #return lambda *params : method(self.auth, *params) except xmlrpclib.ProtocolError: traceback.print_exc() global_error_count += 1 @@ -90,54 +109,7 @@ class PLC: 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): @@ -173,7 +145,11 @@ def getTechEmails(loginbase): # 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) ] + emails = [] + for person in filter(lambda x: 'tech' in x['roles'], p): + if not isPersonExempt(person['email']): + emails.append(person['email']) + #emails = [ person['email'] for person in filter(lambda x: 'tech' in x['roles'], p) ] return emails def getPIEmails(loginbase): @@ -186,7 +162,11 @@ def getPIEmails(loginbase): # 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) ] + #emails = [ person['email'] for person in filter(lambda x: 'pi' in x['roles'], p) ] + emails = [] + for person in filter(lambda x: 'pi' in x['roles'], p): + if not isPersonExempt(person['email']): + emails.append(person['email']) return emails def getSliceUserEmails(loginbase): @@ -202,7 +182,13 @@ def getSliceUserEmails(loginbase): 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) ] + #emails = [ person['email'] for person in filter(lambda x: 'pi' in x['roles'], people) ] + + emails = [] + for person in people: + if not isPersonExempt(person['email']): + emails.append(person['email']) + unique_emails = [ x for x in set(emails) ] return unique_emails @@ -248,7 +234,11 @@ Returns dict of PCU info of a given node. def getpcu(nodename): api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True) anon = {'AuthMethod': "anonymous"} - nodeinfo = api.GetNodes(auth.auth, {"hostname": nodename}, ["pcu_ids", "ports"])[0] + try: + nodeinfo = api.GetNodes(auth.auth, {"hostname": nodename}, ["pcu_ids", "ports"])[0] + except IndexError: + logger.info("Can not find node: %s" % nodename) + return False if nodeinfo['pcu_ids']: print nodeinfo sitepcu = api.GetPCUs(auth.auth, nodeinfo['pcu_ids'])[0] @@ -336,7 +326,7 @@ def isPendingSite(loginbase): try: site = api.GetSites(auth.auth, loginbase)[0] except Exception, exc: - login.info("ERROR: No site %s" % loginbase) + logger.info("ERROR: No site %s" % loginbase) return False if not site['enabled'] and site['ext_consortium_id'] == PENDING_CONSORTIUM_ID: @@ -378,12 +368,19 @@ def nodePOD(nodename): Freeze all site slices. ''' def suspendSiteSlices(loginbase): + if isPendingSite(loginbase): + msg = "INFO: suspendSiteSlices: Pending Site (%s)" % loginbase + print msg + logger.info(msg) + return + 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") + if not isSliceExempt(slice): + api.AddSliceTag(auth.auth, slice, "enabled", "0") except Exception, exc: logger.info("suspendSlices: %s" % exc) @@ -391,16 +388,17 @@ def suspendSiteSlices(loginbase): Freeze all site slices. ''' def suspendSlices(nodename): - api = xmlrpclib.Server(auth.server, verbose=False) - for slice in slices(siteId(nodename)): - 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) + loginbase = siteId(nodename) + suspendSiteSlices(loginbase) + def enableSiteSlices(loginbase): + if isPendingSite(loginbase): + msg = "INFO: enableSiteSlices: Pending Site (%s)" % loginbase + print msg + logger.info(msg) + return + api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True) for slice in slices(loginbase): logger.info("Enabling slices %s" % slice) @@ -410,34 +408,19 @@ def enableSiteSlices(loginbase): if len(slice_list) == 0: return slice_id = slice_list[0]['slice_id'] - l_attr = api.GetSliceAttributes(auth.auth, {'slice_id': slice_id}, None) + l_attr = api.GetSliceTags(auth.auth, {'slice_id': slice_id}, None) for attr in l_attr: - if "enabled" == attr['name'] and attr['value'] == "0": + if "enabled" == attr['tagname'] and attr['value'] == "0": logger.info("Deleted enable=0 attribute from slice %s" % slice) - api.DeleteSliceAttribute(auth.auth, attr['slice_attribute_id']) + if not isSliceExempt(slice): + api.DeleteSliceTag(auth.auth, attr['slice_tag_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: - 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("enableSlices: %s" % exc) - print "exception: %s" % exc + loginbase = siteId(nodename) + enableSiteSlices(loginbase) #I'm commenting this because this really should be a manual process. @@ -448,51 +431,104 @@ def enableSlices(nodename): # api = xmlrpclib.Server(auth.server, verbose=False) # for slice in slices(siteId(nodename)): # logger.info("Suspending slice %s" % slice) -# api.SliceAttributeAdd(auth.auth, slice, "plc_slice_state", {"state" : "suspended"}) +# api.SliceTagAdd(auth.auth, slice, "plc_slice_state", {"state" : "suspended"}) # def enableSiteSliceCreation(loginbase): - if isPendingSite(loginbase): - msg = "INFO: enableSiteSliceCreation: Pending Site (%s)" % loginbase - print msg - logger.info(msg) - return + 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: 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}) + site = api.GetSites(auth.auth, loginbase)[0] + if site['enabled'] == False: + logger.info("\tcalling UpdateSite(%s, enabled=True)" % loginbase) + if not isSiteExempt(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) + loginbase = siteId(nodename) + enableSiteSliceCreation(loginbase) + +def areSlicesEnabled(site): + try: - loginbase = siteId(nodename) - enableSiteSliceCreation(loginbase) + slice_list = api.GetSlices(slices(site)) + if len(slice_list) == 0: + return None + for slice in slice_list: + slice_id = slice['slice_id'] + l_attr = api.GetSliceTags({'slice_id': slice_id}) + for attr in l_attr: + if "enabled" == attr['tagname'] and attr['value'] == "0": + return False + except Exception, exc: - print "ERROR: enableSliceCreation: %s" % exc - logger.info("ERROR: enableSliceCreation: %s" % exc) + pass + + return True + + +def isSiteEnabled(site): + try: + site = api.GetSites(site)[0] + return site['enabled'] + except: + pass + + return True + + +def isTagCurrent(tags): + if len(tags) > 0: + for tag in tags: + until = tag['value'] + if datetime.strptime(until, "%Y%m%d") > datetime.now(): + # NOTE: the 'exempt_until' time is beyond current time + return True + return False + +def isPersonExempt(email): + tags = api.GetPersonTags({'email' : email, 'tagname' : 'exempt_person_until'}) + return isTagCurrent(tags) + +def isNodeExempt(hostname): + tags = api.GetNodeTags({'hostname' : hostname, 'tagname' : 'exempt_node_until'}) + return isTagCurrent(tags) + +def isSliceExempt(slicename): + tags = api.GetSliceTags({'name' : slicename, 'tagname' : 'exempt_slice_until'}) + return isTagCurrent(tags) + +def isSiteExempt(loginbase): + tags = api.GetSiteTags({'login_base' : loginbase, 'tagname' : 'exempt_site_until'}) + return isTagCurrent(tags) ''' Removes site's ability to create slices. Returns previous max_slices ''' def removeSiteSliceCreation(loginbase): - print "removeSiteSliceCreation(%s)" % loginbase + #print "removeSiteSliceCreation(%s)" % loginbase - if isPendingSite(loginbase): - msg = "INFO: removeSiteSliceCreation: Pending Site (%s)" % loginbase - print msg - logger.info(msg) - return + if isPendingSite(loginbase): + msg = "INFO: removeSiteSliceCreation: Pending Site (%s)" % loginbase + print msg + logger.info(msg) + return api = xmlrpclib.Server(auth.server, verbose=False) try: logger.info("Removing slice creation for site %s" % loginbase) if not debug: - api.UpdateSite(auth.auth, loginbase, {'enabled': False}) + if not isSiteExempt(loginbase): + api.UpdateSite(auth.auth, loginbase, {'enabled': False}) except Exception, exc: logger.info("removeSiteSliceCreation: %s" % exc) @@ -500,13 +536,9 @@ def removeSiteSliceCreation(loginbase): Removes ability to create slices. Returns previous max_slices ''' def removeSliceCreation(nodename): - print "removeSliceCreation(%s)" % nodename - api = xmlrpclib.Server(auth.server, verbose=False) - try: - loginbase = siteId(nodename) - removeSiteSliceCreation(loginbase) - except Exception, exc: - logger.info("removeSliceCreation: %s" % exc) + loginbase = siteId(nodename) + removeSiteSliceCreation(loginbase) + ''' QED