def describe_operation(self, parameters, secret):
    """
    Query the InfrastructureManager instance for details regarding
    an operation id for running or terminating instances. This method accepts
    a dictionary of parameters and a secret for authentication purposes.
    The dictionary of parameters must include an 'operation_id' parameter
    which is used to lookup calls that have been made to run or terminate
    instances.

    Args:
      parameters  A dictionary of parameters which contains a valid
                  'operation_id' parameter. A valid 'operation_id'
                  is an ID issued by the run_instances method of the
                  same InfrastructureManager object. Alternatively one
                  may provide a valid JSON string instead of a dictionary
                  object.
      secret      A previously established secret

    Returns:
      invalid key or an invalid 'operation_id':
       'success': False
       'reason': is set to an error message describing the cause.

      If the provided secret key is valid and the parameters map contains
      a valid 'operation_id' parameter, this method will return a
      dictionary containing the following keys for the specified cases.

      For a run_instances operation_id:
        'success': True or False depending on the outcome of the virtual
          machine deployment process.
        'state': pending, failed, or success
        'reason': set only in a failed case.
        'vm_info': a dictionary containing the IP addresses of the spawned
          virtual machines or None if the virtual machine deployment had
          failed or still in the 'pending' state.
      For a terminate_instances operation_id:
        'success': True or False depending on the outcome of the virtual
          machine deployment process.
        'state': pending, failed, or success
        'reason': set only in a failed case.
        * note that this dictionary does not contain 'vm_info'.

    Raises:
      TypeError   If the inputs are not of the expected types
      ValueError  If the input JSON string (parameters) cannot be parsed properly
    """
    parameters, secret = self.__validate_args(parameters, secret)

    if self.secret != secret:
      return self.__generate_response(False, self.REASON_BAD_SECRET)

    for param in self.DESCRIBE_INSTANCES_REQUIRED_PARAMS:
      if not utils.has_parameter(param, parameters):
        return self.__generate_response(False, 'no ' + param)

    operation_id = parameters[self.PARAM_OPERATION_ID]
    if self.operation_ids.has_key(operation_id):
      return self.operation_ids.get(operation_id)
    else:
      return self.__generate_response(False, self.REASON_OPERATION_ID_NOT_FOUND)
    def describe_instances(self, parameters, secret):
        """
    Query the InfrastructureManager instance for details regarding
    a set of virtual machines spawned in the past. This method accepts
    a dictionary of parameters and a secret for authentication purposes.
    The dictionary of parameters must include a 'reservation_id' parameter
    which is used to reference past virtual machine deployments.

    Args:
      parameters  A dictionary of parameters which contains a valid
                  'reservation_id' parameter. A valid 'reservation_id'
                  is an ID issued by the run_instances method of the
                  same InfrastructureManager object. Alternatively one
                  may provide a valid JSON string instead of a dictionary
                  object.
      secret      A previously established secret

    Returns:
      If the provided secret key is valid and the parameters map contains
      a valid 'reservation_id' parameter, this method will return a
      dictionary containing information regarding the requested past
      virtual machine deployment. This returned map contains several
      keys including 'success', 'state', 'reason' and 'vm_info'. The value
      of 'success' could be True of False depending on the outcome of the
      virtual machine deployment process. If the value of 'success' happens
      to be False, the 'reason' key would contain more details as to what
      caused the deployment to fail. The 'state' key could contain a 'pending'
      value or a 'running' value depending on the current state of the
      virtual machine deployment. And finally the 'vm_info' key would point
      to a another dictionary containing the IP addresses of the spawned virtual
      machines. If the virtual machine deployment had failed or still in the
      'pending' state, this key would contain the value None.

      If this method receives an invalid key or an invalid 'reservation_id'
      parameter, it will return a dictionary containing the keys 'success'
      and 'reason' where 'success' would be set to False, and 'reason' is
      set to a simple error message describing the cause of the error.

    Raises:
      TypeError   If the inputs are not of the expected types
      ValueError  If the input JSON string (parameters) cannot be parsed properly
    """
        parameters, secret = self.__validate_args(parameters, secret)

        if self.secret != secret:
            return self.__generate_response(False, self.REASON_BAD_SECRET)

        for param in self.DESCRIBE_INSTANCES_REQUIRED_PARAMS:
            if not utils.has_parameter(param, parameters):
                return self.__generate_response(False, 'no ' + param)

        reservation_id = parameters[self.PARAM_RESERVATION_ID]
        if self.reservations.has_key(reservation_id):
            return self.reservations.get(reservation_id)
        else:
            return self.__generate_response(False,
                                            self.REASON_RESERVATION_NOT_FOUND)
