make plc.py simpler to reduce the dependencies for plc_hosts_to_nagios.
[monitor.git] / monitor / wrapper / plc.py
index 68eb11a..8eba805 100644 (file)
@@ -12,13 +12,21 @@ import xml, xmlrpclib
 import logging
 import time
 import traceback
 import logging
 import time
 import traceback
-from monitor import database
+
+# note: this needs to be consistent with the value in PLEWWW/planetlab/includes/plc_functions.php
+PENDING_CONSORTIUM_ID = 0
+# not used in monitor
+#APPROVED_CONSORTIUM_ID = 999999
 
 try:
        from monitor import config
        debug = config.debug
 
 try:
        from monitor import config
        debug = config.debug
+       XMLRPC_SERVER=config.API_SERVER
 except:
        debug = False
 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:
 logger = logging.getLogger("monitor")
        
 class Auth:
@@ -34,8 +42,6 @@ class Auth:
                                                        'AuthMethod' : 'password',
                                                        'AuthString' : password}
 
                                                        '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.
 
 # NOTE: by default, use anonymous access, but if auth files are 
 #       configured, use them, with their auth definitions.
@@ -54,7 +60,7 @@ except:
                auth = Auth()
                auth.server = XMLRPC_SERVER
 
                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):
 
 class PLC:
        def __init__(self, auth, url):
@@ -67,56 +73,23 @@ class PLC:
                if method is None:
                        raise AssertionError("method does not exist")
 
                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__()
 
 
        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)
 
 
 def getAPI(url):
 
 
 def getAPI(url):
@@ -126,12 +99,22 @@ def getNodeAPI(session):
        nodeauth = Auth(session=session)
        return PLC(nodeauth.auth, auth.server)
 
        nodeauth = Auth(session=session)
        return PLC(nodeauth.auth, auth.server)
 
-def getAuthAPI():
-       return PLC(auth.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 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.
 def getTechEmails(loginbase):
        """
                For the given site, return all user email addresses that have the 'tech' role.
@@ -162,7 +145,7 @@ def getSliceUserEmails(loginbase):
        """
                For the given site, return all user email addresses that have the 'tech' role.
        """
        """
                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
        # get site details.
        s = api.GetSites(loginbase)[0]
        # get people at site
@@ -217,7 +200,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"}
 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]
        if nodeinfo['pcu_ids']:
                print nodeinfo
                sitepcu = api.GetPCUs(auth.auth, nodeinfo['pcu_ids'])[0]
@@ -287,17 +274,33 @@ def getSiteNodes2(loginbase):
 
 def getNodeNetworks(filter=None):
        api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
 
 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', 
        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
 
                        #'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:
+                logger.info("ERROR: No site %s" % loginbase)
+                return False
+
+        if not site['enabled'] and site['ext_consortium_id'] == PENDING_CONSORTIUM_ID:
+                return True
+
+        return False
+
+
 '''
 Sets boot state of a node.
 '''
 '''
 Sets boot state of a node.
 '''
@@ -330,9 +333,15 @@ def nodePOD(nodename):
 '''
 Freeze all site slices.
 '''
 '''
 Freeze all site slices.
 '''
-def suspendSlices(nodename):
+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)
        api = xmlrpclib.Server(auth.server, verbose=False)
-       for slice in slices(siteId(nodename)):
+       for slice in slices(loginbase):
                logger.info("Suspending slice %s" % slice)
                try:
                        if not debug:
                logger.info("Suspending slice %s" % slice)
                try:
                        if not debug:
@@ -340,9 +349,23 @@ def suspendSlices(nodename):
                except Exception, exc:
                        logger.info("suspendSlices:  %s" % exc)
 
                except Exception, exc:
                        logger.info("suspendSlices:  %s" % exc)
 
-def enableSlices(nodename):
+'''
+Freeze all site slices.
+'''
+def suspendSlices(nodename):
+        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)
        api = xmlrpclib.Server(auth.server, verbose=False, allow_none=True)
-       for slice in slices(siteId(nodename)):
+       for slice in slices(loginbase):
                logger.info("Enabling slices %s" % slice)
                try:
                        if not debug:
                logger.info("Enabling slices %s" % slice)
                try:
                        if not debug:
@@ -356,9 +379,14 @@ def enableSlices(nodename):
                                                logger.info("Deleted enable=0 attribute from slice %s" % slice)
                                                api.DeleteSliceAttribute(auth.auth, attr['slice_attribute_id'])
                except Exception, exc:
                                                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)
+                       logger.info("enableSiteSlices: %s" % exc)
                        print "exception: %s" % exc
 
                        print "exception: %s" % exc
 
+def enableSlices(nodename):
+        loginbase = siteId(nodename)
+        enableSiteSlices(loginbase)
+
+
 #I'm commenting this because this really should be a manual process.  
 #'''
 #Enable suspended site slices.
 #I'm commenting this because this really should be a manual process.  
 #'''
 #Enable suspended site slices.
@@ -369,34 +397,56 @@ def enableSlices(nodename):
 #              logger.info("Suspending slice %s" % slice)
 #              api.SliceAttributeAdd(auth.auth, slice, "plc_slice_state", {"state" : "suspended"})
 #
 #              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:
        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("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)
+                               api.UpdateSite(auth.auth, loginbase, {'enabled': True})
        except Exception, exc:
        except Exception, exc:
-               print "ERROR: enableSliceCreation:  %s" % exc
-               logger.info("ERROR: enableSliceCreation:  %s" % exc)
+               print "ERROR: enableSiteSliceCreation:  %s" % exc
+               logger.info("ERROR: enableSiteSliceCreation:  %s" % exc)
+
+def enableSliceCreation(nodename):
+        loginbase = siteId(nodename)
+        enableSiteSliceCreation(loginbase)
 
 '''
 
 '''
-Removes ability to create slices. Returns previous max_slices
+Removes site's ability to create slices. Returns previous max_slices
 '''
 '''
-def removeSliceCreation(nodename):
-       print "removeSliceCreation(%s)" % nodename
+def removeSiteSliceCreation(loginbase):
+       print "removeSiteSliceCreation(%s)" % loginbase
+
+       if isPendingSite(loginbase):
+               msg = "INFO: removeSiteSliceCreation: Pending Site (%s)" % loginbase
+               print msg
+               logger.info(msg)
+               return
+
        api = xmlrpclib.Server(auth.server, verbose=False)
        try:
        api = xmlrpclib.Server(auth.server, verbose=False)
        try:
-               loginbase = siteId(nodename)
-               #numslices = api.GetSites(auth.auth, {"login_base": loginbase}, 
-               #               ["max_slices"])[0]['max_slices']
                logger.info("Removing slice creation for site %s" % loginbase)
                if not debug:
                logger.info("Removing slice creation for site %s" % loginbase)
                if not debug:
-                       #api.UpdateSite(auth.auth, loginbase, {'max_slices': 0})
                        api.UpdateSite(auth.auth, loginbase, {'enabled': False})
        except Exception, exc:
                        api.UpdateSite(auth.auth, loginbase, {'enabled': False})
        except Exception, exc:
-               logger.info("removeSliceCreation:  %s" % exc)
+               logger.info("removeSiteSliceCreation:  %s" % exc)
+
+'''
+Removes ability to create slices. Returns previous max_slices
+'''
+def removeSliceCreation(nodename):
+        loginbase = siteId(nodename)
+        removeSiteSliceCreation(loginbase)
+
 
 '''
 QED
 
 '''
 QED