Files
kamal/test/utils_test.rb
Donal McBreen 989d09e027 Copy env files to remote hosts
Setting env variables in the docker arguments requires having them on
the deploy host.

Instead we'll add two new commands `kamal env push` and
`kamal env delete` which will manage copying the environment as .env
files to the remote host.

Docker will pick up the file with `--env-file <path-to-file>`. Env files
will be stored under `<kamal run directory>/env`.

Running `kamal env push` will create env files for each role and
accessory, and traefik if required.

`kamal envify` has been updated to also push the env files.

By avoiding using `kamal envify` and creating the local and remote
secrets manually, you can now avoid accessing secrets needed
for the docker runtime environment locally. You will still need build
secrets.

One thing to note - the Docker doesn't parse the environment variables
in the env file, one result of this is that you can't specify multi-line
values - see https://github.com/moby/moby/issues/12997.

We maybe need to look docker config or docker secrets longer term to get
around this.

Hattip to @kevinmcconnell - this was all his idea.
2023-08-30 17:00:05 +01:00

127 lines
3.6 KiB
Ruby

require "test_helper"
class UtilsTest < ActiveSupport::TestCase
test "argumentize" do
assert_equal [ "--label", "foo=\"\\`bar\\`\"", "--label", "baz=\"qux\"", "--label", :quux ], \
Kamal::Utils.argumentize("--label", { foo: "`bar`", baz: "qux", quux: nil })
end
test "argumentize with redacted" do
assert_kind_of SSHKit::Redaction, \
Kamal::Utils.argumentize("--label", { foo: "bar" }, sensitive: true).last
end
test "env file simple" do
env = {
"foo" => "bar",
"baz" => "haz"
}
assert_equal "foo=bar\nbaz=haz\n", \
Kamal::Utils.env_file_with_secrets(env)
end
test "env file clear" do
env = {
"clear" => {
"foo" => "bar",
"baz" => "haz"
}
}
assert_equal "foo=bar\nbaz=haz\n", \
Kamal::Utils.env_file_with_secrets(env)
end
test "env file secret" do
ENV["PASSWORD"] = "hello"
env = {
"secret" => [ "PASSWORD" ]
}
assert_equal "PASSWORD=hello\n", \
Kamal::Utils.env_file_with_secrets(env)
ensure
ENV.delete "PASSWORD"
end
test "env file missing secret" do
env = {
"secret" => [ "PASSWORD" ]
}
assert_raises(KeyError) { Kamal::Utils.env_file_with_secrets(env) }
ensure
ENV.delete "PASSWORD"
end
test "env file secret and clear" do
ENV["PASSWORD"] = "hello"
env = {
"secret" => [ "PASSWORD" ],
"clear" => {
"foo" => "bar",
"baz" => "haz"
}
}
assert_equal "PASSWORD=hello\nfoo=bar\nbaz=haz\n", \
Kamal::Utils.env_file_with_secrets(env)
ensure
ENV.delete "PASSWORD"
end
test "optionize" do
assert_equal [ "--foo", "\"bar\"", "--baz", "\"qux\"", "--quux" ], \
Kamal::Utils.optionize({ foo: "bar", baz: "qux", quux: true })
end
test "optionize with" do
assert_equal [ "--foo=\"bar\"", "--baz=\"qux\"", "--quux" ], \
Kamal::Utils.optionize({ foo: "bar", baz: "qux", quux: true }, with: "=")
end
test "no redaction from #to_s" do
assert_equal "secret", Kamal::Utils.sensitive("secret").to_s
end
test "redact from #inspect" do
assert_equal "[REDACTED]".inspect, Kamal::Utils.sensitive("secret").inspect
end
test "redact from SSHKit output" do
assert_kind_of SSHKit::Redaction, Kamal::Utils.sensitive("secret")
end
test "redact from YAML output" do
assert_equal "--- ! '[REDACTED]'\n", YAML.dump(Kamal::Utils.sensitive("secret"))
end
test "escape_shell_value" do
assert_equal "\"foo\"", Kamal::Utils.escape_shell_value("foo")
assert_equal "\"\\`foo\\`\"", Kamal::Utils.escape_shell_value("`foo`")
assert_equal "\"${PWD}\"", Kamal::Utils.escape_shell_value("${PWD}")
assert_equal "\"${cat /etc/hostname}\"", Kamal::Utils.escape_shell_value("${cat /etc/hostname}")
assert_equal "\"\\${PWD]\"", Kamal::Utils.escape_shell_value("${PWD]")
assert_equal "\"\\$(PWD)\"", Kamal::Utils.escape_shell_value("$(PWD)")
assert_equal "\"\\$PWD\"", Kamal::Utils.escape_shell_value("$PWD")
assert_equal "\"^(https?://)www.example.com/(.*)\\$\"",
Kamal::Utils.escape_shell_value("^(https?://)www.example.com/(.*)$")
assert_equal "\"https://example.com/\\$2\"",
Kamal::Utils.escape_shell_value("https://example.com/$2")
end
test "uncommitted changes exist" do
Kamal::Utils.expects(:`).with("git status --porcelain").returns("M file\n")
assert_equal "M file", Kamal::Utils.uncommitted_changes
end
test "uncommitted changes do not exist" do
Kamal::Utils.expects(:`).with("git status --porcelain").returns("")
assert_equal "", Kamal::Utils.uncommitted_changes
end
end