예제 #3
0
  def describe_instances(self, parameters, secret):
    """
    Query the InfrastructureManager instance for details regarding
    a set of virtual machines spawned in the past. This method accepts
    a dictionary of parameters and a secret for authentication purposes.
    The dictionary of parameters must include a 'reservation_id' parameter
    which is used to reference past virtual machine deployments.

    Args:
      parameters  A dictionary of parameters which contains a valid
                  'reservation_id' parameter. A valid 'reservation_id'
                  is an ID issued by the run_instances method of the
                  same InfrastructureManager object. Alternatively one
                  may provide a valid JSON string instead of a dictionary
                  object.
      secret      A previously established secret

    Returns:
      If the provided secret key is valid and the parameters map contains
      a valid 'reservation_id' parameter, this method will return a
      dictionary containing information regarding the requested past
      virtual machine deployment. This returned map contains several
      keys including 'success', 'state', 'reason' and 'vm_info'. The value
      of 'success' could be True of False depending on the outcome of the
      virtual machine deployment process. If the value of 'success' happens
      to be False, the 'reason' key would contain more details as to what
      caused the deployment to fail. The 'state' key could contain a 'pending'
      value or a 'running' value depending on the current state of the
      virtual machine deployment. And finally the 'vm_info' key would point
      to a another dictionary containing the IP addresses of the spawned virtual
      machines. If the virtual machine deployment had failed or still in the
      'pending' state, this key would contain the value None.

      If this method receives an invalid key or an invalid 'reservation_id'
      parameter, it will return a dictionary containing the keys 'success'
      and 'reason' where 'success' would be set to False, and 'reason' is
      set to a simple error message describing the cause of the error.

    Raises:
      TypeError   If the inputs are not of the expected types
      ValueError  If the input JSON string (parameters) cannot be parsed properly
    """
    parameters, secret = self.__validate_args(parameters, secret)

    if self.secret != secret:
      return self.__generate_response(False, self.REASON_BAD_SECRET)

    for param in self.DESCRIBE_INSTANCES_REQUIRED_PARAMS:
      if not utils.has_parameter(param, parameters):
        return self.__generate_response(False, 'no ' + param)

    reservation_id = parameters[self.PARAM_RESERVATION_ID]
    if self.reservations.has_key(reservation_id):
      return self.reservations.get(reservation_id)
    else:
      return self.__generate_response(False, self.REASON_RESERVATION_NOT_FOUND)
