Skip to content

Commit 5b759e1

Browse files
committed
feat: add support for Bitwarden Secret Manager EU vaults
1 parent 2bbd3b1 commit 5b759e1

File tree

11 files changed

+49
-26
lines changed

11 files changed

+49
-26
lines changed

lib/kamal/cli/secrets.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ class Kamal::Cli::Secrets < Kamal::Cli::Base
44
option :account, type: :string, required: false, desc: "The account identifier or username"
55
option :from, type: :string, required: false, desc: "A vault or folder to fetch the secrets from"
66
option :inline, type: :boolean, required: false, hidden: true
7+
option :server_url, type: :string, aliases: "-u", required: false, desc: "Override the default server-url"
78
def fetch(*secrets)
89
adapter = initialize_adapter(options[:adapter])
910

1011
if adapter.requires_account? && options[:account].blank?
1112
return puts "No value provided for required options '--account'"
1213
end
1314

14-
results = adapter.fetch(secrets, **options.slice(:account, :from).symbolize_keys)
15+
results = adapter.fetch(secrets, **options.slice(:account, :from, :server_url).symbolize_keys)
1516

1617
return_or_puts JSON.dump(results).shellescape, inline: options[:inline]
1718
end

lib/kamal/secrets/adapters/aws_secrets_manager.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ def requires_account?
44
end
55

66
private
7-
def login(_account)
7+
def login(_account, **)
88
nil
99
end
1010

11-
def fetch_secrets(secrets, from:, account: nil, session:)
11+
def fetch_secrets(secrets, from:, account: nil, **)
1212
{}.tap do |results|
1313
get_from_secrets_manager(prefixed_secrets(secrets, from: from), account: account).each do |secret|
1414
secret_name = secret["Name"]

lib/kamal/secrets/adapters/base.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
class Kamal::Secrets::Adapters::Base
22
delegate :optionize, to: Kamal::Utils
33

4-
def fetch(secrets, account: nil, from: nil)
4+
def fetch(secrets, account: nil, from: nil, server_url: nil)
55
raise RuntimeError, "Missing required option '--account'" if requires_account? && account.blank?
66

77
check_dependencies!
88

9-
session = login(account)
10-
fetch_secrets(secrets, from: from, account: account, session: session)
9+
session = login(account, server_url: server_url)
10+
fetch_secrets(secrets, from: from, account: account, session: session, server_url: server_url)
1111
end
1212

1313
def requires_account?

lib/kamal/secrets/adapters/bitwarden.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class Kamal::Secrets::Adapters::Bitwarden < Kamal::Secrets::Adapters::Base
22
private
3-
def login(account)
3+
def login(account, **)
44
status = run_command("status")
55

66
if status["status"] == "unauthenticated"
@@ -21,7 +21,7 @@ def login(account)
2121
session
2222
end
2323

24-
def fetch_secrets(secrets, from:, account:, session:)
24+
def fetch_secrets(secrets, from:, session:, **)
2525
{}.tap do |results|
2626
items_fields(prefixed_secrets(secrets, from: from)).each do |item, fields|
2727
item_json = run_command("get item #{item.shellescape}", session: session, raw: true)

lib/kamal/secrets/adapters/bitwarden_secrets_manager.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def requires_account?
99
LIST_COMMAND = "secret list"
1010
GET_COMMAND = "secret get"
1111

12-
def fetch_secrets(secrets, from:, account:, session:)
12+
def fetch_secrets(secrets, from:, server_url:, **)
1313
raise RuntimeError, "You must specify what to retrieve from Bitwarden Secrets Manager" if secrets.length == 0
1414

1515
secrets = prefixed_secrets(secrets, from: from)
@@ -18,13 +18,13 @@ def fetch_secrets(secrets, from:, account:, session:)
1818
{}.tap do |results|
1919
if command.nil?
2020
secrets.each do |secret_uuid|
21-
item_json = run_command("#{GET_COMMAND} #{secret_uuid.shellescape}")
21+
item_json = run_command("#{GET_COMMAND} #{secret_uuid.shellescape}", server_url: server_url)
2222
raise RuntimeError, "Could not read #{secret_uuid} from Bitwarden Secrets Manager" unless $?.success?
2323
item_json = JSON.parse(item_json)
2424
results[item_json["key"]] = item_json["value"]
2525
end
2626
else
27-
items_json = run_command(command)
27+
items_json = run_command(command, server_url: server_url)
2828
raise RuntimeError, "Could not read secrets from Bitwarden Secrets Manager" unless $?.success?
2929

