Ejemplo n.º 1
0
 def __init__(self, auth=None):
     if auth is None:
         auth = {
             'AuthMethod':
             Parameter(str, "Authentication method to use", optional=False)
         }
     Parameter.__init__(self, auth, "API authentication structure")
Ejemplo n.º 2
0
class methodSignature(Method):
    """
    Returns an array of known signatures (an array of arrays) for the
    method name passed. If no signatures are known, returns a
    none-array (test for type != array to detect missing signature).
    """

    roles = []
    accepts = [Parameter(str, "Method name")]
    returns = [Parameter([str], "Method signature")]

    def __init__(self, api):
        Method.__init__(self, api)
        self.name = "system.methodSignature"

    def possible_signatures(self, signature, arg):
        """
        Return a list of the possible new signatures given a current
        signature and the next argument.
        """

        if isinstance(arg, Mixed):
            arg_types = [xmlrpc_type(mixed_arg) for mixed_arg in arg]
        else:
            arg_types = [xmlrpc_type(arg)]

        return [signature + [arg_type] for arg_type in arg_types]

    def signatures(self, returns, args):
        """
        Returns a list of possible signatures given a return value and
        a set of arguments.
        """

        signatures = [[xmlrpc_type(returns)]]

        for arg in args:
            # Create lists of possible new signatures for each current
            # signature. Reduce the list of lists back down to a
            # single list.
            signatures = reduce(lambda a, b: a + b,
                                [self.possible_signatures(signature, arg) \
                                 for signature in signatures])

        return signatures

    def call(self, method):
        function = self.api.callable(method)
        (min_args, max_args, defaults) = function.args()

        signatures = []

        assert len(max_args) >= len(min_args)
        for num_args in range(len(min_args), len(max_args) + 1):
            signatures += self.signatures(function.returns,
                                          function.accepts[:num_args])

        return signatures
Ejemplo n.º 3
0
class Content(Row):
   
   table_name = 'contents'
   primary_key = 'content_id'
   join_tables = ['user_content']
   
   fields = {
      'content_id':             Parameter(int, "Content server identifier"),
      'host_url':               Parameter(str, "Base URL of the content server"),
      'owner':                  Parameter(long, "User ID of the user that is responsible for this content server")
   }
Ejemplo n.º 4
0
   def __init__(self, fields = {}, filter = {}, doc = "Attribute filter"):
      # Store the filter in our dict instance
      dict.__init__(self, filter)

      # Declare ourselves as a type of parameter that can take
      # either a value or a list of values for each of the specified
      # fields.
      self.fields = dict ( [ ( field, Mixed (expected, [expected]))
                              for (field,expected) in fields.iteritems() ] )

      # Null filter means no filter
      Parameter.__init__(self, self.fields, doc = doc, nullok = True)
Ejemplo n.º 5
0
    def __init__(self, fields={}, filter={}, doc="Attribute filter"):
        # Store the filter in our dict instance
        dict.__init__(self, filter)

        # Declare ourselves as a type of parameter that can take
        # either a value or a list of values for each of the specified
        # fields.
        self.fields = dict([(field, Mixed(expected, [expected]))
                            for (field, expected) in fields.iteritems()])

        # Null filter means no filter
        Parameter.__init__(self, self.fields, doc=doc, nullok=True)
Ejemplo n.º 6
0
 def __init__(self):
     Auth.__init__(
         self, {
             'AuthMethod':
             Parameter(str,
                       "Authentication method to use, always 'anonymous'",
                       False),
         })
Ejemplo n.º 7
0
 def __init__(self):
     Auth.__init__(
         self, {
             'AuthMethod':
             Parameter(
                 str,
                 "Authentication method to use, always 'password' or 'capability'",
                 optional=False),
             'Username':
             Parameter(str,
                       "PlanetLab username, typically an e-mail address",
                       optional=False),
             'AuthString':
             Parameter(str,
                       "Authentication string, typically a password",
                       optional=False),
         })