예제 #4
0
  def terminate_instances(self, parameters, secret):
    """
    Terminate a group of virtual machines using the provided parameters.
    The input parameter map must contain an 'infrastructure' parameter which
    will be used to instantiate a suitable cloud agent. Any additional
    environment specific parameters should also be available in the same
    map.

    If this InfrastructureManager instance has been created in the blocking mode,
    this method will not return until the VM deployment is complete. Otherwise
    this method simply starts the VM termination process and returns immediately.

    Args:
      parameters  A dictionary of parameters containing the required
                  'infrastructure' parameter and any other platform
                  dependent required parameters. Alternatively one
                  may provide a valid JSON string instead of a dictionary
                  object.
      secret      A previously established secret

    Returns:
      If the secret is valid and all the parameters required to successfully
      start a termination process are present in the parameters dictionary,
      this method will return a dictionary with the key 'success' set to
      True. Otherwise it returns a dictionary with 'success' set to False
      and 'reason' set to a simple error message.

    Raises:
      TypeError   If the inputs are not of the expected types
      ValueError  If the input JSON string (parameters) cannot be parsed properly
    """
    parameters, secret = self.__validate_args(parameters, secret)

    if self.secret != secret:
      return self.__generate_response(False, self.REASON_BAD_SECRET)

    for param in self.TERMINATE_INSTANCES_REQUIRED_PARAMS:
      if not utils.has_parameter(param, parameters):
        return self.__generate_response(False, 'no ' + param)

    infrastructure = parameters[self.PARAM_INFRASTRUCTURE]
    agent = self.agent_factory.create_agent(infrastructure)
    try:
      agent.assert_required_parameters(parameters,
        BaseAgent.OPERATION_TERMINATE)
    except AgentConfigurationException as exception:
      return self.__generate_response(False, str(exception))

    if self.blocking:
      self.__kill_vms(agent, parameters)
    else:
      thread.start_new_thread(self.__kill_vms, (agent, parameters))
    return self.__generate_response(True, self.REASON_NONE)
    def terminate_instances(self, parameters, secret):
        """
    Terminate a group of virtual machines using the provided parameters.
    The input parameter map must contain an 'infrastructure' parameter which
    will be used to instantiate a suitable cloud agent. Any additional
    environment specific parameters should also be available in the same
    map.

    If this InfrastructureManager instance has been created in the blocking mode,
    this method will not return until the VM deployment is complete. Otherwise
    this method simply starts the VM termination process and returns immediately.

    Args:
      parameters  A dictionary of parameters containing the required
                  'infrastructure' parameter and any other platform
                  dependent required parameters. Alternatively one
                  may provide a valid JSON string instead of a dictionary
                  object.
      secret      A previously established secret

    Returns:
      If the secret is valid and all the parameters required to successfully
      start a termination process are present in the parameters dictionary,
      this method will return a dictionary with the key 'success' set to
      True. Otherwise it returns a dictionary with 'success' set to False
      and 'reason' set to a simple error message.

    Raises:
      TypeError   If the inputs are not of the expected types
      ValueError  If the input JSON string (parameters) cannot be parsed properly
    """
        parameters, secret = self.__validate_args(parameters, secret)

        if self.secret != secret:
            return self.__generate_response(False, self.REASON_BAD_SECRET)

        for param in self.TERMINATE_INSTANCES_REQUIRED_PARAMS:
            if not utils.has_parameter(param, parameters):
                return self.__generate_response(False, 'no ' + param)

        infrastructure = parameters[self.PARAM_INFRASTRUCTURE]
        agent = self.agent_factory.create_agent(infrastructure)
        try:
            agent.assert_required_parameters(parameters,
                                             BaseAgent.OPERATION_TERMINATE)
        except AgentConfigurationException as exception:
            return self.__generate_response(False, str(exception))

        if self.blocking:
            self.__kill_vms(agent, parameters)
        else:
            thread.start_new_thread(self.__kill_vms, (agent, parameters))
        return self.__generate_response(True, self.REASON_NONE)
예제 #6
0
    def assert_required_parameters(self, parameters, operation):
        required_params = ()
        if operation == BaseAgent.OPERATION_PREPARE:
            required_params = self.REQUIRED_FLEX_PREPARE_INSTANCES_PARAMS
        elif operation == BaseAgent.OPERATION_DEREGISTER:
            required_params = self.REQUIRED_FLEX_DEREGISTER_INSTANCES_PARAMS

        logging.debug('required_params: {0}'.format(required_params))

        for param in required_params:
            logging.debug('param: {0}'.format(param))
            if not utils.has_parameter(param, parameters):
                raise AgentConfigurationException('no ' + param)
예제 #7
0
    def assert_required_parameters(self, parameters, operation):
        required_params = ()
        if operation == BaseAgent.OPERATION_PREPARE:
            required_params = self.REQUIRED_FLEX_PREPARE_INSTANCES_PARAMS
        elif operation == BaseAgent.OPERATION_DEREGISTER:
            required_params = self.REQUIRED_FLEX_DEREGISTER_INSTANCES_PARAMS

        logging.debug('required_params: {0}'.format(required_params))

        for param in required_params:
            logging.debug('param: {0}'.format(param))
            if not utils.has_parameter(param, parameters):
                raise AgentConfigurationException('no ' + param)
