nocoffee-kamal 2.3.0.1 → 2.3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/kamal/cli/accessory.rb +22 -7
- data/lib/kamal/cli/secrets.rb +9 -3
- data/lib/kamal/cli/templates/deploy.yml +5 -2
- data/lib/kamal/commands/accessory/proxy.rb +16 -0
- data/lib/kamal/commands/accessory.rb +5 -1
- data/lib/kamal/commands/app/containers.rb +2 -2
- data/lib/kamal/commands/app/images.rb +1 -1
- data/lib/kamal/commands/app.rb +15 -7
- data/lib/kamal/commands/builder/base.rb +6 -2
- data/lib/kamal/configuration/accessory.rb +17 -2
- data/lib/kamal/configuration/builder.rb +4 -0
- data/lib/kamal/configuration/docs/accessory.yml +4 -0
- data/lib/kamal/configuration/docs/builder.yml +6 -0
- data/lib/kamal/configuration/docs/proxy.yml +5 -0
- data/lib/kamal/configuration/proxy.rb +1 -0
- data/lib/kamal/configuration.rb +1 -1
- data/lib/kamal/secrets/adapters/aws_secrets_manager.rb +34 -0
- data/lib/kamal/secrets/adapters/base.rb +8 -1
- data/lib/kamal/secrets/adapters/doppler.rb +53 -0
- data/lib/kamal/secrets/adapters/test_optional_account.rb +5 -0
- data/lib/kamal/version.rb +1 -1
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 223e16fa86229aef57b0240731cc7f2941f224aa4552e605bd5d7182166084c2
|
4
|
+
data.tar.gz: bb2d69b0ffe59f22eaa1f7a22f0b368d5fbbef2a041bc17b96ac68aef28972fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbbd09944ed7dcdf4e4d0065e49800d04290b471ff6165bb9dacf3609e8ddbff6351309aebdccadf673690cc6b8fafcb8be75e2b88a29ea08823dd4cc7f0a86c
|
7
|
+
data.tar.gz: c3d96a182bb8e20becbfb9a8621a98d66f2415007278a568c3785b535b661f9aae549b7c5578130a23b086e54b989da2de7413860e8865c9e4cbd8050c3062a8
|
data/lib/kamal/cli/accessory.rb
CHANGED
@@ -18,6 +18,11 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
18
18
|
execute *accessory.ensure_env_directory
|
19
19
|
upload! accessory.secrets_io, accessory.secrets_path, mode: "0600"
|
20
20
|
execute *accessory.run
|
21
|
+
|
22
|
+
if accessory.running_proxy?
|
23
|
+
target = capture_with_info(*accessory.container_id_for(container_name: accessory.service_name, only_running: true)).strip
|
24
|
+
execute *accessory.deploy(target: target)
|
25
|
+
end
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
@@ -75,6 +80,10 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
75
80
|
on(hosts) do
|
76
81
|
execute *KAMAL.auditor.record("Started #{name} accessory"), verbosity: :debug
|
77
82
|
execute *accessory.start
|
83
|
+
if accessory.running_proxy?
|
84
|
+
target = capture_with_info(*accessory.container_id_for(container_name: accessory.service_name, only_running: true)).strip
|
85
|
+
execute *accessory.deploy(target: target)
|
86
|
+
end
|
78
87
|
end
|
79
88
|
end
|
80
89
|
end
|
@@ -87,6 +96,11 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
87
96
|
on(hosts) do
|
88
97
|
execute *KAMAL.auditor.record("Stopped #{name} accessory"), verbosity: :debug
|
89
98
|
execute *accessory.stop, raise_on_non_zero_exit: false
|
99
|
+
|
100
|
+
if accessory.running_proxy?
|
101
|
+
target = capture_with_info(*accessory.container_id_for(container_name: accessory.service_name, only_running: true)).strip
|
102
|
+
execute *accessory.remove if target
|
103
|
+
end
|
90
104
|
end
|
91
105
|
end
|
92
106
|
end
|
@@ -112,14 +126,15 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
112
126
|
end
|
113
127
|
end
|
114
128
|
|
115
|
-
desc "exec [NAME] [CMD]", "Execute a custom command on servers (use --help to show options)"
|
129
|
+
desc "exec [NAME] [CMD...]", "Execute a custom command on servers within the accessory container (use --help to show options)"
|
116
130
|
option :interactive, aliases: "-i", type: :boolean, default: false, desc: "Execute command over ssh for an interactive shell (use for console/bash)"
|
117
131
|
option :reuse, type: :boolean, default: false, desc: "Reuse currently running container instead of starting a new one"
|
118
|
-
def exec(name, cmd)
|
132
|
+
def exec(name, *cmd)
|
133
|
+
cmd = Kamal::Utils.join_commands(cmd)
|
119
134
|
with_accessory(name) do |accessory, hosts|
|
120
135
|
case
|
121
136
|
when options[:interactive] && options[:reuse]
|
122
|
-
say "Launching interactive command
|
137
|
+
say "Launching interactive command via SSH from existing container...", :magenta
|
123
138
|
run_locally { exec accessory.execute_in_existing_container_over_ssh(cmd) }
|
124
139
|
|
125
140
|
when options[:interactive]
|
@@ -128,16 +143,16 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|
128
143
|
|
129
144
|
when options[:reuse]
|
130
145
|
say "Launching command from existing container...", :magenta
|
131
|
-
on(hosts) do
|
146
|
+
on(hosts) do |host|
|
132
147
|
execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on #{name} accessory"), verbosity: :debug
|
133
|
-
capture_with_info(*accessory.execute_in_existing_container(cmd))
|
148
|
+
puts_by_host host, capture_with_info(*accessory.execute_in_existing_container(cmd))
|
134
149
|
end
|
135
150
|
|
136
151
|
else
|
137
152
|
say "Launching command from new container...", :magenta
|
138
|
-
on(hosts) do
|
153
|
+
on(hosts) do |host|
|
139
154
|
execute *KAMAL.auditor.record("Executed cmd '#{cmd}' on #{name} accessory"), verbosity: :debug
|
140
|
-
capture_with_info(*accessory.execute_in_new_container(cmd))
|
155
|
+
puts_by_host host, capture_with_info(*accessory.execute_in_new_container(cmd))
|
141
156
|
end
|
142
157
|
end
|
143
158
|
end
|
data/lib/kamal/cli/secrets.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
class Kamal::Cli::Secrets < Kamal::Cli::Base
|
2
2
|
desc "fetch [SECRETS...]", "Fetch secrets from a vault"
|
3
3
|
option :adapter, type: :string, aliases: "-a", required: true, desc: "Which vault adapter to use"
|
4
|
-
option :account, type: :string, required:
|
4
|
+
option :account, type: :string, required: false, desc: "The account identifier or username"
|
5
5
|
option :from, type: :string, required: false, desc: "A vault or folder to fetch the secrets from"
|
6
6
|
option :inline, type: :boolean, required: false, hidden: true
|
7
7
|
def fetch(*secrets)
|
8
|
-
|
8
|
+
adapter = initialize_adapter(options[:adapter])
|
9
|
+
|
10
|
+
if adapter.requires_account? && options[:account].blank?
|
11
|
+
return puts "No value provided for required options '--account'"
|
12
|
+
end
|
13
|
+
|
14
|
+
results = adapter.fetch(secrets, **options.slice(:account, :from).symbolize_keys)
|
9
15
|
|
10
16
|
return_or_puts JSON.dump(results).shellescape, inline: options[:inline]
|
11
17
|
end
|
@@ -29,7 +35,7 @@ class Kamal::Cli::Secrets < Kamal::Cli::Base
|
|
29
35
|
end
|
30
36
|
|
31
37
|
private
|
32
|
-
def
|
38
|
+
def initialize_adapter(adapter)
|
33
39
|
Kamal::Secrets::Adapters.lookup(adapter)
|
34
40
|
end
|
35
41
|
|
@@ -16,8 +16,8 @@ servers:
|
|
16
16
|
# Enable SSL auto certification via Let's Encrypt and allow for multiple apps on a single web server.
|
17
17
|
# Remove this section when using multiple web servers and ensure you terminate SSL at your load balancer.
|
18
18
|
#
|
19
|
-
# Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption.
|
20
|
-
proxy:
|
19
|
+
# Note: If using Cloudflare, set encryption mode in SSL/TLS setting to "Full" to enable CF-to-app encryption.
|
20
|
+
proxy:
|
21
21
|
ssl: true
|
22
22
|
host: app.example.com
|
23
23
|
# Proxy connects to your container on port 80 by default.
|
@@ -36,6 +36,9 @@ registry:
|
|
36
36
|
# Configure builder setup.
|
37
37
|
builder:
|
38
38
|
arch: amd64
|
39
|
+
# Pass in additional build args needed for your Dockerfile.
|
40
|
+
# args:
|
41
|
+
# RUBY_VERSION: <%= File.read('.ruby-version').strip %>
|
39
42
|
|
40
43
|
# Inject ENV variables into containers (secrets come from .kamal/secrets).
|
41
44
|
#
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Kamal::Commands::Accessory::Proxy
|
2
|
+
delegate :proxy_container_name, to: :config
|
3
|
+
|
4
|
+
def deploy(target:)
|
5
|
+
proxy_exec :deploy, service_name, *proxy.deploy_command_args(target: target)
|
6
|
+
end
|
7
|
+
|
8
|
+
def remove
|
9
|
+
proxy_exec :remove, service_name
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def proxy_exec(*command)
|
14
|
+
docker :exec, proxy_container_name, "kamal-proxy", *command
|
15
|
+
end
|
16
|
+
end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
class Kamal::Commands::Accessory < Kamal::Commands::Base
|
2
|
+
include Proxy
|
3
|
+
|
2
4
|
attr_reader :accessory_config
|
3
5
|
delegate :service_name, :image, :hosts, :port, :files, :directories, :cmd,
|
4
6
|
:network_args, :publish_args, :env_args, :volume_args, :label_args, :option_args,
|
5
|
-
:secrets_io, :secrets_path, :env_directory,
|
7
|
+
:secrets_io, :secrets_path, :env_directory, :proxy, :running_proxy?,
|
6
8
|
to: :accessory_config
|
9
|
+
delegate :proxy_container_name, to: :config
|
10
|
+
|
7
11
|
|
8
12
|
def initialize(config, name:)
|
9
13
|
super(config)
|
@@ -2,7 +2,7 @@ module Kamal::Commands::App::Containers
|
|
2
2
|
DOCKER_HEALTH_LOG_FORMAT = "'{{json .State.Health}}'"
|
3
3
|
|
4
4
|
def list_containers
|
5
|
-
docker :container, :ls, "--all", *
|
5
|
+
docker :container, :ls, "--all", *container_filter_args
|
6
6
|
end
|
7
7
|
|
8
8
|
def list_container_names
|
@@ -20,7 +20,7 @@ module Kamal::Commands::App::Containers
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def remove_containers
|
23
|
-
docker :container, :prune, "--force", *
|
23
|
+
docker :container, :prune, "--force", *container_filter_args
|
24
24
|
end
|
25
25
|
|
26
26
|
def container_health_log(version:)
|
data/lib/kamal/commands/app.rb
CHANGED
@@ -47,7 +47,7 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def info
|
50
|
-
docker :ps, *
|
50
|
+
docker :ps, *container_filter_args
|
51
51
|
end
|
52
52
|
|
53
53
|
|
@@ -67,7 +67,7 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|
67
67
|
|
68
68
|
def list_versions(*docker_args, statuses: nil)
|
69
69
|
pipe \
|
70
|
-
docker(:ps, *
|
70
|
+
docker(:ps, *container_filter_args(statuses: statuses), *docker_args, "--format", '"{{.Names}}"'),
|
71
71
|
extract_version_from_name
|
72
72
|
end
|
73
73
|
|
@@ -91,11 +91,15 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def latest_container(format:, filters: nil)
|
94
|
-
docker :ps, "--latest", *format, *
|
94
|
+
docker :ps, "--latest", *format, *container_filter_args(statuses: ACTIVE_DOCKER_STATUSES), argumentize("--filter", filters)
|
95
95
|
end
|
96
96
|
|
97
|
-
def
|
98
|
-
argumentize "--filter",
|
97
|
+
def container_filter_args(statuses: nil)
|
98
|
+
argumentize "--filter", container_filters(statuses: statuses)
|
99
|
+
end
|
100
|
+
|
101
|
+
def image_filter_args
|
102
|
+
argumentize "--filter", image_filters
|
99
103
|
end
|
100
104
|
|
101
105
|
def extract_version_from_name
|
@@ -103,13 +107,17 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|
103
107
|
%(while read line; do echo ${line##{role.container_prefix}-}; done)
|
104
108
|
end
|
105
109
|
|
106
|
-
def
|
110
|
+
def container_filters(statuses: nil)
|
107
111
|
[ "label=service=#{config.service}" ].tap do |filters|
|
108
|
-
filters << "label=destination=#{config.destination}"
|
112
|
+
filters << "label=destination=#{config.destination}"
|
109
113
|
filters << "label=role=#{role}" if role
|
110
114
|
statuses&.each do |status|
|
111
115
|
filters << "status=#{status}"
|
112
116
|
end
|
113
117
|
end
|
114
118
|
end
|
119
|
+
|
120
|
+
def image_filters
|
121
|
+
[ "label=service=#{config.service}" ]
|
122
|
+
end
|
115
123
|
end
|
@@ -6,7 +6,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
6
6
|
delegate :argumentize, to: Kamal::Utils
|
7
7
|
delegate \
|
8
8
|
:args, :secrets, :dockerfile, :target, :arches, :local_arches, :remote_arches, :remote,
|
9
|
-
:cache_from, :cache_to, :ssh, :provenance, :driver, :docker_driver?,
|
9
|
+
:cache_from, :cache_to, :ssh, :provenance, :sbom, :driver, :docker_driver?,
|
10
10
|
to: :builder_config
|
11
11
|
|
12
12
|
def clean
|
@@ -37,7 +37,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def build_options
|
40
|
-
[ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh, *builder_provenance ]
|
40
|
+
[ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh, *builder_provenance, *builder_sbom ]
|
41
41
|
end
|
42
42
|
|
43
43
|
def build_context
|
@@ -101,6 +101,10 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
101
101
|
argumentize "--provenance", provenance unless provenance.nil?
|
102
102
|
end
|
103
103
|
|
104
|
+
def builder_sbom
|
105
|
+
argumentize "--sbom", sbom unless sbom.nil?
|
106
|
+
end
|
107
|
+
|
104
108
|
def builder_config
|
105
109
|
config.builder
|
106
110
|
end
|
@@ -5,7 +5,7 @@ class Kamal::Configuration::Accessory
|
|
5
5
|
|
6
6
|
delegate :argumentize, :optionize, to: Kamal::Utils
|
7
7
|
|
8
|
-
attr_reader :name, :accessory_config, :env
|
8
|
+
attr_reader :name, :accessory_config, :env, :proxy
|
9
9
|
|
10
10
|
def initialize(name, config:)
|
11
11
|
@name, @config, @accessory_config = name.inquiry, config, config.raw_config["accessories"][name]
|
@@ -20,6 +20,8 @@ class Kamal::Configuration::Accessory
|
|
20
20
|
config: accessory_config.fetch("env", {}),
|
21
21
|
secrets: config.secrets,
|
22
22
|
context: "accessories/#{name}/env"
|
23
|
+
|
24
|
+
initialize_proxy if running_proxy?
|
23
25
|
end
|
24
26
|
|
25
27
|
def service_name
|
@@ -106,6 +108,17 @@ class Kamal::Configuration::Accessory
|
|
106
108
|
accessory_config["cmd"]
|
107
109
|
end
|
108
110
|
|
111
|
+
def running_proxy?
|
112
|
+
@accessory_config["proxy"].present?
|
113
|
+
end
|
114
|
+
|
115
|
+
def initialize_proxy
|
116
|
+
@proxy = Kamal::Configuration::Proxy.new \
|
117
|
+
config: config,
|
118
|
+
proxy_config: accessory_config["proxy"],
|
119
|
+
context: "accessories/#{name}/proxy"
|
120
|
+
end
|
121
|
+
|
109
122
|
private
|
110
123
|
attr_accessor :config
|
111
124
|
|
@@ -176,7 +189,9 @@ class Kamal::Configuration::Accessory
|
|
176
189
|
|
177
190
|
def hosts_from_roles
|
178
191
|
if accessory_config.key?("roles")
|
179
|
-
accessory_config["roles"].flat_map
|
192
|
+
accessory_config["roles"].flat_map do |role|
|
193
|
+
config.role(role)&.hosts || raise(Kamal::ConfigurationError, "Unknown role in accessories config: '#{role}'")
|
194
|
+
end
|
180
195
|
end
|
181
196
|
end
|
182
197
|
|
@@ -108,3 +108,9 @@ builder:
|
|
108
108
|
# It is used to configure provenance attestations for the build result.
|
109
109
|
# The value can also be a boolean to enable or disable provenance attestations.
|
110
110
|
provenance: mode=max
|
111
|
+
|
112
|
+
# SBOM (Software Bill of Materials)
|
113
|
+
#
|
114
|
+
# It is used to configure SBOM generation for the build result.
|
115
|
+
# The value can also be a boolean to enable or disable SBOM generation.
|
116
|
+
sbom: true
|
@@ -54,6 +54,11 @@ proxy:
|
|
54
54
|
# Next big thing after...
|
55
55
|
tls_on_demand_url: "http://example.com/check_host"
|
56
56
|
|
57
|
+
# TLSFlexibleMode
|
58
|
+
#
|
59
|
+
# Next big thing after...
|
60
|
+
tls_flexible_mode: false
|
61
|
+
|
57
62
|
# Response timeout
|
58
63
|
#
|
59
64
|
# How long to wait for requests to complete before timing out, defaults to 30 seconds:
|
@@ -31,6 +31,7 @@ class Kamal::Configuration::Proxy
|
|
31
31
|
host: hosts,
|
32
32
|
tls: proxy_config["ssl"].presence,
|
33
33
|
"tls-on-demand-url": proxy_config["tls_on_demand_url"],
|
34
|
+
"tls-flexible-mode": proxy_config["tls_flexible_mode"].presence,
|
34
35
|
"deploy-timeout": seconds_duration(config.deploy_timeout),
|
35
36
|
"drain-timeout": seconds_duration(config.drain_timeout),
|
36
37
|
"health-check-interval": seconds_duration(proxy_config.dig("healthcheck", "interval")),
|
data/lib/kamal/configuration.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
class Kamal::Secrets::Adapters::AwsSecretsManager < Kamal::Secrets::Adapters::Base
|
2
|
+
private
|
3
|
+
def login(_account)
|
4
|
+
nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def fetch_secrets(secrets, account:, session:)
|
8
|
+
{}.tap do |results|
|
9
|
+
JSON.parse(get_from_secrets_manager(secrets, account: account))["SecretValues"].each do |secret|
|
10
|
+
secret_name = secret["Name"]
|
11
|
+
secret_string = JSON.parse(secret["SecretString"])
|
12
|
+
|
13
|
+
secret_string.each do |key, value|
|
14
|
+
results["#{secret_name}/#{key}"] = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_from_secrets_manager(secrets, account:)
|
21
|
+
`aws secretsmanager batch-get-secret-value --secret-id-list #{secrets.map(&:shellescape).join(" ")} --profile #{account.shellescape}`.tap do
|
22
|
+
raise RuntimeError, "Could not read #{secret} from AWS Secrets Manager" unless $?.success?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def check_dependencies!
|
27
|
+
raise RuntimeError, "AWS CLI is not installed" unless cli_installed?
|
28
|
+
end
|
29
|
+
|
30
|
+
def cli_installed?
|
31
|
+
`aws --version 2> /dev/null`
|
32
|
+
$?.success?
|
33
|
+
end
|
34
|
+
end
|
@@ -1,13 +1,20 @@
|
|
1
1
|
class Kamal::Secrets::Adapters::Base
|
2
2
|
delegate :optionize, to: Kamal::Utils
|
3
3
|
|
4
|
-
def fetch(secrets, account
|
4
|
+
def fetch(secrets, account: nil, from: nil)
|
5
|
+
raise RuntimeError, "Missing required option '--account'" if requires_account? && account.blank?
|
6
|
+
|
5
7
|
check_dependencies!
|
8
|
+
|
6
9
|
session = login(account)
|
7
10
|
full_secrets = secrets.map { |secret| [ from, secret ].compact.join("/") }
|
8
11
|
fetch_secrets(full_secrets, account: account, session: session)
|
9
12
|
end
|
10
13
|
|
14
|
+
def requires_account?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
11
18
|
private
|
12
19
|
def login(...)
|
13
20
|
raise NotImplementedError
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class Kamal::Secrets::Adapters::Doppler < Kamal::Secrets::Adapters::Base
|
2
|
+
def requires_account?
|
3
|
+
false
|
4
|
+
end
|
5
|
+
|
6
|
+
private
|
7
|
+
def login(*)
|
8
|
+
unless loggedin?
|
9
|
+
`doppler login -y`
|
10
|
+
raise RuntimeError, "Failed to login to Doppler" unless $?.success?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def loggedin?
|
15
|
+
`doppler me --json 2> /dev/null`
|
16
|
+
$?.success?
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch_secrets(secrets, **)
|
20
|
+
project_and_config_flags = ""
|
21
|
+
unless service_token_set?
|
22
|
+
project, config, _ = secrets.first.split("/")
|
23
|
+
|
24
|
+
unless project && config
|
25
|
+
raise RuntimeError, "Missing project or config from '--from=project/config' option"
|
26
|
+
end
|
27
|
+
|
28
|
+
project_and_config_flags = "-p #{project.shellescape} -c #{config.shellescape}"
|
29
|
+
end
|
30
|
+
|
31
|
+
secret_names = secrets.collect { |s| s.split("/").last }
|
32
|
+
|
33
|
+
items = `doppler secrets get #{secret_names.map(&:shellescape).join(" ")} --json #{project_and_config_flags}`
|
34
|
+
raise RuntimeError, "Could not read #{secrets} from Doppler" unless $?.success?
|
35
|
+
|
36
|
+
items = JSON.parse(items)
|
37
|
+
|
38
|
+
items.transform_values { |value| value["computed"] }
|
39
|
+
end
|
40
|
+
|
41
|
+
def service_token_set?
|
42
|
+
ENV["DOPPLER_TOKEN"] && ENV["DOPPLER_TOKEN"][0, 5] == "dp.st"
|
43
|
+
end
|
44
|
+
|
45
|
+
def check_dependencies!
|
46
|
+
raise RuntimeError, "Doppler CLI is not installed" unless cli_installed?
|
47
|
+
end
|
48
|
+
|
49
|
+
def cli_installed?
|
50
|
+
`doppler --version 2> /dev/null`
|
51
|
+
$?.success?
|
52
|
+
end
|
53
|
+
end
|
data/lib/kamal/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nocoffee-kamal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.0.
|
4
|
+
version: 2.3.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -204,7 +204,7 @@ dependencies:
|
|
204
204
|
- - ">="
|
205
205
|
- !ruby/object:Gem::Version
|
206
206
|
version: '0'
|
207
|
-
description:
|
207
|
+
description:
|
208
208
|
email: dhh@hey.com
|
209
209
|
executables:
|
210
210
|
- kamal
|
@@ -247,6 +247,7 @@ files:
|
|
247
247
|
- lib/kamal/commander/specifics.rb
|
248
248
|
- lib/kamal/commands.rb
|
249
249
|
- lib/kamal/commands/accessory.rb
|
250
|
+
- lib/kamal/commands/accessory/proxy.rb
|
250
251
|
- lib/kamal/commands/app.rb
|
251
252
|
- lib/kamal/commands/app/assets.rb
|
252
253
|
- lib/kamal/commands/app/containers.rb
|
@@ -312,11 +313,14 @@ files:
|
|
312
313
|
- lib/kamal/git.rb
|
313
314
|
- lib/kamal/secrets.rb
|
314
315
|
- lib/kamal/secrets/adapters.rb
|
316
|
+
- lib/kamal/secrets/adapters/aws_secrets_manager.rb
|
315
317
|
- lib/kamal/secrets/adapters/base.rb
|
316
318
|
- lib/kamal/secrets/adapters/bitwarden.rb
|
319
|
+
- lib/kamal/secrets/adapters/doppler.rb
|
317
320
|
- lib/kamal/secrets/adapters/last_pass.rb
|
318
321
|
- lib/kamal/secrets/adapters/one_password.rb
|
319
322
|
- lib/kamal/secrets/adapters/test.rb
|
323
|
+
- lib/kamal/secrets/adapters/test_optional_account.rb
|
320
324
|
- lib/kamal/secrets/dotenv/inline_command_substitution.rb
|
321
325
|
- lib/kamal/sshkit_with_ext.rb
|
322
326
|
- lib/kamal/tags.rb
|
@@ -342,8 +346,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
342
346
|
- !ruby/object:Gem::Version
|
343
347
|
version: '0'
|
344
348
|
requirements: []
|
345
|
-
rubygems_version: 3.5.
|
349
|
+
rubygems_version: 3.5.23
|
346
350
|
signing_key:
|
347
351
|
specification_version: 4
|
348
|
-
summary:
|
352
|
+
summary: Kamal with the TLS on demand feature.
|
349
353
|
test_files: []
|