Audit details (#1)

Audit details

* Audit logs and broadcasts accept `details` whose values are included as log tags and MRSK_* env vars passed to the broadcast command
* Commands may return execution options to the CLI in their args list
* Introduce `mrsk broadcast` helper for sending audit broadcasts
* Report UTC time, not local time, in audit logs. Standardize on ISO 8601 format
This commit is contained in:
Jeremy Daer
2023-05-02 11:42:05 -07:00
committed by GitHub
parent 88a7413b3e
commit 048aecf352
11 changed files with 143 additions and 90 deletions

View File

@@ -321,6 +321,19 @@ class CliMainTest < CliTestCase
end
end
test "broadcast" do
SSHKit::Backend::Abstract.any_instance.expects(:execute).with do |command, line, options, verbosity:|
command == "bin/audit_broadcast" &&
line =~ /\A'\[[^\]]+\] message'\z/ &&
options[:env].keys == %w[ MRSK_RECORDED_AT MRSK_PERFORMER MRSK_EVENT ] &&
verbosity == :debug
end.returns("Broadcast audit message: message")
run_command("broadcast", "-m", "message").tap do |output|
assert_match "Broadcast: message", output
end
end
test "version" do
version = stdouted { Mrsk::Cli::Main.new.version }
assert_equal Mrsk::VERSION, version

View File

@@ -6,55 +6,65 @@ class CommandsAuditorTest < ActiveSupport::TestCase
service: "app", image: "dhh/app", registry: { "username" => "dhh", "password" => "secret" }, servers: [ "1.1.1.1" ],
audit_broadcast_cmd: "bin/audit_broadcast"
}
@auditor = new_command
end
test "record" do
assert_match \
/echo '.* app removed container' >> mrsk-app-audit.log/,
new_command.record("app removed container").join(" ")
assert_equal [
:echo,
"[#{@auditor.details[:recorded_at]}]", "[#{@auditor.details[:performer]}]",
"app removed container",
">>", "mrsk-app-audit.log"
], @auditor.record("app removed container")
end
test "record with destination" do
@destination = "staging"
assert_match \
/echo '.* app removed container' >> mrsk-app-staging-audit.log/,
new_command.record("app removed container").join(" ")
new_command(destination: "staging").tap do |auditor|
assert_equal [
:echo,
"[#{auditor.details[:recorded_at]}]", "[#{auditor.details[:performer]}]", "[#{auditor.details[:destination]}]",
"app removed container",
">>", "mrsk-app-staging-audit.log"
], auditor.record("app removed container")
end
end
test "record with role" do
@role = "web"
test "record with command details" do
new_command(role: "web").tap do |auditor|
assert_equal [
:echo,
"[#{auditor.details[:recorded_at]}]", "[#{auditor.details[:performer]}]", "[#{auditor.details[:role]}]",
"app removed container",
">>", "mrsk-app-audit.log"
], auditor.record("app removed container")
end
end
assert_match \
/echo '.* \[web\] app removed container' >> mrsk-app-audit.log/,
new_command.record("app removed container").join(" ")
test "record with arg details" do
assert_equal [
:echo,
"[#{@auditor.details[:recorded_at]}]", "[#{@auditor.details[:performer]}]", "[value]",
"app removed container",
">>", "mrsk-app-audit.log"
], @auditor.record("app removed container", detail: "value")
end
test "broadcast" do
Mrsk::Commands::Auditor.any_instance.stubs(:performer).returns("bob")
@role = "web"
@destination = "staging"
assert_equal \
["bin/audit_broadcast", "'[bob] [web] [staging] app removed container'"],
new_command.broadcast("app removed container")
end
test "broadcast environment" do
Mrsk::Commands::Auditor.any_instance.stubs(:performer).returns("bob")
@role = "web"
@destination = "staging"
env = new_command.broadcast_environment("app removed container")
assert_equal "bob", env["MRSK_PERFORMER"]
assert_equal "web", env["MRSK_ROLE"]
assert_equal "staging", env["MRSK_DESTINATION"]
assert_equal "app removed container", env["MRSK_MESSAGE"]
assert_equal [
"bin/audit_broadcast",
"'[#{@auditor.details[:performer]}] [value] app removed container'",
env: {
"MRSK_RECORDED_AT" => @auditor.details[:recorded_at],
"MRSK_PERFORMER" => @auditor.details[:performer],
"MRSK_EVENT" => "app removed container",
"MRSK_DETAIL" => "value"
}
], @auditor.broadcast("app removed container", detail: "value")
end
private
def new_command
Mrsk::Commands::Auditor.new(Mrsk::Configuration.new(@config, destination: @destination, version: "123"), role: @role)
def new_command(destination: nil, **details)
Mrsk::Commands::Auditor.new(Mrsk::Configuration.new(@config, destination: destination, version: "123"), **details)
end
end

View File

@@ -6,3 +6,4 @@ servers:
registry:
username: user
password: pw
audit_broadcast_cmd: "bin/audit_broadcast"