def test_skip_hooks_in_create(self): """Run a test of create, with a hook that should forbid running create, but with a user who's covered by one of the hook skip exception rules - so it should succeed. """ GlobalCommandHookRegistry.reset() command_hook = HookForTesting(True) GlobalCommandHookRegistry.register_command_hook(command_hook) command_hook_two = SecondHookForTesting(False) GlobalCommandHookRegistry.register_command_hook(command_hook_two) mock_response = Mock() mock_context = FakeAuroraCommandContext() with contextlib.nested( patch("apache.aurora.client.cli.jobs.Job.create_context", return_value=mock_context), patch("requests.get", return_value=mock_response), patch("getpass.getuser", return_value="bozo")): mock_response.json.return_value = { "a": { "users": ["bozo", "clown"], "commands": { "job": ["killall", "create"] }, "hooks": ["test_hook", "second"] }, "b": { "commands": { "user": ["kick"] }, } } mock_query = self.create_mock_query() mock_context.add_expected_status_query_result( self.create_mock_status_query_result(ScheduleStatus.INIT)) mock_context.add_expected_status_query_result( self.create_mock_status_query_result(ScheduleStatus.RUNNING)) api = mock_context.get_api("west") api.create_job.return_value = self.get_createjob_response() GlobalCommandHookRegistry.setup("http://foo.bar") with temporary_file() as fp: fp.write(self.get_valid_config()) fp.flush() cmd = AuroraCommandLine() result = cmd.execute([ "job", "create", "--skip-hooks=second", "--wait-until=RUNNING", "west/bozo/test/hello", fp.name ]) assert result == 0 self.assert_create_job_called(api) self.assert_scheduler_called(api, mock_query, 1) assert command_hook.ran_pre assert command_hook.ran_post
def test_skip_hooks_in_create(self): """Run a test of create, with a hook that should forbid running create, but with a user who's covered by one of the hook skip exception rules - so it should succeed. """ GlobalCommandHookRegistry.reset() command_hook = HookForTesting(True) GlobalCommandHookRegistry.register_command_hook(command_hook) command_hook_two = SecondHookForTesting(False) GlobalCommandHookRegistry.register_command_hook(command_hook_two) mock_response = Mock() mock_context = FakeAuroraCommandContext() with contextlib.nested( patch("apache.aurora.client.cli.jobs.Job.create_context", return_value=mock_context), patch("requests.get", return_value=mock_response), patch("getpass.getuser", return_value="bozo")): mock_response.json.return_value = { "a": { "users": ["bozo", "clown"], "commands": {"job": ["killall", "create"]}, "hooks": ["test_hook", "second"] }, "b": { "commands": {"user": ["kick"]}, } } mock_query = self.create_mock_query() mock_context.add_expected_status_query_result( self.create_mock_status_query_result(ScheduleStatus.INIT)) mock_context.add_expected_status_query_result( self.create_mock_status_query_result(ScheduleStatus.RUNNING)) mock_context.get_api("west").check_status.side_effect = ( lambda x: self.create_mock_status_query_result(ScheduleStatus.RUNNING)) api = mock_context.get_api("west") api.create_job.return_value = self.get_createjob_response() GlobalCommandHookRegistry.setup("http://foo.bar") with temporary_file() as fp: fp.write(self.get_valid_config()) fp.flush() cmd = AuroraCommandLine() result = cmd.execute(["job", "create", "--skip-hooks=second", "--wait-until=RUNNING", "west/bozo/test/hello", fp.name]) assert result == 0 self.assert_create_job_called(api) self.assert_scheduler_called(api, mock_query, 1) assert command_hook.ran_pre assert command_hook.ran_post
def test_cannot_skip_hooks_in_create(self): """This time, the hook shouldn't be skippable, because we use a username who isn't allowed by the hook exception rule. """ GlobalCommandHookRegistry.reset() command_hook = HookForTesting(True) GlobalCommandHookRegistry.register_command_hook(command_hook) command_hook_two = SecondHookForTesting(False) GlobalCommandHookRegistry.register_command_hook(command_hook_two) mock_response = Mock() mock_context = FakeAuroraCommandContext() with contextlib.nested( patch("apache.aurora.client.cli.jobs.Job.create_context", return_value=mock_context), patch("requests.get", return_value=mock_response), patch("getpass.getuser", return_value="beezus")): mock_response.json.return_value = { "a": { "users": ["bozo", "clown"], "commands": { "job": ["killall", "create"] }, "hooks": ["test_hook", "second"] }, "b": { "commands": { "user": ["kick"] }, } } mock_context.add_expected_status_query_result( self.create_mock_status_query_result(ScheduleStatus.INIT)) mock_context.add_expected_status_query_result( self.create_mock_status_query_result(ScheduleStatus.RUNNING)) api = mock_context.get_api("west") api.create_job.return_value = self.get_createjob_response() GlobalCommandHookRegistry.setup("http://foo.bar") with temporary_file() as fp: fp.write(self.get_valid_config()) fp.flush() cmd = AuroraCommandLine() result = cmd.execute([ "job", "create", "--skip-hooks=second", "--wait-until=RUNNING", "west/bozo/test/hello", fp.name ]) # Check that it returns the right error code, and that create_job didn't get called. assert result == EXIT_PERMISSION_VIOLATION assert api.create_job.call_count == 0
def test_json_skip_rules(self): """Load up a set of skips, specified in JSON, and then check a bunch of different cases to see that the skip rules work correctly. """ mock_response = Mock() mock_context = FakeAuroraCommandContext() with patch("requests.get", return_value=mock_response): mock_response.json.return_value = { "a": { "users": ["bozo", "clown"], "commands": { "job": ["killall"] }, "hooks": ["test_hook", "second"] }, "b": { "commands": { "user": ["kick"] }, } } GlobalCommandHookRegistry.reset() GlobalCommandHookRegistry.setup("http://foo.bar") command_hook_one = HookForTesting(False) GlobalCommandHookRegistry.register_command_hook(command_hook_one) command_hook_two = SecondHookForTesting(True) GlobalCommandHookRegistry.register_command_hook(command_hook_two) assert len(GlobalCommandHookRegistry.SKIP_HOOK_RULES) == 2 # Should not be allowed: no skip rule permitting skipping hooks on job kill self.assert_skip_forbidden(mock_context, "all", "beezus", "job", "kill", ["a", "b", "c"]) # Should not be allowed: there are hooks on "job killall", and beezus doesn't satisfy # their exception rules self.assert_skip_forbidden(mock_context, "all", "beezus", "job", "kill", ["a", "b", "c"]) # Should be allowed: there's a rule allowing bozo to skip test_hook on job killall. self.assert_skip_allowed(mock_context, "test_hook", "bozo", "job", "killall", ["a", "b", "c"]) # Should be allowed: since there's only one hook on killall, this is equivalent to # the previous. self.assert_skip_allowed(mock_context, "all", "bozo", "job", "killall", ["a", "b", "c"]) # Should be allowed: there's a rule allowing anyone to skip any hook on "user kick". self.assert_skip_allowed(mock_context, "test_hook,something_else", "nobody", "user", "kick", ["a", "b", "c"]) # should be allowed: there are no hooks in place for "user kick", so all is acceptable. self.assert_skip_allowed(mock_context, "all", "nobody", "user", "kick", ["a", "b", "c"])
def test_cannot_skip_hooks_in_create(self): """This time, the hook shouldn't be skippable, because we use a username who isn't allowed by the hook exception rule. """ GlobalCommandHookRegistry.reset() command_hook = HookForTesting(True) GlobalCommandHookRegistry.register_command_hook(command_hook) command_hook_two = SecondHookForTesting(False) GlobalCommandHookRegistry.register_command_hook(command_hook_two) mock_response = Mock() mock_context = FakeAuroraCommandContext() with contextlib.nested( patch("apache.aurora.client.cli.jobs.Job.create_context", return_value=mock_context), patch("requests.get", return_value=mock_response), patch("getpass.getuser", return_value="beezus")): mock_response.json.return_value = { "a": { "users": ["bozo", "clown"], "commands": {"job": ["killall", "create"]}, "hooks": ["test_hook", "second"] }, "b": { "commands": {"user": ["kick"]}, } } mock_context.add_expected_status_query_result( self.create_mock_status_query_result(ScheduleStatus.INIT)) mock_context.add_expected_status_query_result( self.create_mock_status_query_result(ScheduleStatus.RUNNING)) api = mock_context.get_api("west") api.create_job.return_value = self.get_createjob_response() GlobalCommandHookRegistry.setup("http://foo.bar") with temporary_file() as fp: fp.write(self.get_valid_config()) fp.flush() cmd = AuroraCommandLine() result = cmd.execute(["job", "create", "--skip-hooks=second", "--wait-until=RUNNING", "west/bozo/test/hello", fp.name]) # Check that it returns the right error code, and that create_job didn't get called. assert result == EXIT_PERMISSION_VIOLATION assert api.create_job.call_count == 0
def test_json_skip_rules(self): """Load up a set of skips, specified in JSON, and then check a bunch of different cases to see that the skip rules work correctly. """ mock_response = Mock() mock_context = FakeAuroraCommandContext() with patch("requests.get", return_value=mock_response): mock_response.json.return_value = { "a": { "users": ["bozo", "clown"], "commands": {"job": ["killall"]}, "hooks": ["test_hook", "second"] }, "b": { "commands": {"user": ["kick"]}, } } GlobalCommandHookRegistry.reset() GlobalCommandHookRegistry.setup("http://foo.bar") command_hook_one = HookForTesting(False) GlobalCommandHookRegistry.register_command_hook(command_hook_one) command_hook_two = SecondHookForTesting(True) GlobalCommandHookRegistry.register_command_hook(command_hook_two) assert len(GlobalCommandHookRegistry.SKIP_HOOK_RULES) == 2 # Should not be allowed: no skip rule permitting skipping hooks on job kill self.assert_skip_forbidden(mock_context, "all", "beezus", "job", "kill", ["a", "b", "c"]) # Should not be allowed: there are hooks on "job killall", and beezus doesn't satisfy # their exception rules self.assert_skip_forbidden(mock_context, "all", "beezus", "job", "kill", ["a", "b", "c"]) # Should be allowed: there's a rule allowing bozo to skip test_hook on job killall. self.assert_skip_allowed(mock_context, "test_hook", "bozo", "job", "killall", ["a", "b", "c"]) # Should be allowed: since there's only one hook on killall, this is equivalent to # the previous. self.assert_skip_allowed(mock_context, "all", "bozo", "job", "killall", ["a", "b", "c"]) # Should be allowed: there's a rule allowing anyone to skip any hook on "user kick". self.assert_skip_allowed(mock_context, "test_hook,something_else", "nobody", "user", "kick", ["a", "b", "c"]) # should be allowed: there are no hooks in place for "user kick", so all is acceptable. self.assert_skip_allowed(mock_context, "all", "nobody", "user", "kick", ["a", "b", "c"])