예제 #8
0
  def assert_required_parameters(self, parameters, operation):
    """
    Assert that all the parameters required for the EC2 agent are in place.
    (Also see documentation for the BaseAgent class)

    Args:
      parameters  A dictionary of parameters
      operation   Operations to be invoked using the above parameters
    """
    required_params = ()
    if operation == BaseAgent.OPERATION_RUN:
      required_params = self.REQUIRED_EC2_RUN_INSTANCES_PARAMS
    elif operation == BaseAgent.OPERATION_TERMINATE:
      required_params = self.REQUIRED_EC2_TERMINATE_INSTANCES_PARAMS

    for param in required_params:
      if not utils.has_parameter(param, parameters):
        raise AgentConfigurationException('no ' + param)
예제 #9
0
    def assert_required_parameters(self, parameters, operation):
        """
    Assert that all the parameters required for the EC2 agent are in place.
    (Also see documentation for the BaseAgent class)

    Args:
      parameters  A dictionary of parameters
      operation   Operations to be invoked using the above parameters
    """
        required_params = ()
        if operation == BaseAgent.OPERATION_RUN:
            required_params = self.REQUIRED_EC2_RUN_INSTANCES_PARAMS
        elif operation == BaseAgent.OPERATION_TERMINATE:
            required_params = self.REQUIRED_EC2_TERMINATE_INSTANCES_PARAMS

        for param in required_params:
            if not utils.has_parameter(param, parameters):
                raise AgentConfigurationException('no ' + param)
예제 #10
0
  def run_instances(self, parameters, secret):
    """
    Start a new virtual machine deployment using the provided parameters. The
    input parameter set must include an 'infrastructure' parameter which indicates
    the exact cloud environment to use. Value of this parameter will be used to
    instantiate a cloud environment specific agent which knows how to interact
    with the specified cloud platform. The parameters map must also contain a
    'num_vms' parameter which indicates the number of virtual machines that should
    be spawned. In addition to that any parameters required to spawn VMs in the
    specified cloud environment must be included in the parameters map.

    If this InfrastructureManager instance has been created in the blocking mode,
    this method will not return until the VM deployment is complete. Otherwise
    this method will simply kick off the VM deployment process and return
    immediately.

    Args:
      parameters  A parameter map containing the keys 'infrastructure',
                  'num_vms' and any other cloud platform specific
                  parameters. Alternatively one may provide a valid
                  JSON string instead of a dictionary object.
      secret      A previously established secret

    Returns:
      If the secret is valid and all the required parameters are available in
      the input parameter map, this method will return a dictionary containing
      a special 'reservation_id' key. If the secret is invalid or a required
      parameter is missing, this method will return a different map with the
      key 'success' set to False and 'reason' set to a simple error message.

    Raises:
      TypeError   If the inputs are not of the expected types
      ValueError  If the input JSON string (parameters) cannot be parsed properly
    """
    parameters, secret = self.__validate_args(parameters, secret)

    utils.log('Received a request to run instances.')

    if self.secret != secret:
      utils.log('Incoming secret {0} does not match the current secret {1} - '\
                'Rejecting request.'.format(secret, self.secret))
      return self.__generate_response(False, self.REASON_BAD_SECRET)

    for param in self.RUN_INSTANCES_REQUIRED_PARAMS:
      if not utils.has_parameter(param, parameters):
        return self.__generate_response(False, 'no ' + param)

    num_vms = int(parameters[self.PARAM_NUM_VMS])
    if num_vms <= 0:
      utils.log('Invalid VM count: {0}'.format(num_vms))
      return self.__generate_response(False, self.REASON_BAD_VM_COUNT)

    infrastructure = parameters[self.PARAM_INFRASTRUCTURE]
    agent = self.agent_factory.create_agent(infrastructure)
    try:
      agent.assert_required_parameters(parameters, BaseAgent.OPERATION_RUN)
    except AgentConfigurationException as exception:
      return self.__generate_response(False, str(exception))

    reservation_id = utils.get_random_alphanumeric()
    status_info = {
      'success': True,
      'reason': 'received run request',
      'state': self.STATE_PENDING,
      'vm_info': None
    }
    self.reservations.put(reservation_id, status_info)
    utils.log('Generated reservation id {0} for this request.'.format(
      reservation_id))
    try:
      if self.blocking:
        self.__spawn_vms(agent, num_vms, parameters, reservation_id)
      else:
        thread.start_new_thread(self.__spawn_vms,
          (agent, num_vms, parameters, reservation_id))
    except AgentConfigurationException as exception:
      status_info = {
        'success' : False,
        'reason' : str(exception),
        'state' : self.STATE_FAILED,
        'vm_info' : None
      }
      self.reservations.put(reservation_id, status_info)
      utils.log('Updated reservation id {0} with failed status because: {1}' \
        .format(reservation_id, str(exception)))

    utils.log('Successfully started request {0}.'.format(reservation_id))
    return self.__generate_response(True,
      self.REASON_NONE, {'reservation_id': reservation_id})
