def testSystemCronFlowsMayBeDisabledViaConfig(self): with test_lib.ConfigOverrider({ "Cron.disabled_system_jobs": ["DummySystemCronJob"] }): aff4_cronjobs.ScheduleSystemCronFlows(token=self.token) jobs = aff4_cronjobs.GetCronManager().ListJobs(token=self.token) self.assertIn("DummySystemCronJob", jobs) # This cron job should be disabled, because it's listed in # Cron.disabled_system_jobs config variable. job = aff4_cronjobs.GetCronManager().ReadJob( "DummySystemCronJob", token=self.token) self.assertTrue(job.Get(job.Schema.DISABLED)) # Now remove the cron job from the list and check that it gets disabled # after next ScheduleSystemCronFlows() call. with test_lib.ConfigOverrider({"Cron.disabled_system_jobs": []}): aff4_cronjobs.ScheduleSystemCronFlows(token=self.token) # System cron job should be enabled. job = aff4_cronjobs.GetCronManager().ReadJob( "DummySystemCronJob", token=self.token) self.assertFalse(job.Get(job.Schema.DISABLED))
def testSystemCronJobSetsStartTime(self): with test_lib.FakeTime(100): now = rdfvalue.RDFDatetime.Now() aff4_cronjobs.ScheduleSystemCronFlows( names=[ DummySystemCronJob.__name__, DummySystemCronJobStartNow.__name__ ], token=self.token) random_time = "DummySystemCronJob" no_random_time = "DummySystemCronJobStartNow" random_time_job = aff4_cronjobs.GetCronManager().ReadJob( random_time, token=self.token) no_random_time_job = aff4_cronjobs.GetCronManager().ReadJob( no_random_time, token=self.token) start_time_now = no_random_time_job.Get( no_random_time_job.Schema.CRON_ARGS).start_time self.assertEqual(start_time_now, now) random_start_time = random_time_job.Get( random_time_job.Schema.CRON_ARGS).start_time self.assertTrue( now < random_start_time < (now + DummySystemCronJob.frequency))
def testDeletesCronFromCollection(self): jobs = list(cronjobs.GetCronManager().ListJobs(token=self.token)) self.assertEqual(len(jobs), 1) self.assertEqual(jobs[0], self.cron_job_id) args = cron_plugin.ApiDeleteCronJobArgs(cron_job_id=self.cron_job_id) self.handler.Handle(args, token=self.token) jobs = list(cronjobs.GetCronManager().ListJobs(token=self.token)) self.assertEqual(len(jobs), 0)
def testSystemCronFlowsWithDisabledAttributeDoNotGetScheduled(self): aff4_cronjobs.ScheduleSystemCronFlows( names=[DummyDisabledSystemCronJob.__name__], token=self.token) jobs = aff4_cronjobs.GetCronManager().ListJobs(token=self.token) self.assertIn("DummyDisabledSystemCronJob", jobs) # System cron job should be enabled by default. job = aff4_cronjobs.GetCronManager().ReadJob( "DummyDisabledSystemCronJob", token=self.token) self.assertTrue(job.Get(job.Schema.DISABLED))
def testSystemCronFlowsGetScheduledAutomatically(self): aff4_cronjobs.ScheduleSystemCronFlows( names=[DummySystemCronJob.__name__], token=self.token) jobs = aff4_cronjobs.GetCronManager().ListJobs(token=self.token) self.assertIn("DummySystemCronJob", jobs) # System cron job should be enabled by default. job = aff4_cronjobs.GetCronManager().ReadJob( "DummySystemCronJob", token=self.token) self.assertFalse(job.Get(job.Schema.DISABLED))
def setUp(self): super(ApiListCronJobFlowsHandlerRegressionTest, self).setUp() with test_lib.FakeTime(44): cron_args = rdf_cronjobs.CreateCronJobFlowArgs(periodicity="7d", lifetime="1d") cron_args.flow_runner_args.flow_name = self.flow_name cronjobs.GetCronManager().CreateJob(cron_args, job_id=self.flow_name, token=self.token) cronjobs.GetCronManager().RunOnce(token=self.token)
def Handle(self, args, token=None): cron_id = str(args.cron_job_id) if args.state == "ENABLED": aff4_cronjobs.GetCronManager().EnableJob(cron_id, token=token) elif args.state == "DISABLED": aff4_cronjobs.GetCronManager().DisableJob(cron_id, token=token) else: raise ValueError("Invalid cron job state: %s" % str(args.state)) cron_job_obj = aff4_cronjobs.GetCronManager().ReadJob(cron_id, token=token) return ApiCronJob().InitFromObject(cron_job_obj)
def setUp(self): super(TestCronView, self).setUp() for flow_name in [ cron_system.GRRVersionBreakDown.__name__, cron_system.OSBreakDown.__name__, cron_system.LastAccessStats.__name__ ]: cron_args = rdf_cronjobs.CreateCronJobFlowArgs( periodicity="7d", lifetime="1d") cron_args.flow_runner_args.flow_name = flow_name cronjobs.GetCronManager().CreateJob( cron_args, job_id=flow_name, token=self.token) cronjobs.GetCronManager().RunOnce(token=self.token)
def setUp(self): super(ApiGetCronJobFlowHandlerRegressionTest, self).setUp() self.flow_name = cron_system.GRRVersionBreakDown.__name__ with test_lib.FakeTime(44): cron_args = cronjobs.CreateCronJobFlowArgs(periodicity="7d", lifetime="1d") cron_args.flow_runner_args.flow_name = self.flow_name cronjobs.GetCronManager().CreateJob(cron_args, job_id=self.flow_name, token=self.token) cronjobs.GetCronManager().RunOnce(token=self.token)
def testCronJobPreservesFlowNameAndArguments(self): """Testing initialization of a ConfigManager.""" pathspec = rdf_paths.PathSpec( path="/foo", pathtype=rdf_paths.PathSpec.PathType.TSK) cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs( periodicity="1d", allow_overruns=False) cron_args.flow_runner_args.flow_name = transfer.GetFile.__name__ cron_args.flow_args.pathspec = pathspec job_id = cron_manager.CreateJob(cron_args=cron_args) # Check that CronJob definition is saved properly jobs = cron_manager.ListJobs(token=self.token) self.assertEqual(len(jobs), 1) self.assertEqual(jobs[0], job_id) cron_job = cron_manager.ReadJob(job_id, token=self.token) self.assertEqual(cron_job.cron_args.flow_runner_args.flow_name, transfer.GetFile.__name__) self.assertEqual(cron_job.cron_args.flow_args.pathspec, pathspec) self.assertEqual(cron_job.cron_args.periodicity, rdfvalue.Duration("1d")) self.assertEqual(cron_job.cron_args.allow_overruns, False)
def Run(self): with test_lib.FakeTime(42): self.CreateUser("approver") cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs(periodicity="1d", allow_overruns=False) cron_id = cron_manager.CreateJob(cron_args=cron_args, token=self.token) def ReplaceCronAndApprovalIds(): approvals = self.ListCronJobApprovals() return { approvals[0].id: "approval:112233", cron_id: "CronJob_123456" } with test_lib.FakeTime(126): self.Check("CreateCronJobApproval", args=user_plugin.ApiCreateCronJobApprovalArgs( cron_job_id=cron_id, approval=user_plugin.ApiCronJobApproval( reason="really important reason!", notified_users=["approver1", "approver2"], email_cc_addresses=["*****@*****.**"])), replace=ReplaceCronAndApprovalIds)
def testEmailCronJobApprovalRequestLinkLeadsToACorrectPage(self): cronjobs.ScheduleSystemCronFlows( names=[cron_system.OSBreakDown.__name__], token=self.token) cronjobs.GetCronManager().DisableJob(job_id="OSBreakDown") self.RequestCronJobApproval( "OSBreakDown", reason=self.APPROVAL_REASON, approver=self.GRANTOR_USERNAME, requestor=self.token.username) self.assertEqual(len(self.messages_sent), 1) message = self.messages_sent[0] self.assertIn(self.APPROVAL_REASON, message) self.assertIn(self.token.username, message) self.assertIn("OSBreakDown", message) # Extract link from the message text and open it. m = re.search(r"href='(.+?)'", message, re.MULTILINE) link = urlparse.urlparse(m.group(1)) self.Open(link.path + "?" + link.query + "#" + link.fragment) # Check that requestor's username and reason are correctly displayed. self.WaitUntil(self.IsTextPresent, self.token.username) self.WaitUntil(self.IsTextPresent, self.APPROVAL_REASON) # Check that host information is displayed. self.WaitUntil(self.IsTextPresent, cron_system.OSBreakDown.__name__) self.WaitUntil(self.IsTextPresent, "Periodicity")
def Run(self): with test_lib.FakeTime(42): self.CreateAdminUser("requestor") cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs( periodicity="1d", allow_overruns=False) cron_id = cron_manager.CreateJob(cron_args=cron_args, token=self.token) with test_lib.FakeTime(44): approval_id = self.RequestCronJobApproval( cron_id, approver=self.token.username, requestor="requestor", reason="foo") with test_lib.FakeTime(126): self.Check( "GrantCronJobApproval", args=user_plugin.ApiGrantCronJobApprovalArgs( cron_job_id=cron_id, approval_id=approval_id, username="******"), replace={ cron_id: "CronJob_123456", approval_id: "approval:111111" })
def testLastRunStatusGetsUpdatedOnEveryRun(self): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs() cron_args.flow_runner_args.flow_name = "OccasionallyFailingFakeCronJob" cron_args.periodicity = "30s" job_id = cron_manager.CreateJob(cron_args=cron_args, token=self.token) for fake_time in [0, 60]: with test_lib.FakeTime(fake_time): # This call should start a new cron job flow cron_manager.RunOnce(token=self.token) cron_job = cron_manager.ReadJob(job_id, token=self.token) cron_flow_urn = cron_job.Get(cron_job.Schema.CURRENT_FLOW_URN) flow_test_lib.TestFlowHelper( cron_flow_urn, check_flow_errors=False, token=self.token) # This RunOnce call should determine that the flow has finished cron_manager.RunOnce(token=self.token) cron_job = cron_manager.ReadJob(job_id, token=self.token) statuses = list( cron_job.GetValuesForAttribute(cron_job.Schema.LAST_RUN_STATUS)) statuses = sorted(statuses, key=lambda x: x.age) self.assertEqual(len(statuses), 2) self.assertEqual(statuses[0].age, rdfvalue.RDFDatetime.FromSecondsSinceEpoch(0)) self.assertEqual(statuses[1].age, rdfvalue.RDFDatetime.FromSecondsSinceEpoch(60)) self.assertEqual(statuses[0].status, rdf_cronjobs.CronJobRunStatus.Status.OK) self.assertEqual(statuses[1].status, rdf_cronjobs.CronJobRunStatus.Status.ERROR)
def testLastRunStatusGetsUpdated(self): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs() cron_args.flow_runner_args.flow_name = "OccasionallyFailingFakeCronJob" cron_args.periodicity = "30s" job_id = cron_manager.CreateJob(cron_args=cron_args) statuses = [] for fake_time in [0, 60]: with test_lib.FakeTime(fake_time): # This call should start a new cron job flow cron_manager.RunOnce(token=self.token) run_urn = cron_manager.ReadJobRuns(job_id)[-1].urn flow_test_lib.TestFlowHelper( run_urn, check_flow_errors=False, token=self.token) # This RunOnce call should determine that the flow has finished cron_manager.RunOnce(token=self.token) cron_job = cron_manager.ReadJob(job_id, token=self.token) statuses.append(cron_job.last_run_status) statuses = sorted(statuses, key=lambda x: x.age) self.assertEqual(len(statuses), 2) self.assertEqual(statuses[0], rdf_cronjobs.CronJobRunStatus.Status.OK) self.assertEqual(statuses[1], rdf_cronjobs.CronJobRunStatus.Status.ERROR)
def testCronJobRunAllowsOverrunsWhenAllowOverrunsIsTrue(self): with test_lib.FakeTime(0): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs( allow_overruns=True, periodicity="1h") cron_args.flow_runner_args.flow_name = "FakeCronJob" job_id = cron_manager.CreateJob(cron_args=cron_args) cron_manager.RunOnce(token=self.token) cron_job_runs = cron_manager.ReadJobRuns(job_id, token=self.token) self.assertEqual(len(cron_job_runs), 1) # Let an hour pass. Frequency is 1h (i.e. cron job iterations are # supposed to be started every hour), so the new flow should be started # by RunOnce(). Previous iteration flow hasn't finished yet, but # allow_overruns is True, so it's ok to start new iteration. time.time = lambda: 60 * 60 + 1 cron_manager.RunOnce(token=self.token) cron_job_runs = cron_manager.ReadJobRuns(job_id, token=self.token) self.assertEqual(len(cron_job_runs), 2)
def testLatencyStatsAreCorrectlyRecorded(self): with test_lib.FakeTime(0): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs() cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_args.periodicity = "1w" cron_job_id = cron_manager.CreateJob( cron_args=cron_args, token=self.token) cron_manager.RunOnce(token=self.token) prev_metric_value = stats.STATS.GetMetricValue( "cron_job_latency", fields=[cron_job_id]) # Fast forward one minute with test_lib.FakeTime(60): cron_manager.RunOnce(token=self.token) cron_job = cron_manager.ReadJob(cron_job_id, token=self.token) cron_flow_urn = cron_job.Get(cron_job.Schema.CURRENT_FLOW_URN) flow_test_lib.TestFlowHelper( cron_flow_urn, check_flow_errors=False, token=self.token) # This RunOnce call should determine that the flow has finished cron_manager.RunOnce(token=self.token) # Check that stats got updated current_metric_value = stats.STATS.GetMetricValue( "cron_job_latency", fields=[cron_job_id]) self.assertEqual(current_metric_value.count - prev_metric_value.count, 1) self.assertEqual(current_metric_value.sum - prev_metric_value.sum, 60)
def Handle(self, args, token=None): try: cron_job = aff4_cronjobs.GetCronManager().ReadJob( str(args.cron_job_id), token=token) return ApiCronJob().InitFromObject(cron_job) except aff4.InstantiationError: raise CronJobNotFoundError( "Cron job with id %s could not be found" % args.cron_job_id)
def setUp(self): super(CleanCronJobsTest, self).setUp() with test_lib.FakeTime(40): cron_args = rdf_cronjobs.CreateCronJobFlowArgs( periodicity=RetentionTestSystemCronJob.frequency) cron_args.flow_runner_args.flow_name = RetentionTestSystemCronJob.__name__ cron_args.lifetime = RetentionTestSystemCronJob.lifetime self.cron_jobs_names = [] self.cron_jobs_names.append(cronjobs.GetCronManager().CreateJob( cron_args=cron_args, job_id="Foo", token=self.token, disabled=False)) self.cron_jobs_names.append(cronjobs.GetCronManager().CreateJob( cron_args=cron_args, job_id="Bar", token=self.token, disabled=False)) for i in range(self.NUM_CRON_RUNS): with test_lib.FakeTime(40 + 60 * i): cronjobs.GetCronManager().RunOnce(token=self.token, force=True)
def testSchedulingJobWithFixedNamePreservesTheName(self): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs( allow_overruns=True, periodicity="1d") cron_args.flow_runner_args.flow_name = "FakeCronJob" job_id = cron_manager.CreateJob(cron_args=cron_args, job_id="TheJob") self.assertEqual("TheJob", job_id)
def testDoesNothingIfAgeLimitNotSetInConfig(self): with test_lib.FakeTime(40 + 60 * self.NUM_CRON_RUNS): flow.GRRFlow.StartFlow( flow_name=data_retention.CleanCronJobs.__name__, sync=True, token=self.token) for name in self.cron_jobs_names: runs = cronjobs.GetCronManager().ReadJobRuns(name, token=self.token) self.assertEqual(len(runs), self.NUM_CRON_RUNS)
def Start(self): cron_jobs_ttl = config.CONFIG["DataRetention.cron_jobs_flows_ttl"] if not cron_jobs_ttl: self.Log("TTL not set - nothing to do...") return for job in cronjobs.GetCronManager().ReadJobs(token=self.token): age = rdfvalue.RDFDatetime.Now() - cron_jobs_ttl job.DeleteRuns(age) self.HeartBeat()
def testSystemCronJobsGetScheduledWhenDisabledListInvalid(self): with test_lib.ConfigOverrider({ "Cron.disabled_system_jobs": ["NonExistent"] }): with self.assertRaises(ValueError): aff4_cronjobs.ScheduleSystemCronFlows( names=[DummySystemCronJob.__name__], token=self.token) jobs = aff4_cronjobs.GetCronManager().ListJobs(token=self.token) self.assertIn("DummySystemCronJob", jobs)
def testDeletesFlowsOlderThanGivenAge(self): all_children = [] for cron_name in self.cron_jobs_names: all_children.extend(cronjobs.GetCronManager().ReadJobRuns( cron_name, token=self.token)) with test_lib.ConfigOverrider({ "DataRetention.cron_jobs_flows_ttl": rdfvalue.Duration("150s") }): # Only two iterations are supposed to survive, as they were running # every minute. with test_lib.FakeTime(40 + 60 * self.NUM_CRON_RUNS): flow.GRRFlow.StartFlow( flow_name=data_retention.CleanCronJobs.__name__, sync=True, token=self.token) latest_timestamp = rdfvalue.RDFDatetime.Now() remaining_children = [] for cron_name in self.cron_jobs_names: children = cronjobs.GetCronManager().ReadJobRuns( cron_name, token=self.token) self.assertEqual(len(children), 2) remaining_children.extend(children) for child in children: create_time = child.context.create_time self.assertLess(create_time, latest_timestamp) self.assertGreater(create_time, latest_timestamp - rdfvalue.Duration("150s")) # Only works with the test data store. if isinstance(data_store.DB, fake_data_store.FakeDataStore): # Check that no subjects are left behind that have anything to do with # the deleted flows (requests, responses, ...). deleted_flows = set(all_children) - set(remaining_children) for subject in data_store.DB.subjects: for flow_urn in deleted_flows: self.assertNotIn(str(flow_urn), subject)
def testToolbarStateForDisabledCronJob(self): cronjobs.GetCronManager().DisableJob(job_id="OSBreakDown") self.Open("/") self.Click("css=a[grrtarget=crons]") self.Click("css=td:contains('OSBreakDown')") self.assertTrue( self.IsElementPresent("css=button[name=EnableCronJob]:not([disabled])")) self.assertTrue( self.IsElementPresent("css=button[name=DisableCronJob][disabled]")) self.assertTrue( self.IsElementPresent("css=button[name=DeleteCronJob]:not([disabled])"))
def testCronJobRespectsStartTime(self): with test_lib.FakeTime(0): cron_manager = aff4_cronjobs.GetCronManager() start_time1 = rdfvalue.RDFDatetime(100 * 1000 * 1000) cron_args1 = rdf_cronjobs.CreateCronJobFlowArgs(start_time=start_time1) cron_args1.flow_runner_args.flow_name = "FakeCronJob" cron_args2 = rdf_cronjobs.CreateCronJobFlowArgs() cron_args2.flow_runner_args.flow_name = "FakeCronJob" cron_job_id1 = cron_manager.CreateJob(cron_args1) cron_job_id2 = cron_manager.CreateJob(cron_args2) cron_manager.RunOnce(token=self.token) cron_job1 = cron_manager.ReadJob(cron_job_id1, token=self.token) cron_job2 = cron_manager.ReadJob(cron_job_id2, token=self.token) self.assertEqual(cron_job1.cron_args.start_time, start_time1) # Flow without a start time should now be running self.assertFalse(cron_manager.JobIsRunning(cron_job1, token=self.token)) self.assertTrue(cron_manager.JobIsRunning(cron_job2, token=self.token)) # Move the clock past the start time with test_lib.FakeTime(500): cron_manager.RunOnce(token=self.token) cron_job1 = cron_manager.ReadJob(cron_job_id1, token=self.token) cron_job2 = cron_manager.ReadJob(cron_job_id2, token=self.token) # Start time should be the same self.assertEqual(cron_job1.cron_args.start_time, start_time1) # Now both should be running self.assertTrue(cron_manager.JobIsRunning(cron_job1, token=self.token)) self.assertTrue(cron_manager.JobIsRunning(cron_job2, token=self.token)) # Check setting a bad run id is handled. data_store.REL_DB.UpdateCronJob(cron_job2.job_id, current_run_id=12345) cron_job2 = cron_manager.ReadJob(cron_job_id2, token=self.token) self.assertFalse(cron_manager.JobIsRunning(cron_job2, token=self.token)) # Job got updated right away. self.assertFalse(cron_job2.current_run_id) # DB also reflects the removed run id. cron_job2 = cron_manager.ReadJob(cron_job_id2, token=self.token) self.assertFalse(cron_job2.current_run_id)
def testCronJobRespectsStartTime(self): with test_lib.FakeTime(0): cron_manager = aff4_cronjobs.GetCronManager() start_time1 = rdfvalue.RDFDatetime(100 * 1000 * 1000) cron_args1 = rdf_cronjobs.CreateCronJobFlowArgs(start_time=start_time1) cron_args1.flow_runner_args.flow_name = "FakeCronJob" cron_args2 = rdf_cronjobs.CreateCronJobFlowArgs() cron_args2.flow_runner_args.flow_name = "FakeCronJob" cron_job_id1 = cron_manager.CreateJob(cron_args1, token=self.token) cron_job_id2 = cron_manager.CreateJob(cron_args2, token=self.token) cron_manager.RunOnce(token=self.token) cron_job1 = cron_manager.ReadJob(cron_job_id1, token=self.token) cron_job2 = cron_manager.ReadJob(cron_job_id2, token=self.token) self.assertEqual( cron_job1.Get(cron_job1.Schema.CRON_ARGS).start_time, start_time1) # Flow without a start time should now be running self.assertFalse(cron_job1.IsRunning()) self.assertTrue(cron_job2.IsRunning()) # Move the clock past the start time with test_lib.FakeTime(500): cron_manager.RunOnce(token=self.token) cron_job1 = cron_manager.ReadJob(cron_job_id1, token=self.token) cron_job2 = cron_manager.ReadJob(cron_job_id2, token=self.token) # Start time should be the same self.assertEqual( cron_job1.Get(cron_job1.Schema.CRON_ARGS).start_time, start_time1) # Now both should be running self.assertTrue(cron_job1.IsRunning()) self.assertTrue(cron_job2.IsRunning()) # Check setting a bad flow urn is handled and removed with aff4.FACTORY.OpenWithLock( cron_job2.urn, aff4_type=aff4_cronjobs.CronJob, token=self.token) as cron_job2: cron_job2.Set(cron_job2.Schema.CURRENT_FLOW_URN("aff4:/does/not/exist")) self.assertFalse(cron_job2.IsRunning()) cron_job2 = cron_manager.ReadJob(cron_job_id2, token=self.token) self.assertFalse(cron_job2.Get(cron_job2.Schema.CURRENT_FLOW_URN))
def Handle(self, args, token=None): args.flow_args.hunt_runner_args.hunt_name = "GenericHunt" # TODO(user): The following should be asserted in a more elegant way. # Also, it's not clear whether cron job scheduling UI is used often enough # to justify its existence. We should check with opensource users whether # they find this feature useful and if not, deprecate it altogether. if args.flow_name != standard.CreateAndRunGenericHuntFlow.__name__: raise ValueError( "Only CreateAndRunGenericHuntFlow flows are supported " "here (got: %s)." % args.flow_name) # Clear all fields marked with HIDDEN, except for output_plugins - they are # marked HIDDEN, because we have a separate UI for them, not because they # shouldn't be shown to the user at all. # # TODO(user): Refactor the code to remove the HIDDEN label from # FlowRunnerArgs.output_plugins. args.flow_runner_args.ClearFieldsWithLabel( rdf_structs.SemanticDescriptor.Labels.HIDDEN, exceptions="output_plugins") if not args.flow_runner_args.flow_name: args.flow_runner_args.flow_name = args.flow_name cron_args = rdf_cronjobs.CreateCronJobFlowArgs( description=args.description, periodicity=args.periodicity, flow_runner_args=args.flow_runner_args, flow_args=args.flow_args, allow_overruns=args.allow_overruns, lifetime=args.lifetime) name = aff4_cronjobs.GetCronManager().CreateJob(cron_args=cron_args, disabled=True, token=token) fd = aff4_cronjobs.GetCronManager().ReadJob(name) return ApiCronJob().InitFromObject(fd)
def Handle(self, args, token=None): if not args.count: stop = None else: stop = args.offset + args.count cron_manager = aff4_cronjobs.GetCronManager() all_jobs = list(cron_manager.ReadJobs(token=token)) all_jobs.sort(key=lambda job: getattr(job, "job_id", None) or job.urn) cron_jobs = all_jobs[args.offset:stop] items = [ApiCronJob().InitFromObject(cron_job) for cron_job in cron_jobs] return ApiListCronJobsResult(items=items, total_count=len(all_jobs))
def testForceRunCronJob(self): cronjobs.GetCronManager().EnableJob(job_id="OSBreakDown") with test_lib.FakeTime( # 2274264646 corresponds to Sat, 25 Jan 2042 12:10:46 GMT. rdfvalue.RDFDatetime.FromSecondsSinceEpoch(2274264646), increment=1e-6): self.Open("/") self.Click("css=a[grrtarget=crons]") self.Click("css=td:contains('OSBreakDown')") # Click on Force Run button and check that dialog appears. self.Click("css=button[name=ForceRunCronJob]:not([disabled])") self.WaitUntil( self.IsTextPresent, "Are you sure you want to FORCE-RUN this cron job?") # Click on "Proceed" and wait for authorization dialog to appear. self.Click("css=button[name=Proceed]") self.WaitUntil(self.IsTextPresent, "Create a new approval") self.Click("css=grr-request-approval-dialog button[name=Cancel]") # Wait for dialog to disappear. self.WaitUntilNot(self.IsVisible, "css=.modal-open") self.RequestAndGrantCronJobApproval("OSBreakDown") # Click on Force Run button and check that dialog appears. self.Click("css=button[name=ForceRunCronJob]:not([disabled])") self.WaitUntil( self.IsTextPresent, "Are you sure you want to FORCE-RUN this cron job?") # Click on "Proceed" and wait for success label to appear. # Also check that "Proceed" button gets disabled. self.Click("css=button[name=Proceed]") self.WaitUntil(self.IsTextPresent, "Cron job flow was FORCE-STARTED successfully!") self.assertFalse(self.IsElementPresent("css=button[name=Proceed]")) # Click on "Close" and check that dialog disappears. self.Click("css=button[name=Close]") self.WaitUntilNot(self.IsVisible, "css=.modal-open") # View should be refreshed automatically. The last run date should appear. self.WaitUntil( self.IsElementPresent, "css=grr-cron-jobs-list " "tr:contains('OSBreakDown') td:contains('2042')")