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
-APPROVED_CONSORTIUM_ID = 999999
+# not used in monitor
+#APPROVED_CONSORTIUM_ID = 999999
try:
from monitor import config
# 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:
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
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):
# 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):
# 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):
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
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]
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:
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)
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)
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.
# 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)
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