Ejemplo n.º 8
0
class methodHelp(Method):
    """
    Returns help text if defined for the method passed, otherwise
    returns an empty string.
    """

    roles = []
    accepts = [Parameter(str, 'Method name')]
    returns = Parameter(str, 'Method help')

    def __init__(self, api):
        Method.__init__(self, api)
        self.name = "system.methodHelp"

    def call(self, method):
        function = self.api.callable(method)
        return function.help()
Ejemplo n.º 9
0
class multicall(Method):
    """
    Process an array of calls, and return an array of results. Calls
    should be structs of the form

    {'methodName': string, 'params': array}

    Each result will either be a single-item array containg the result
    value, or a struct of the form

    {'faultCode': int, 'faultString': string}

    This is useful when you need to make lots of small calls without
    lots of round trips.
    """

    roles = []
    accepts = [[{'methodName': Parameter(str, "Method name"),
                 'params': Parameter(list, "Method arguments")}]]
    returns = Mixed([Mixed()],
                    {'faultCode': Parameter(int, "XML-RPC fault code"),
                     'faultString': Parameter(int, "XML-RPC fault detail")})

    def __init__(self, api):
        Method.__init__(self, api)
        self.name = "system.multicall"

    def call(self, calls):
        # Some error codes, borrowed from xmlrpc-c.
        REQUEST_REFUSED_ERROR = -507

        results = []
        for call in calls:
            try:
                name = call['methodName']
                params = call['params']
                if name == 'system.multicall':
                    errmsg = "Recursive system.multicall forbidden"
                    raise xmlrpclib.Fault(REQUEST_REFUSED_ERROR, errmsg)
                result = [self.api.call(self.source, name, *params)]
            except xmlrpclib.Fault, fault:
                result = {'faultCode': fault.faultCode,
                          'faultString': fault.faultString}
            except:
Ejemplo n.º 10
0
class listMethods(Method):
    """
    This method lists all the methods that the XML-RPC server knows
    how to dispatch.
    """

    roles = []
    accepts = []
    returns = Parameter(list, 'List of methods')

    def __init__(self, api):
        Method.__init__(self, api)
        self.name = "system.listMethods"

    def call(self):
        return self.api.all_methods
Ejemplo n.º 11
0
class MDServer(Row):

    table_name = 'mdservers'
    primary_key = 'server_id'
    join_tables = ['user_mdserver', 'mdserver_user']

    fields = {
        'server_id':
        Parameter(long, "Server ID"),
        'name':
        Parameter(
            str,
            "Owner-given name of this metadata server (will be URL-encoded)"),
        'host':
        Parameter(str, "Name of the host that hosts this metadata server"),
        'portnum':
        Parameter(int,
                  "Port on which this metadata server listens",
                  min=1025,
                  max=65534),
        'status':
        Parameter(str, "Desired status of this metadata server"),
        'auth_read':
        Parameter(bool,
                  "Must a user authenticate with the server to read from it?"),
        'auth_write':
        Parameter(bool,
                  "Must a user authenticate with the server to write to it?"),
        'owner':
        Parameter(
            int,
            "User ID of the user who created and controls this metadata server"
        ),
        'user_ids':
        Parameter([int],
                  "User IDs of users subscribed to this metadata server")
    }

    related_fields = {'user_ids': [Parameter(int, "Subscribed user ID")]}

    def __init__(self, api, fields={}):
        super(MDServer, self).__init__(api, fields)
        import SMDS.user
        self._add_user = Row.add_object(SMDS.user.User, 'mdserver_user')
        self._remove_user = Row.remove_object(SMDS.user.User, 'mdserver_user')

    def add_user(self, obj, commit=True):
        self._add_user(self, obj, commit=commit)

    def remove_user(self, obj, commit=True):
        self._remove_user(self, obj, commit=commit)

    @classmethod
    def refresh(api, m):
        md = MDServers(api, [m['server_id']])[0]
        m.update(md)

    def remove_users(self, user_ids):
        import SMDS.user

        users = SMDS.user.Users(self.api, user_ids)
        if users:
            for user in users:
                self.remove_user(user, commit=False)

        self.commit()

    def create_server(self):
        # signal the controller on this metadata server's host to create this server
        self['status'] = 'stopped'
        server = self.api.connect_mdctl(self['host'])

        import SMDS.user

        # get our users
        if self.get('user_ids') == None:
            self['user_ids'] = []

        user_ids = self['user_ids']
        users = []
        if user_ids:
            users = SMDS.user.Users(self.api, user_ids)

        logger.info("Creating metadata server '%s' with users '%s'" %
                    (self['name'], [user['username'] for user in users]))

        rc = 0
        try:
            as_dict = {}
            as_dict.update(self)

            user_dicts = []
            for user in users:
                user_dict = {}
                user_dict.update(user)
                user_dicts.append(user_dict)

            rc = server.create_server(as_dict, user_dicts)
        except Exception, e:
            logger.exception(e, "Could not restart metadata server")
            rc = -500

        if rc == 1:
            self.sync()
        else:
            logger.error("Could not create metadata server, rc = %s" % rc)

        return rc
