nocoffee-kamal 2.3.0.1 → 2.3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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.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: 28c14758366da1ecad587823ea0ecaaee14a3584373a6b40ce6f2fe390490970
|
4
|
+
data.tar.gz: 7526c6d1c7188edeb94801529a804ec688a3bac00b6d60e22c6b3ee9fe3628c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9936c64cbfd480b28bfb64b5a93513a54f92efe4fb86aa71f3cbfefc1e11229cf2aec435a733d51990cd345255b981e243043c4f6bbf0d11c1d63a6bc9cbeff
|
7
|
+
data.tar.gz: c90910f3d1bfd2dfdf7ddebdd9c6e126a90c0104f8f109c1e41da13235c7c0cc06ea59a3217ceccdf64e8e6082db6a61d4cc5d7d9d5a01e9fa7fffe0b46455f5
|
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
|
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.2
|
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: []
|