예제 #11
0
  def run_instances(self, parameters, secret):
    """
    Start a new virtual machine deployment using the provided parameters. The
    input parameter set must include an 'infrastructure' parameter which indicates
    the exact cloud environment to use. Value of this parameter will be used to
    instantiate a cloud environment specific agent which knows how to interact
    with the specified cloud platform. The parameters map must also contain a
    'num_vms' parameter which indicates the number of virtual machines that should
    be spawned. In addition to that any parameters required to spawn VMs in the
    specified cloud environment must be included in the parameters map.

    If this InfrastructureManager instance has been created in the blocking mode,
    this method will not return until the VM deployment is complete. Otherwise
    this method will simply kick off the VM deployment process and return
    immediately.

    Args:
      parameters  A parameter map containing the keys 'infrastructure',
                  'num_vms' and any other cloud platform specific
                  parameters. Alternatively one may provide a valid
                  JSON string instead of a dictionary object.
      secret      A previously established secret (currently not used)

    Returns:
      If the secret is valid and all the required parameters are available in
      the input parameter map, this method will return a dictionary containing
      a special 'reservation_id' key. If the secret is invalid or a required
      parameter is missing, this method will return a different map with the
      key 'success' set to False and 'reason' set to a simple error message.

    Raises:
      TypeError   If the inputs are not of the expected types
      ValueError  If the input JSON string (parameters) cannot be parsed properly
    """

    utils.log('Received a request to run instances.')

    utils.log('Request parameters are {0}'.format(parameters))
    for param in self.RUN_INSTANCES_REQUIRED_PARAMS:
      if not utils.has_parameter(param, parameters):
        return self.__generate_response(False, 'no ' + param)

    num_vms = int(parameters[self.PARAM_NUM_VMS])
    if num_vms <= 0:
      utils.log('Invalid VM count: {0}'.format(num_vms))
      return self.__generate_response(False, self.REASON_BAD_VM_COUNT)

    infrastructure = parameters[self.PARAM_INFRASTRUCTURE]
    agent = self.agent_factory.create_agent(infrastructure)
    try:
      agent.assert_required_parameters(parameters, BaseAgent.OPERATION_RUN)
    except AgentConfigurationException as exception:
      return self.__generate_response(False, exception.message)

    keyname = parameters[self.PARAM_KEYNAME]
    if keyname is None :
      utils.log('Invalid keyname: '+keyname)
      return self.__generate_response(False, self.REASON_BAD_ARGUMENTS)

    reservation_id = utils.get_random_alphanumeric()
    status_info = {
      'success': True,
      'reason': 'received run request',
      'state': self.STATE_PENDING,
      'vm_info': None
    }
    self.reservations.put(reservation_id, status_info)
    utils.log('Generated reservation id {0} for this request.'.format(
      reservation_id))
    #TODO: We are forcing blocking mode because of how the Google App Engine sandbox environment
    # joins on all threads before returning a response from a request, which effectively makes non-
    # blocking mode the same as blocking mode anyways.
    # (see https://developers.google.com/appengine/docs/python/#Python_The_sandbox)
    if self.blocking or True:
      utils.log('Running spawn_vms in blocking mode')
      self.__spawn_vms(agent, num_vms, parameters, reservation_id)
    else:
      utils.log('Running spawn_vms in non-blocking mode')
      thread.start_new_thread(self.__spawn_vms,
        (agent, num_vms, parameters, reservation_id))
    utils.log('Successfully started request {0}.'.format(reservation_id))
    return self.__generate_response(True,
      self.REASON_NONE, {'reservation_id': reservation_id})
