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
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)
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
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())
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
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