Exemple #1
0
    def InitFromObject(cls, cron_job):
        api_cron_job = ApiCronJob(
            cron_job_id=cron_job.cron_job_id,
            args=cron_job.args,
            # TODO(amoser): AFF4 does not keep this data. Enable once we don't have
            # aff4 to support anymore.
            # created_at=cron_job.created_at,
            current_run_id=cron_job.current_run_id or None,
            description=cron_job.description,
            enabled=cron_job.enabled,
            last_run_status=cron_job.last_run_status or None,
            last_run_time=cron_job.last_run_time,
            frequency=cron_job.frequency,
            lifetime=cron_job.lifetime or None,
            allow_overruns=cron_job.allow_overruns,
            is_failing=cls._IsCronJobObjectFailing(cron_job))

        if cron_job.forced_run_requested:
            api_cron_job.forced_run_requested = True

        state_dict = cron_job.state.ToDict()
        if state_dict:
            state = api_call_handler_utils.ApiDataObject()
            state.InitFromDataObject(state_dict)
            api_cron_job.state = state

        return api_cron_job
Exemple #2
0
  def Handle(self, args, token=None):
    """Retrieves the context for a hunt."""
    hunt = aff4.FACTORY.Open(
        args.hunt_id.ToURN(), aff4_type=implementation.GRRHunt, token=token)

    if isinstance(hunt.context, rdf_hunts.HuntContext):  # New style hunt.
      # TODO(amoser): Hunt state will go away soon, we don't render it anymore.
      state = api_call_handler_utils.ApiDataObject()
      result = ApiGetHuntContextResult(context=hunt.context, state=state)
      # Assign args last since it needs the other fields set to
      # determine the args protobuf.
      result.args = hunt.args
      return result

    else:
      # Just pack the whole context data object in the state
      # field. This contains everything for old style hunts so we at
      # least show the data somehow.
      context = api_call_handler_utils.ApiDataObject().InitFromDataObject(
          hunt.context)

      return ApiGetHuntContextResult(state=context)
Exemple #3
0
  def InitFromAff4Object(self, cron_job):
    cron_args = cron_job.Get(cron_job.Schema.CRON_ARGS)

    flow_name = cron_args.flow_runner_args.flow_name
    if flow_name == "CreateAndRunGenericHuntFlow":
      action_type = rdf_cronjobs.CronJobAction.ActionType.HUNT_CRON_ACTION
      hunt_args = cron_args.flow_args.hunt_args
      # Hunt name is always GenericHunt, no need to keep it around.
      cron_args.flow_args.hunt_runner_args.hunt_name = None
      args = rdf_cronjobs.CronJobAction(
          action_type=action_type,
          hunt_cron_action=rdf_cronjobs.HuntCronAction(
              hunt_runner_args=cron_args.flow_args.hunt_runner_args,
              flow_args=hunt_args.flow_args,
              flow_name=hunt_args.flow_runner_args.flow_name,
          ))
    else:
      action_type = rdf_cronjobs.CronJobAction.ActionType.SYSTEM_CRON_ACTION
      args = rdf_cronjobs.CronJobAction(
          action_type=action_type,
          system_cron_action=rdf_cronjobs.SystemCronAction(
              job_class_name=cron_args.flow_runner_args.flow_name))

    api_cron_job = ApiCronJob(
        cron_job_id=cron_job.urn.Basename(),
        args=args,
        enabled=not cron_job.Get(cron_job.Schema.DISABLED),
        last_run_status=self._StatusFromCronJobRunStatus(
            cron_job.Get(cron_job.Schema.LAST_RUN_STATUS)),
        last_run_time=cron_job.Get(cron_job.Schema.LAST_RUN_TIME),
        frequency=cron_args.periodicity,
        lifetime=cron_args.lifetime or None,
        allow_overruns=cron_args.allow_overruns,
        description=cron_args.description,
        is_failing=self._IsCronJobFailing(cron_job))

    state_dict = cron_job.Get(cron_job.Schema.STATE_DICT)
    if state_dict:
      state = api_call_handler_utils.ApiDataObject()
      state.InitFromDataObject(state_dict)
      api_cron_job.state = state

    current_flow_urn = cron_job.Get(cron_job.Schema.CURRENT_FLOW_URN)
    if current_flow_urn:
      api_cron_job.current_run_id = current_flow_urn.Basename()

    return api_cron_job
Exemple #4
0
 def Handle(self, args, context=None):
   hunt_id = str(args.hunt_id)
   h = data_store.REL_DB.ReadHuntObject(hunt_id)
   h_counters = data_store.REL_DB.ReadHuntCounters(hunt_id)
   context = rdf_hunts.HuntContext(
       session_id=rdfvalue.RDFURN("hunts").Add(h.hunt_id),
       create_time=h.create_time,
       creator=h.creator,
       duration=h.duration,
       network_bytes_sent=h_counters.total_network_bytes_sent,
       next_client_due=h.last_start_time,
       start_time=h.last_start_time,
       # TODO(user): implement proper hunt client resources starts support
       # for REL_DB hunts.
       # usage_stats=h.client_resources_stats
   )
   return ApiGetHuntContextResult(
       context=context, state=api_call_handler_utils.ApiDataObject())
