Package backend :: Package server :: Package handlers :: Package xmlrpc :: Module getMethod
[hide private]
[frames] | no frames]

Source Code for Module backend.server.handlers.xmlrpc.getMethod

  1  # Retrieve action method name given queued action information. 
  2  # 
  3  # Client code for Update Agent 
  4  # 
  5  # Copyright (c) 2008--2016 Red Hat, Inc. 
  6  # 
  7  # This software is licensed to you under the GNU General Public License, 
  8  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  9  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
 10  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
 11  # along with this software; if not, see 
 12  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 13  # 
 14  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 15  # granted to use or replicate Red Hat trademarks that are incorporated 
 16  # in this software or its documentation. 
 17  # 
 18  # 
 19  # An allowable xmlrpc method is retrieved given a base location, a 
 20  # hierarchical route to the class/module, and method name. 
 21  # 
 22   
 23  import os 
 24  import string 
 25  import sys 
 26  from spacewalk.common.usix import ClassType 
 27  from distutils.sysconfig import get_python_lib 
 28   
 29  from spacewalk.common.usix import raise_with_tb 
 30   
31 -class GetMethodException(Exception):
32 33 """Exception class""" 34 pass
35 36
37 -def sanity(methodNameComps):
38 """ Verifies if all the components have proper names.""" 39 # Allowed characters in each string 40 alpha = string.lowercase + string.uppercase 41 allowedChars = alpha + string.digits + '_' 42 for comp in methodNameComps: 43 if not len(comp): 44 raise GetMethodException("Empty method component") 45 for c in comp: 46 if c not in allowedChars: 47 raise GetMethodException( 48 "Invalid character '%s' in the method name" % c) 49 # Can only begin with a letter 50 if comp[0] not in alpha: 51 raise GetMethodException( 52 "Method names should start with an alphabetic character")
53 54
55 -def getMethod(methodName, baseClass):
56 """ Retreive method given methodName, path to base of tree, and class/module 57 route/label. 58 """ 59 # First split the method name 60 methodNameComps = ['spacewalk'] + string.split(baseClass, '.') + string.split(methodName, '.') 61 # Sanity checks 62 sanity(methodNameComps) 63 # Build the path to the file 64 path = get_python_lib() 65 for index in range(len(methodNameComps)): 66 comp = methodNameComps[index] 67 path = "%s/%s" % (path, comp) 68 # If this is a directory, fine... 69 if os.path.isdir(path): 70 # Okay, go on 71 continue 72 # Try to load this as a file 73 for extension in ['py', 'pyc', 'pyo']: 74 if os.path.isfile("%s.%s" % (path, extension)): 75 # Yes, this is a file 76 break 77 else: 78 # No dir and no file. Die 79 raise GetMethodException("Action %s could not be found" % methodName) 80 break 81 else: 82 # Only directories. This can't happen 83 raise GetMethodException("Very wrong") 84 85 # The position of the file 86 fIndex = index + 1 87 # Now build the module name 88 modulename = string.join(methodNameComps[:fIndex], '.') 89 # And try to import it 90 try: 91 actions = __import__(modulename) 92 except ImportError: 93 raise_with_tb(GetMethodException("Could not import module %s" % modulename), sys.exc_info()[2]) 94 95 className = actions 96 # Iterate through the list of components and try to load that specific 97 # module/method 98 for index in range(1, len(methodNameComps)): 99 comp = methodNameComps[index] 100 if index < fIndex: 101 # This is a directory or a file we have to load 102 if not hasattr(className, comp): 103 # Hmmm... Not there 104 raise GetMethodException("Class %s has no attribute %s" % ( 105 string.join(methodNameComps[:index], '.'), comp)) 106 className = getattr(className, comp) 107 # print type(className) 108 continue 109 # A file or method 110 # We look for the special __rhnexport__ array 111 if not hasattr(className, '__rhnexport__'): 112 raise GetMethodException("Class %s is not RHN-compliant" % 113 string.join(methodNameComps[:index], '.')) 114 export = getattr(className, '__rhnexport__') 115 if comp not in export: 116 raise GetMethodException("Class %s does not export '%s'" % ( 117 string.join(methodNameComps[:index], '.'), comp)) 118 className = getattr(className, comp) 119 if type(className) is ClassType: 120 # Try to instantiate it 121 className = className() 122 # print type(className) 123 124 return className
125 126 127 #----------------------------------------------------------------------------- 128 if __name__ == '__main__': 129 # Two valid ones and a bogus one 130 methods = [ 131 'a.b.c.d.e.f', 132 'a.b.c.d.e.foo.h', 133 'a.b.c.d.e.g.h', 134 'a.b.d.d.e.g.h', 135 'a.b.d.d._e.g.h', 136 'a.b.d.d.e_.g.h', 137 'a.b.d.d.e-.g.h', 138 'a.b.d.d..g.h', 139 ] 140 141 for m in methods: 142 print("----Running method %s: " % m) 143 try: 144 method = getMethod(m, 'Actions') 145 except GetMethodException: 146 e = sys.exc_info()[1] 147 print("Error getting the method %s: %s" % (m, 148 string.join(map(str, e.args)))) 149 else: 150 method() 151 #----------------------------------------------------------------------------- 152