3030
JSON.parse(items_json).each do |item_json|
@@ -45,13 +45,14 @@ def extract_command_and_project(secrets)
4545
end
4646
end
4747

48-
def run_command(command, session: nil)
49-
full_command = [ "bws", command ].join(" ")
50-
`#{full_command}`
48+
def run_command(command, server_url: nil)
49+
full_command = [ "bws", command ]
50+
full_command << "--server-url=#{server_url}" if server_url
51+
`#{full_command.join(" ")}`
5152
end
5253

53-
def login(account)
54-
run_command("project list")
54+
def login(_account, server_url: nil)
55+
run_command("project list", server_url: server_url)
5556
raise RuntimeError, "Could not authenticate to Bitwarden Secrets Manager. Did you set a valid access token?" unless $?.success?
5657
end
5758

lib/kamal/secrets/adapters/enpass.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def requires_account?
1414
end
1515

1616
private
17-
def fetch_secrets(secrets, from:, account:, session:)
17+
def fetch_secrets(secrets, from:, **)
1818
secrets_titles = fetch_secret_titles(secrets)
1919

2020
result = `enpass-cli -json -vault #{from.shellescape} show #{secrets_titles.map(&:shellescape).join(" ")}`.strip
@@ -31,7 +31,7 @@ def cli_installed?
3131
$?.success?
3232
end
3333

34-
def login(account)
34+
def login(_account, **)
3535
nil
3636
end
3737

lib/kamal/secrets/adapters/gcp_secret_manager.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class Kamal::Secrets::Adapters::GcpSecretManager < Kamal::Secrets::Adapters::Base
22
private
3-
def login(account)
3+
def login(_account, **)
44
# Since only the account option is passed from the cli, we'll use it for both account and service account
55
# impersonation.
66
#
@@ -26,7 +26,7 @@ def login(account)
2626
nil
2727
end
2828

29-
def fetch_secrets(secrets, from:, account:, session:)
29+
def fetch_secrets(secrets, from:, account:, **)
3030
user, service_account = parse_account(account)
3131

3232
{}.tap do |results|

lib/kamal/secrets/adapters/last_pass.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class Kamal::Secrets::Adapters::LastPass < Kamal::Secrets::Adapters::Base
22
private
3-
def login(account)
3+
def login(account, **)
44
unless loggedin?(account)
55
`lpass login #{account.shellescape}`
66
raise RuntimeError, "Failed to login to LastPass" unless $?.success?
@@ -11,7 +11,7 @@ def loggedin?(account)
1111
`lpass status --color never`.strip == "Logged in as #{account}."
1212
end
1313

14-
def fetch_secrets(secrets, from:, account:, session:)
14+
def fetch_secrets(secrets, from:, **)
1515
secrets = prefixed_secrets(secrets, from: from)
1616
items = `lpass show #{secrets.map(&:shellescape).join(" ")} --json`
1717
raise RuntimeError, "Could not read #{secrets} from LastPass" unless $?.success?

lib/kamal/secrets/adapters/one_password.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class Kamal::Secrets::Adapters::OnePassword < Kamal::Secrets::Adapters::Base
22
delegate :optionize, to: Kamal::Utils
33

44
private
5-
def login(account)
5+
def login(account, **)
66
unless loggedin?(account)
77
`op signin #{to_options(account: account, force: true, raw: true)}`.tap do
88
raise RuntimeError, "Failed to login to 1Password" unless $?.success?
@@ -15,7 +15,7 @@ def loggedin?(account)
1515
$?.success?
1616
end
1717

18-
def fetch_secrets(secrets, from:, account:, session:)
18+
def fetch_secrets(secrets, from:, account:, session:, **)
1919
if secrets.blank?
2020
fetch_all_secrets(from: from, account: account, session: session)
2121
else

lib/kamal/secrets/adapters/test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
class Kamal::Secrets::Adapters::Test < Kamal::Secrets::Adapters::Base
22
private
3-
def login(account)
3+
def login(_account, **)
44
true
55
end
66

7-
def fetch_secrets(secrets, from:, account:, session:)
7+
def fetch_secrets(secrets, from:, **)
88
prefixed_secrets(secrets, from: from).to_h { |secret| [ secret, secret.reverse ] }
99
end
1010

0 commit comments

Comments
 (0)