예제 #12
0
    def prepare_instances(self, parameters):
        """
        Prepare and setup a new virtual machine deployment using the provided parameters. The
        input parameter set must include an 'infrastructure' parameter which indicates
        the exact cloud environment to use. Value of this parameter will be used to
        instantiate a cloud environment specific agent which knows how to interact
        with the specified cloud platform. The parameters map must also contain a
        'num_vms' parameter which indicates the number of virtual machines that should
        be spawned. In addition to that any parameters required to spawn VMs in the
        specified cloud environment must be included in the parameters map.

        If this InfrastructureManager instance has been created in the blocking mode,
        this method will not return until the VM deployment is complete. Otherwise
        this method will simply kick off the VM deployment process and return
        immediately.

        Args:
          parameters  A parameter map containing the keys 'infrastructure',
                      'num_vms' and any other cloud platform specific
                      parameters. Alternatively one may provide a valid
                      JSON string instead of a dictionary object.

        Returns:
          If the secret is valid and all the required parameters are available in
          the input parameter map, this method will return a dictionary containing
          a special 'reservation_id' key. If the secret is invalid or a required
          parameter is missing, this method will return a different map with the
          key 'success' set to False and 'reason' set to a simple error message.

        Raises:
          TypeError   If the inputs are not of the expected types
          ValueError  If the input JSON string (parameters) cannot be parsed properly
        """

        reservation_id = parameters['reservation_id']
        logging.info('Received a request to prepare instances.')
        logging.info('Requested reservation_id = {0}'.format(reservation_id))

        logging.info('Request parameters are {0}'.format(parameters))
        for param in self.PREPARE_INSTANCES_REQUIRED_PARAMS:
            if not utils.has_parameter(param, parameters):
                logging.error('no {0}'.format(param))
                return self.__generate_response(False, 'no ' + param)

        infrastructure = parameters[self.PARAM_INFRASTRUCTURE]
        logging.info('infrastructure = {0}'.format(infrastructure))
        agent = self.agent_factory.create_agent(infrastructure)

        try:
            agent.assert_required_parameters(parameters, BaseAgent.OPERATION_PREPARE)
        except AgentConfigurationException as exception:
            logging.error(str(exception))
            return self.__generate_response(False, exception.message)

        keyname = parameters[self.PARAM_KEYNAME]
        if keyname is None:
            logging.info('Invalid keyname: ' + keyname)
            return self.__generate_response(False, self.REASON_BAD_ARGUMENTS)

        if self.blocking:
            logging.info('Running __prepare_vms in blocking mode')
            result = self.__prepare_vms(agent, len(parameters['vms']), parameters, reservation_id)

            # NOTE: We will only be able to return an IP for the started instances when run in blocking
            #       mode, but this is needed to update the queue head IP in celeryconfig.py.

            return result

        else:
            logging.info('Running prepare_vms in non-blocking mode...')

            # send the spawn vms task to backend server
            from_fields = {
                'op': InfrastructureManager.PREPARE_VMS_OP,
                'infra': pickle.dumps(self),
                'agent': pickle.dumps(agent),
                'parameters': pickle.dumps(parameters),
                'reservation_id': pickle.dumps(reservation_id)
            }

            taskqueue.add(url=InfrastructureManager.BACKEND_QUEUE_URL, params=from_fields, method='GET')

            logging.info('Successfully sent request to backend server, reservation_id: {0}.'.format(reservation_id))
            return self.__generate_response(True, 'Succeeded in sending request to backend server.')
    def prepare_instances(self, parameters):
        """
        Prepare and setup a new virtual machine deployment using the provided parameters. The
        input parameter set must include an 'infrastructure' parameter which indicates
        the exact cloud environment to use. Value of this parameter will be used to
        instantiate a cloud environment specific agent which knows how to interact
        with the specified cloud platform. The parameters map must also contain a
        'num_vms' parameter which indicates the number of virtual machines that should
        be spawned. In addition to that any parameters required to spawn VMs in the
        specified cloud environment must be included in the parameters map.

        If this InfrastructureManager instance has been created in the blocking mode,
        this method will not return until the VM deployment is complete. Otherwise
        this method will simply kick off the VM deployment process and return
        immediately.

        Args:
          parameters  A parameter map containing the keys 'infrastructure',
                      'num_vms' and any other cloud platform specific
                      parameters. Alternatively one may provide a valid
                      JSON string instead of a dictionary object.

        Returns:
          If the secret is valid and all the required parameters are available in
          the input parameter map, this method will return a dictionary containing
          a special 'reservation_id' key. If the secret is invalid or a required
          parameter is missing, this method will return a different map with the
          key 'success' set to False and 'reason' set to a simple error message.

        Raises:
          TypeError   If the inputs are not of the expected types
          ValueError  If the input JSON string (parameters) cannot be parsed properly
        """

        reservation_id = parameters['reservation_id']
        logging.info('Received a request to prepare instances.')
        logging.info('Requested reservation_id = {0}'.format(reservation_id))

        logging.info('Request parameters are {0}'.format(parameters))
        for param in self.PREPARE_INSTANCES_REQUIRED_PARAMS:
            if not utils.has_parameter(param, parameters):
                logging.error('no {0}'.format(param))
                return self.__generate_response(False, 'no ' + param)

        infrastructure = parameters[self.PARAM_INFRASTRUCTURE]
        logging.info('infrastructure = {0}'.format(infrastructure))
        agent = self.agent_factory.create_agent(infrastructure)

        try:
            agent.assert_required_parameters(parameters,
                                             BaseAgent.OPERATION_PREPARE)
        except AgentConfigurationException as exception:
            logging.error(str(exception))
            return self.__generate_response(False, exception.message)

        keyname = parameters[self.PARAM_KEYNAME]
        if keyname is None:
            logging.info('Invalid keyname: ' + keyname)
            return self.__generate_response(False, self.REASON_BAD_ARGUMENTS)

        if self.blocking:
            logging.info('Running __prepare_vms in blocking mode')
            result = self.__prepare_vms(agent, len(parameters['vms']),
                                        parameters, reservation_id)

            # NOTE: We will only be able to return an IP for the started instances when run in blocking
            #       mode, but this is needed to update the queue head IP in celeryconfig.py.

            return result

        else:
            logging.info('Running prepare_vms in non-blocking mode...')

            # send the spawn vms task to backend server
            from_fields = {
                'op': InfrastructureManager.PREPARE_VMS_OP,
                'infra': pickle.dumps(self),
                'agent': pickle.dumps(agent),
                'parameters': pickle.dumps(parameters),
                'reservation_id': pickle.dumps(reservation_id)
            }

            taskqueue.add(url=InfrastructureManager.BACKEND_QUEUE_URL,
                          params=from_fields,
                          method='GET')

            logging.info(
                'Successfully sent request to backend server, reservation_id: {0}.'
                .format(reservation_id))
            return self.__generate_response(
                True, 'Succeeded in sending request to backend server.')