Exemple #5
0
    def InitFromFlowObject(self,
                           flow_obj,
                           with_args=True,
                           with_progress=False,
                           with_state_and_context=False):
        try:
            self.flow_id = flow_obj.flow_id
            self.client_id = flow_obj.client_id

            # TODO(amoser): Get rid of all urns.
            self.urn = flow_obj.long_flow_id

            self.name = flow_obj.flow_class_name
            self.started_at = flow_obj.create_time
            self.last_active_at = flow_obj.last_update_time
            self.creator = flow_obj.creator

            if flow_obj.client_crash_info:
                self.state = "CLIENT_CRASHED"
            elif flow_obj.pending_termination:
                self.state = "ERROR"
                self.status = ("Pending termination: %s" %
                               flow_obj.pending_termination.reason)
            else:
                context_state_map = {1: "RUNNING", 2: "TERMINATED", 3: "ERROR"}
                self.state = context_state_map[int(flow_obj.flow_state)]

            if with_state_and_context:
                outstanding_requests = (flow_obj.next_outbound_id -
                                        flow_obj.next_request_to_process)
                self.context = rdf_flow_runner.FlowContext(
                    # TODO(amoser): No need to set this in all cases once the legacy API
                    # is removed.
                    client_resources=rdf_client_stats.ClientResources(
                        cpu_usage=rdf_client_stats.CpuSeconds()),
                    create_time=flow_obj.create_time,
                    creator=flow_obj.creator,
                    current_state=flow_obj.current_state,
                    next_outbound_id=flow_obj.next_outbound_id,
                    outstanding_requests=outstanding_requests,
                    state=self.state,
                    # TODO(amoser): Get rid of all urns.
                    session_id=flow_obj.long_flow_id,
                )
                if flow_obj.output_plugins_states:
                    self.context.output_plugins_states = flow_obj.output_plugins_states
                if flow_obj.network_bytes_sent:
                    self.context.network_bytes_sent = flow_obj.network_bytes_sent
                    self.context.client_resources.network_bytes_sent = (
                        flow_obj.network_bytes_sent)
                if flow_obj.cpu_time_used:
                    self.context.client_resources.cpu_time_used = flow_obj.cpu_time_used
                if flow_obj.error_message:
                    self.context.status = flow_obj.error_message
                if flow_obj.backtrace:
                    self.context.backtrace = flow_obj.backtrace

            if with_args:
                try:
                    self.args = flow_obj.args
                except ValueError:
                    # If args class name has changed, ValueError will be raised. Handling
                    # this gracefully - we should still try to display some useful info
                    # about the flow.
                    pass

            if with_progress:
                flow_cls = self._GetFlowClass()
                if flow_cls:
                    self.progress = flow_cls(flow_obj).GetProgress()

            self.runner_args = rdf_flow_runner.FlowRunnerArgs(
                client_id=flow_obj.client_id,
                flow_name=flow_obj.flow_class_name,
                notify_to_user=flow_base.FlowBase(
                    flow_obj).ShouldSendNotifications())

            if flow_obj.output_plugins:
                self.runner_args.output_plugins = flow_obj.output_plugins

            if flow_obj.HasField("cpu_limit"):
                self.runner_args.cpu_limit = flow_obj.cpu_limit

            if flow_obj.HasField("network_bytes_limit"):
                self.runner_args.cpu_limit = flow_obj.network_bytes_limit

            if flow_obj.original_flow.flow_id:
                self.original_flow = ApiFlowReference().FromFlowReference(
                    flow_obj.original_flow)

            if with_state_and_context and flow_obj.persistent_data.ToDict():
                self.state_data = (
                    api_call_handler_utils.ApiDataObject().InitFromDataObject(
                        flow_obj.persistent_data))

        except Exception as e:  # pylint: disable=broad-except
            self.internal_error = "Error while opening flow: %s" % str(e)

        return self
Exemple #6
0
    def InitFromAff4Object(self,
                           flow_obj,
                           flow_id=None,
                           with_state_and_context=False):
        try:
            # TODO(user): we should be able to infer flow id from the
            # URN. Currently it's not possible due to an inconsistent way in
            # which we create symlinks and name them.
            self.flow_id = flow_id
            self.urn = flow_obj.urn

            first_component = self.urn.Split()[0]
            try:
                self.client_id = first_component
            except ValueError:
                # This is not a client-based flow, nothing to be done here.
                pass

            self.name = flow_obj.runner_args.flow_name
            self.started_at = flow_obj.context.create_time
            self.last_active_at = flow_obj.Get(flow_obj.Schema.LAST)
            self.creator = flow_obj.context.creator

            if flow_obj.Get(flow_obj.Schema.CLIENT_CRASH):
                self.state = "CLIENT_CRASHED"
            elif flow_obj.Get(flow_obj.Schema.PENDING_TERMINATION):
                self.state = flow_obj.context.state = "ERROR"
                reason = flow_obj.Get(
                    flow_obj.Schema.PENDING_TERMINATION).reason
                flow_obj.context.status = "Pending termination: %s" % reason
            else:
                self.state = flow_obj.context.state

            try:
                self.args = flow_obj.args
            except ValueError:
                # If args class name has changed, ValueError will be raised. Handling
                # this gracefully - we should still try to display some useful info
                # about the flow.
                pass

            self.runner_args = flow_obj.runner_args

            if self.runner_args.original_flow.flow_id:
                self.original_flow = ApiFlowReference().FromFlowReference(
                    self.runner_args.original_flow)

            if with_state_and_context:
                try:
                    self.context = flow_obj.context
                except ValueError:
                    pass

                flow_state_dict = flow_obj.Get(flow_obj.Schema.FLOW_STATE_DICT)
                if flow_state_dict is not None:
                    flow_state_data = flow_state_dict.ToDict()

                    if flow_state_data:
                        self.state_data = (
                            api_call_handler_utils.ApiDataObject(
                            ).InitFromDataObject(flow_state_data))
        except Exception as e:  # pylint: disable=broad-except
            self.internal_error = "Error while opening flow: %s" % str(e)

        return self