def testRuleExpiration(self): with test_lib.FakeTime(1000): foreman_obj = foreman.GetForeman() rules = [] rules.append( foreman_rules.ForemanCondition( creation_time=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(1000), expiration_time=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(1500), description="Test rule1", hunt_id="H:111111")) rules.append( foreman_rules.ForemanCondition( creation_time=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(1000), expiration_time=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(1200), description="Test rule2", hunt_id="H:222222")) rules.append( foreman_rules.ForemanCondition( creation_time=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(1000), expiration_time=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(1500), description="Test rule3", hunt_id="H:333333")) rules.append( foreman_rules.ForemanCondition( creation_time=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(1000), expiration_time=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(1300), description="Test rule4", hunt_id="H:444444")) client_id = self.SetupTestClientObject(0x21).client_id # Clear the rule set and add the new rules to it. for rule in rules: # Add some regex that does not match the client. rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.REGEX, regex=foreman_rules.ForemanRegexClientRule( field="SYSTEM", attribute_regex="XXX")) ]) data_store.REL_DB.WriteForemanRule(rule) for now, num_rules in [(1000, 4), (1250, 3), (1350, 2), (1600, 0)]: with test_lib.FakeTime(now): data_store.REL_DB.WriteClientMetadata( client_id, last_foreman=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(100)) foreman_obj.AssignTasksToClient(client_id) rules = data_store.REL_DB.ReadAllForemanRules() self.assertLen(rules, num_rules)
def testAssigningTasksToClientDoesNotEraseFleetspeakValidationInfo(self): client_id = self.SetupClient(0) data_store.REL_DB.WriteClientMetadata(client_id, fleetspeak_validation_info={ "foo": "bar", "12": "34" }) # Setup the rules so that AssignTasksToClient have to apply them # and update the foreman check timestamp (otherwise it will exit # doing nothing). now = rdfvalue.RDFDatetime.Now() expiration_time = now + rdfvalue.Duration.From(1, rdfvalue.HOURS) # Make a new rule rule = foreman_rules.ForemanCondition(creation_time=now, expiration_time=expiration_time, description="Test rule", hunt_id="11111111") data_store.REL_DB.WriteForemanRule(rule) foreman_obj = foreman.Foreman() foreman_obj.AssignTasksToClient(client_id) client_metadata = data_store.REL_DB.ReadClientMetadata(client_id) self.assertTrue( client_metadata.HasField("last_fleetspeak_validation_info"))
def _ScheduleGenericHunt(hunt_obj): """Adds foreman rules for a generic hunt.""" foreman_condition = foreman_rules.ForemanCondition( creation_time=rdfvalue.RDFDatetime.Now(), expiration_time=hunt_obj.expiry_time, description="Hunt %s %s" % (hunt_obj.hunt_id, hunt_obj.args.hunt_type), client_rule_set=hunt_obj.client_rule_set, hunt_id=hunt_obj.hunt_id) # Make sure the rule makes sense. foreman_condition.Validate() data_store.REL_DB.WriteForemanRule(foreman_condition)
def _ScheduleGenericHunt(hunt_obj): """Adds foreman rules for a generic hunt.""" # TODO: Migrate foreman conditions to use relation expiration # durations instead of absolute timestamps. foreman_condition = foreman_rules.ForemanCondition( creation_time=rdfvalue.RDFDatetime.Now(), expiration_time=hunt_obj.init_start_time + hunt_obj.duration, description="Hunt %s %s" % (hunt_obj.hunt_id, hunt_obj.args.hunt_type), client_rule_set=hunt_obj.client_rule_set, hunt_id=hunt_obj.hunt_id) # Make sure the rule makes sense. foreman_condition.Validate() data_store.REL_DB.WriteForemanRule(foreman_condition)
def testOperatingSystemSelection(self): """Tests that we can distinguish based on operating system.""" self.SetupTestClientObject(1, system="Windows XP") self.SetupTestClientObject(2, system="Linux") self.SetupTestClientObject(3, system="Windows 7") with utils.Stubber(implementation.GRRHunt, "StartClients", self.StartClients): # Now setup the filters now = rdfvalue.RDFDatetime.Now() expiration_time = now + rdfvalue.Duration("1h") # Make a new rule rule = foreman_rules.ForemanCondition( creation_time=now, expiration_time=expiration_time, description="Test rule", hunt_name=standard.GenericHunt.__name__, hunt_id="H:111111") # Matches Windows boxes rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.OS, os=foreman_rules.ForemanOsClientRule(os_windows=True)) ]) data_store.REL_DB.WriteForemanRule(rule) self.clients_started = [] foreman_obj = foreman.GetForeman() foreman_obj.AssignTasksToClient(u"C.1000000000000001") foreman_obj.AssignTasksToClient(u"C.1000000000000002") foreman_obj.AssignTasksToClient(u"C.1000000000000003") # Make sure that only the windows machines ran self.assertEqual(len(self.clients_started), 2) self.assertEqual(self.clients_started[0][1], u"C.1000000000000001") self.assertEqual(self.clients_started[1][1], u"C.1000000000000003") self.clients_started = [] # Run again - This should not fire since it did already foreman_obj.AssignTasksToClient(u"C.1000000000000001") foreman_obj.AssignTasksToClient(u"C.1000000000000002") foreman_obj.AssignTasksToClient(u"C.1000000000000003") self.assertEqual(len(self.clients_started), 0)
def _GetTestRule(self, hunt_id="H:123456", expires=None): now = rdfvalue.RDFDatetime.Now() expiration_time = expires or now + rdfvalue.Duration("2w") rule = foreman_rules.ForemanCondition(creation_time=now, expiration_time=expiration_time, description="Test rule", hunt_id=hunt_id) rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="INSTALL_TIME", operator=foreman_rules.ForemanIntegerClientRule.Operator. LESS_THAN, value=now)) ]) return rule
def StartHunt(hunt_id): """Starts a hunt with a given id.""" hunt_obj = data_store.REL_DB.ReadHuntObject(hunt_id) output_plugins_states = None if hunt_obj.output_plugins and not hunt_obj.output_plugins_states: output_plugins_states = flow.GetOutputPluginStates( hunt_obj.output_plugins, source="hunts/%s" % hunt_obj.hunt_id, token=access_control.ACLToken(username=hunt_obj.creator)) for ops in output_plugins_states: ops.plugin_state["success_count"] = 0 ops.plugin_state["error_count"] = 0 def UpdateFn(h): """Updates given hunt in a transaction.""" if h.hunt_state != h.HuntState.PAUSED: raise OnlyPausedHuntCanBeStartedError(h) if (output_plugins_states is not None and not hunt_obj.output_plugins_states): h.output_plugins_states = output_plugins_states h.hunt_state = h.HuntState.STARTED h.hunt_state_comment = None h.next_client_due = rdfvalue.RDFDatetime.Now() return h hunt_obj = data_store.REL_DB.UpdateHuntObject(hunt_id, UpdateFn) if hunt_obj.hunt_state != hunt_obj.HuntState.STARTED: return foreman_condition = foreman_rules.ForemanCondition( creation_time=rdfvalue.RDFDatetime.Now(), expiration_time=hunt_obj.expiry_time, description="Hunt %s %s" % (hunt_obj.hunt_id, hunt_obj.args.hunt_type), client_rule_set=hunt_obj.client_rule_set, hunt_id=hunt_obj.hunt_id) # Make sure the rule makes sense. foreman_condition.Validate() data_store.REL_DB.WriteForemanRule(foreman_condition) return hunt_obj
def testIntegerComparisons(self): """Tests that we can use integer matching rules on the foreman.""" base_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch( 1336480583.077736) boot_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch( 1336300000.000000) self.SetupClient(0x11, system="Windows XP", install_time=base_time) self.SetupClient(0x12, system="Windows 7", install_time=base_time) # This one was installed one week earlier. one_week_ago = base_time - rdfvalue.DurationSeconds("1w") self.SetupClient(0x13, system="Windows 7", install_time=one_week_ago) self.SetupClient(0x14, system="Windows 7", last_boot_time=boot_time) with utils.Stubber(hunt, "StartHuntFlowOnClient", self.StartHuntFlowOnClient): now = rdfvalue.RDFDatetime.Now() expiration_time = now + rdfvalue.DurationSeconds("1h") # Make a new rule rule = foreman_rules.ForemanCondition( creation_time=now, expiration_time=expiration_time, description="Test rule(old)", hunt_id="111111") # Matches the old client one_hour_ago = base_time - rdfvalue.DurationSeconds("1h") rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="INSTALL_TIME", operator=foreman_rules.ForemanIntegerClientRule. Operator.LESS_THAN, value=one_hour_ago.AsSecondsSinceEpoch())) ]) data_store.REL_DB.WriteForemanRule(rule) # Make a new rule rule = foreman_rules.ForemanCondition( creation_time=now, expiration_time=expiration_time, description="Test rule(new)", hunt_id="222222") # Matches the newer clients rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="INSTALL_TIME", operator=foreman_rules.ForemanIntegerClientRule. Operator.GREATER_THAN, value=one_hour_ago.AsSecondsSinceEpoch())) ]) data_store.REL_DB.WriteForemanRule(rule) # Make a new rule rule = foreman_rules.ForemanCondition( creation_time=now, expiration_time=expiration_time, description="Test rule(eq)", hunt_id="333333") # Note that this also tests the handling of nonexistent attributes. rule.client_rule_set = foreman_rules.ForemanClientRuleSet(rules=[ foreman_rules.ForemanClientRule( rule_type=foreman_rules.ForemanClientRule.Type.INTEGER, integer=foreman_rules.ForemanIntegerClientRule( field="LAST_BOOT_TIME", operator="EQUAL", value=boot_time.AsSecondsSinceEpoch())) ]) data_store.REL_DB.WriteForemanRule(rule) foreman_obj = foreman.Foreman() self.clients_started = [] foreman_obj.AssignTasksToClient(u"C.1000000000000011") foreman_obj.AssignTasksToClient(u"C.1000000000000012") foreman_obj.AssignTasksToClient(u"C.1000000000000013") foreman_obj.AssignTasksToClient(u"C.1000000000000014") # Make sure that the clients ran the correct flows. self.assertLen(self.clients_started, 4) self.assertEqual(self.clients_started[0][1], u"C.1000000000000011") self.assertEqual("222222", self.clients_started[0][0]) self.assertEqual(self.clients_started[1][1], u"C.1000000000000012") self.assertEqual("222222", self.clients_started[1][0]) self.assertEqual(self.clients_started[2][1], u"C.1000000000000013") self.assertEqual("111111", self.clients_started[2][0]) self.assertEqual(self.clients_started[3][1], u"C.1000000000000014") self.assertEqual("333333", self.clients_started[3][0])