예제 #14
0
  def terminate_instances(self, parameters, secret):
    """
    Terminate a virtual machine using the provided parameters.
    The input parameter map must contain an 'infrastructure' parameter which
    will be used to instantiate a suitable cloud agent. Any additional
    environment specific parameters should also be available in the same
    map.

    If this InfrastructureManager instance has been created in the blocking mode,
    this method will not return until the VM deployment is complete. Otherwise
    this method simply starts the VM termination process and returns immediately.

    Args:
      parameters  A dictionary of parameters containing the required
                  'infrastructure' parameter and any other platform
                  dependent required parameters. Alternatively one
                  may provide a valid JSON string instead of a dictionary
                  object.
      secret      A previously established secret

    Returns:
      If the secret is valid and all the required parameters are available in
      the input parameter map, this method will return a dictionary containing
      a special 'operation_id' key. If the secret is invalid or a required
      parameter is missing, this method will return a different map with the
      key 'success' set to False and 'reason' set to a simple error message.

    Raises:
      TypeError   If the inputs are not of the expected types
      ValueError  If the input JSON string (parameters) cannot be parsed properly
    """
    parameters, secret = self.__validate_args(parameters, secret)

    if self.secret != secret:
      return self.__generate_response(False, self.REASON_BAD_SECRET)

    for param in self.TERMINATE_INSTANCES_REQUIRED_PARAMS:
      if not utils.has_parameter(param, parameters):
        return self.__generate_response(False, 'no ' + param)

    infrastructure = parameters[self.PARAM_INFRASTRUCTURE]
    agent = self.agent_factory.create_agent(infrastructure)
    try:
      agent.assert_required_parameters(parameters,
        BaseAgent.OPERATION_TERMINATE)
    except AgentConfigurationException as exception:
      return self.__generate_response(False, str(exception))

    operation_id = utils.get_random_alphanumeric()
    status_info = {
      'success': True,
      'reason': 'received kill request',
      'state': self.STATE_PENDING
    }
    self.operation_ids.put(operation_id, status_info)
    utils.log('Generated operation id {0} for this terminate instances '
              'request.'.format(operation_id))

    if self.blocking:
      self.__kill_vms(agent, parameters, operation_id)
    else:
      thread.start_new_thread(self.__kill_vms,
                              (agent, parameters, operation_id))

    utils.log('Successfully started terminate instances request {0}.'.format(
        operation_id))
    return self.__generate_response(True,
      self.REASON_NONE, {'operation_id': operation_id})