Ejemplo n.º 12
0
 def Parameter(doc):
     return Mixed(
         Parameter(int, doc + " (unix timestamp)"),
         Parameter(str, doc + " (formatted as %s)" % Timestamp.sql_format),
     )
Ejemplo n.º 13
0
 def __init__(self, auth = None):
     if auth is None:
         auth = {'AuthMethod': Parameter(str, "Authentication method to use", optional = False)}
     Parameter.__init__(self, auth, "API authentication structure")
Ejemplo n.º 14
0
class User(Row):
   
   table_name = 'users'
   primary_key = 'user_id'
   
   fields = {
      'user_id':           Parameter(long, "User ID"),
      'username':          Parameter(str, "Username", max=128),
      'password':          Parameter(str, "Password hash", max=254),
      'email':             Parameter(str, "User's email address", max=254),
      'enabled':           Parameter(bool, "Has the user been enabled?"),
      'roles':             Parameter([str], "List of roles this user fulfulls"),
      'max_mdservers':     Parameter(int, "Maximum number of metadata servers this user can own"),
      'max_contents':      Parameter(int, "Maximum number of content servers this user can register"),
      'my_mdserver_ids':   Parameter([int], "Server IDs of servers owned by this user"),
      'sub_mdserver_ids':  Parameter([int], "Server IDs of servers this user is subscribed to"),
      'content_ids':       Parameter([int], "Content IDs of content servers owned by this user")
   }
   
   related_fields = {
      'my_mdserver_ids': [Parameter(int, "Server ID")],
      'sub_mdserver_ids': [Parameter(int, "Server ID")],
      'content_ids': [Parameter(int, "Content ID")]
   }
   
   user_content_view = 'user_contents'
   user_mdserver_view = 'user_mdservers'
   
   join_tables = ['user_mdserver', 'user_content', 'mdserver_user']
   
   add_mdserver    = Row.add_object(SMDS.mdserver.MDServer, 'user_mdserver')
   remove_mdserver = Row.remove_object(SMDS.mdserver.MDServer, 'user_mdserver')
   
   add_content     = Row.add_object(Content, 'user_content')
   remove_content  = Row.remove_object(Content, 'user_content')
   
   public_fieldnames = filter( lambda f: f not in ['password'], fields.keys())
   
   register_fieldnames = ['username','password','email']
   
   def public(self):
      ret = {}
      for f in self.public_fieldnames:
         ret[f] = self.get(f)
      
      return ret
   
   @staticmethod
   def refresh( api, u):
      user = Users( api, [u['user_id']] )[0]
      u.update( user )