Example #1
0
  def _check_available_vessels(self, data, remoteip):
    '''
    Connects to the clearinghouse and returns a response_dict containing
    the following keys:
      'status':
        'ok' on success /'error' on failure
      'max_hosts':
        The remaining number of hosts that the user can acquire.
        On failure, this is '?'.
      'default_port':
        The user's assigned userport.
      'error':
        A description of the error that occurred. This only exists if an error
        happened.

    '''
    response_dict = {}
    try:
      client = selexorhelper.connect_to_clearinghouse(data)
      accinfo = client.get_account_info()
      acquired_resources = client.get_resource_info()

      response_dict['status'] = 'ok'
      response_dict['max_hosts'] = accinfo['max_vessels'] - len(acquired_resources)
      response_dict['default_port'] = accinfo['user_port']

    except seattleclearinghouse_xmlrpc.AuthenticationError, e:
      response_dict['status'] = 'error'
      response_dict['error'] = str(e)
      response_dict['max_hosts'] = "?"
Example #2
0
  def handle_request(self, authinfo, request, remoteip):
    '''
    <Purpose>
      Handles a host request for the specified user.

    <Arguments>
      userdata:
        A dictionary representing the user's authentication information. It should
        contain the following:
          'username':
            The user's username.
          'api_key':
            The user's API key.
          'clearinghouse_uri':
            The target Clearinghouse to connect to.

      request:
        A string representing a user request. This string must not contain any
        spaces (except for a parameter value) nor newlines. Groups are separated
        with semicolons. Each group must have a group ID, number of vessels,
        and optionally rules, all colon separated. The group ID should be an
        integer. Rules are also colon separated. Rules should have a rule type,
        followed by their list of parameters, comma separated. Parameters are
        in the format of parameter_name~parameter_value. Each parameter may only
        have one value.

        Example (split across multiple lines for readability):
          0:3:location_specific,city~?,country~USA:location_different,num_locations~4,location_type~city;
          1:2:latency_average,min_latency~40ms,max_latency~200ms;

      remoteip: The IP address where this request originated from.

    <Side Effects>
      Attempts to obtain vessels described in the request_data. This is not
      guaranteed, depending on the ddata collected in the selexordatabase.

    <Exceptions>
      None

    <Returns>
      Returns the status of the request, as a string.

      'timeout':
        The request did not finish in the allocated time.
      'complete':
        Selexor successfully finished the request.

    '''
    if not self._accepting_requests:
      return {'error': "Server is not accepting requests."}

    # Get ready to handle the request
    username = authinfo.keys()[0]
    identity = (username, remoteip)
    request_datum[identity] = {'status': 'processing'}
    logger.info(str(identity) + ": Obtained request: " + str(request))

    # Make sure the request is valid
    request_data = self._validate_request(identity, request)
    request_datum[identity] = request_data
    logger.info(str(identity) + ": Generated Request data: " + str(request_data))

    if request_data['status'] == 'accepted':
      try:
        client = selexorhelper.connect_to_clearinghouse(authinfo)
      except selexorexceptions.SelexorException, e:
        request_data['status'] = 'error'
        request_data['error'] = str(e)
        raise
      except:
Example #3
0
  def release_vessels(self, authdata, vessels_to_release, remoteip):
    '''
    <Purpose>
      Returns the # of vessels released
    <Arguments>
      authdata:
        An authdict. See module documentation for more information.
      vessels:
        A list of dictionaries containing vessel information of the vessels
        to release.  These dictionaries should either contain the vessel handle,
        or node_ip:node_port:vesselname.
      remoteip:
        The remote IP address of the client. This is used for client identification.
    <Exceptions>
      None
    <Side Effects>
      None
    <Return>
      A dictionary containing the status of each group.
      'group_id': 'group_status'

    '''
    try:
      username = authdata.keys()[0]
      identity = (username, remoteip)
      logger.info(str(identity) + "> Release: " + str(vessels_to_release))

      # There's nothing to do if there aren't any vessels to release
      if not vessels_to_release:
        return 0

      handles_of_vessels_to_release = []
      for vesseldict in vessels_to_release:
        if 'node_handle' in vesseldict:
          handles_of_vessels_to_release.append(vesseldict['node_handle'])
        else:
          # Do we have this information in the database?
          db, cursor = selexorhelper.connect_to_db()

          # If it is found, the lookup returns a 1L.
          node_in_db = 1L == cursor.execute("SELECT node_key FROM nodes WHERE ip_addr='"+vesseldict['node_ip']+"' AND node_port="+str(vesseldict['node_port']))
          if node_in_db:
            [node_key] = cursor.fetchone()
            logger.debug('\n'.join([
                str(identity),
                "Found node in database: "+vesseldict['node_ip']+':'+str(int(vesseldict['node_port']))+':'+vesseldict['vesselname']+" with key:",
                node_key]))
            handles_of_vessels_to_release.append(node_key+':'+vesseldict['vesselname'])

          else:
            # Try to connect to that node to get the handle
            vessel_location = vesseldict['node_ip']+':'+str(int(vesseldict['node_port']))+':'+vesseldict['vesselname']
            try:
              handles_of_vessels_to_release.append(get_handle_from_nodehandle(vessel_location))
            except fastnmclient.NMClientException, e:
              logger.info("Failed to look up vessel "+vessel_location+' through nodemanager: '+ str(e))

      client = selexorhelper.connect_to_clearinghouse(authdata)

      # Release the remaining vessels
      for vessel in handles_of_vessels_to_release:
        # Do we need to check if a vessel failed to release?
        # Maybe it means that a vessel has gone offline/is now invalid.
        client.release_resources([vessel])

      # Assume all the vessels were released successfully
      num_released = len(handles_of_vessels_to_release)

      # Remove vessel entries from the groups tables.
      if identity in request_datum:
        for group in request_datum[identity]['groups']:
          for vesselhandle in handles_of_vessels_to_release:
            if vesselhandle in request_datum[identity]['groups'][group]['acquired']:
              request_datum[identity]['groups'][group]['acquired'].remove(vesselhandle)
              request_datum[identity]['groups'][group]['allocate'] -= 1