예제 #15
0
  def run_instances(self, parameters, secret):
    """
    Start a new virtual machine deployment using the provided parameters. The
    input parameter set must include an 'infrastructure' parameter which indicates
    the exact cloud environment to use. Value of this parameter will be used to
    instantiate a cloud environment specific agent which knows how to interact
    with the specified cloud platform. The parameters map must also contain a
    'num_vms' parameter which indicates the number of virtual machines that should
    be spawned. In addition to that any parameters required to spawn VMs in the
    specified cloud environment must be included in the parameters map.

    If this InfrastructureManager instance has been created in the blocking mode,
    this method will not return until the VM deployment is complete. Otherwise
    this method will simply kick off the VM deployment process and return
    immediately.

    Args:
      parameters  A parameter map containing the keys 'infrastructure',
                  'num_vms' and any other cloud platform specific
                  parameters. Alternatively one may provide a valid
                  JSON string instead of a dictionary object.
      secret      A previously established secret

    Returns:
      If the secret is valid and all the required parameters are available in
      the input parameter map, this method will return a dictionary containing
      a special 'operation_id' key. If the secret is invalid or a required
      parameter is missing, this method will return a different map with the
      key 'success' set to False and 'reason' set to a simple error message.

    Raises:
      TypeError   If the inputs are not of the expected types
      ValueError  If the input JSON string (parameters) cannot be parsed properly
    """
    parameters, secret = self.__validate_args(parameters, secret)

    utils.log('Received a request to run instances.')

    if self.secret != secret:
      utils.log('Incoming secret {0} does not match the current secret {1} - '\
                'Rejecting request.'.format(secret, self.secret))
      return self.__generate_response(False, self.REASON_BAD_SECRET)

    for param in self.RUN_INSTANCES_REQUIRED_PARAMS:
      if not utils.has_parameter(param, parameters):
        return self.__generate_response(False, 'no ' + param)

    num_vms = int(parameters[self.PARAM_NUM_VMS])
    if num_vms <= 0:
      utils.log('Invalid VM count: {0}'.format(num_vms))
      return self.__generate_response(False, self.REASON_BAD_VM_COUNT)

    infrastructure = parameters[self.PARAM_INFRASTRUCTURE]
    agent = self.agent_factory.create_agent(infrastructure)
    try:
      agent.assert_required_parameters(parameters, BaseAgent.OPERATION_RUN)
    except AgentConfigurationException as exception:
      return self.__generate_response(False, str(exception))

    operation_id = utils.get_random_alphanumeric()
    status_info = {
      'success': True,
      'reason': 'received run request',
      'state': self.STATE_PENDING,
      'vm_info': None
    }
    self.operation_ids.put(operation_id, status_info)
    utils.log('Generated operation id {0} for this run '
              'instances request.'.format(operation_id))
    if self.blocking:
      self.__spawn_vms(agent, num_vms, parameters, operation_id)
    else:
      thread.start_new_thread(self.__spawn_vms,
        (agent, num_vms, parameters, operation_id))

    utils.log('Successfully started run instances request {0}.'.format(
        operation_id))
    return self.__generate_response(True,
      self.REASON_NONE, {'operation_id': operation_id})