kamal-backup 0.2.0 → 0.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71b890ee6ff8e37a722f17ea92270d01c6c106fec2a523bf601b8016790646b4
4
- data.tar.gz: 4ac9df9a5f7e9b6b7c9a4b5cab76d23c0555a237885579c5e6ada74968ac1ab6
3
+ metadata.gz: 49afc009b695f3cf7f456e1b68b2b744f5adc7138f7ca4d0c84ffb1f0d3b766d
4
+ data.tar.gz: fc0261dc6c744a19e02460f27aab7e8f7555de779ea1fe7827a2fdf077042071
5
5
  SHA512:
6
- metadata.gz: 5f0e231df821c0dae8bcb570fe9a41a221d9e8561fee88b57228de6f045c6fdbc211030e0aae27b8072c881e76714c0665aa26e3daf73f6eff5b8046b955cfdf
7
- data.tar.gz: b86e898c00cd2676a62d91e8c28b207128894907795a483a420280dbedc5c3040e230ad66e6f23fc97831300e2e7805466ab51dd9e7baefd8164b4e49c6dda8e
6
+ metadata.gz: 39839b0f31f1e5a9bf561e63ee2248330d1857f5f21c2736e1668aed2e226c79e3c6063c6195a6bb09e05c180bfd42a6cd6901271638e3dbba2a36ab8146844f
7
+ data.tar.gz: 3bb459e3ff320cff130ac29c523a09c50b85b3efb98ad977410cdd2db0a53e333fce935f8a92aaa65325b7d421ce36be4ed92c49a6f46d5836184f2a4009e94e
@@ -64,7 +64,8 @@ module KamalBackup
64
64
  @bridge ||= KamalBridge.new(
65
65
  redactor: redactor,
66
66
  config_file: options[:config_file],
67
- destination: options[:destination]
67
+ destination: options[:destination],
68
+ env: command_env
68
69
  )
69
70
  end
70
71
 
@@ -6,10 +6,11 @@ module KamalBackup
6
6
  DEFAULT_CONFIG_FILE = "config/deploy.yml"
7
7
  VERSION_LINE_PATTERN = /\A\d+(?:\.\d+)+(?:[-.][A-Za-z0-9]+)*\z/
8
8
 
9
- def initialize(redactor:, config_file: nil, destination: nil)
9
+ def initialize(redactor:, config_file: nil, destination: nil, env: ENV)
10
10
  @redactor = redactor
11
11
  @config_file = config_file
12
12
  @destination = destination
13
+ @env = env
13
14
  end
14
15
 
15
16
  def accessory_name(preferred: nil)
@@ -104,16 +105,54 @@ module KamalBackup
104
105
  def normalize_secret_env(values)
105
106
  case values
106
107
  when Hash
107
- values.each_with_object({}) { |(key, _value), env| env[key.to_s] = "configured" }
108
+ values.each_with_object({}) do |(key, secret_key), env|
109
+ add_resolved_secret(env, target: key, source: secret_key)
110
+ end
108
111
  when Array
109
- values.each_with_object({}) { |key, env| env[key.to_s] = "configured" }
112
+ values.each_with_object({}) do |entry, env|
113
+ target, source = parse_secret_entry(entry)
114
+ add_resolved_secret(env, target: target, source: source)
115
+ end
110
116
  when String, Symbol
111
- { values.to_s => "configured" }
117
+ {}.tap do |env|
118
+ target, source = parse_secret_entry(values)
119
+ add_resolved_secret(env, target: target, source: source)
120
+ end
112
121
  else
113
122
  {}
114
123
  end
115
124
  end
116
125
 
126
+ def parse_secret_entry(entry)
127
+ target, source = entry.to_s.split(":", 2)
128
+ [ target, source || target ]
129
+ end
130
+
131
+ def add_resolved_secret(env, target:, source:)
132
+ if value = resolved_secret(source)
133
+ env[target.to_s] = value
134
+ end
135
+ end
136
+
137
+ def resolved_secret(key)
138
+ raw = resolved_secrets[key.to_s] || @env[key.to_s]
139
+ value = raw.to_s.strip
140
+ value.empty? ? nil : value
141
+ end
142
+
143
+ def resolved_secrets
144
+ @resolved_secrets ||= parse_secret_output(capture_kamal(kamal_secrets_print_argv).stdout)
145
+ end
146
+
147
+ def parse_secret_output(output)
148
+ output.to_s.lines.each_with_object({}) do |line, secrets|
149
+ key, value = line.chomp.split("=", 2)
150
+ next if key.to_s.empty?
151
+
152
+ secrets[key] = value.to_s
153
+ end
154
+ end
155
+
117
156
  def fetch(hash, key)
118
157
  hash[key] || hash[key.to_s] || hash[key.to_sym]
119
158
  end
@@ -139,6 +178,15 @@ module KamalBackup
139
178
  ]
140
179
  end
141
180
 
181
+ def kamal_secrets_print_argv
182
+ [
183
+ "kamal",
184
+ "secrets",
185
+ "print",
186
+ *kamal_option_argv
187
+ ]
188
+ end
189
+
142
190
  def kamal_option_argv
143
191
  argv = []
144
192
  argv.concat(["-c", @config_file]) if @config_file
@@ -6,6 +6,8 @@ require_relative "command"
6
6
 
7
7
  module KamalBackup
8
8
  class Restic
9
+ RESTIC_ENV_PATTERN = /\A(?:RESTIC_|AWS_|B2_|AZURE_|GOOGLE_|RCLONE_|OS_|ST_|HP_|HTTP_|HTTPS_|NO_PROXY)/i
10
+
9
11
  attr_reader :config, :redactor
10
12
 
11
13
  def initialize(config, redactor:)
@@ -25,13 +27,19 @@ module KamalBackup
25
27
  end
26
28
 
27
29
  def backup_stream(command, filename:, tags:)
28
- restic_command = CommandSpec.new(argv: ["restic", "backup", "--stdin", "--stdin-filename", filename] + tag_args(common_tags + tags))
30
+ restic_command = CommandSpec.new(
31
+ argv: ["restic", "backup", "--stdin", "--stdin-filename", filename] + tag_args(common_tags + tags),
32
+ env: restic_env
33
+ )
29
34
  log("backing up stream as #{filename}")
30
35
  pipe_commands(command, restic_command, producer_label: "dump", consumer_label: "restic backup")
31
36
  end
32
37
 
33
38
  def backup_file(path, filename:, tags:)
34
- command = CommandSpec.new(argv: ["restic", "backup", "--stdin", "--stdin-filename", filename] + tag_args(common_tags + tags))
39
+ command = CommandSpec.new(
40
+ argv: ["restic", "backup", "--stdin", "--stdin-filename", filename] + tag_args(common_tags + tags),
41
+ env: restic_env
42
+ )
35
43
  log("backing up file content as #{filename}")
36
44
 
37
45
  File.open(path, "rb") do |file|
@@ -126,12 +134,12 @@ module KamalBackup
126
134
  end
127
135
 
128
136
  def pipe_dump_to_command(snapshot, filename, command)
129
- restic_command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename])
137
+ restic_command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename], env: restic_env)
130
138
  pipe_commands(restic_command, command, producer_label: "restic dump", consumer_label: command.argv.first)
131
139
  end
132
140
 
133
141
  def write_dump_to_path(snapshot, filename, target_path)
134
- command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename])
142
+ command = CommandSpec.new(argv: ["restic", "dump", snapshot, filename], env: restic_env)
135
143
  target_path = File.expand_path(target_path)
136
144
  FileUtils.mkdir_p(File.dirname(target_path))
137
145
  temp_path = "#{target_path}.kamal-backup-#{$$}.tmp"
@@ -160,7 +168,7 @@ module KamalBackup
160
168
  end
161
169
 
162
170
  def run(args)
163
- Command.capture(CommandSpec.new(argv: ["restic"] + args), redactor: redactor)
171
+ Command.capture(CommandSpec.new(argv: ["restic"] + args, env: restic_env), redactor: redactor)
164
172
  end
165
173
 
166
174
  def common_tags
@@ -172,6 +180,12 @@ module KamalBackup
172
180
  tags.compact.each_with_object([]) { |tag, args| args.concat(["--tag", tag]) }
173
181
  end
174
182
 
183
+ def restic_env
184
+ config.env.each_with_object({}) do |(key, value), env|
185
+ env[key] = value if key.to_s.match?(RESTIC_ENV_PATTERN)
186
+ end
187
+ end
188
+
175
189
  def pipe_commands(producer, consumer, producer_label:, consumer_label:)
176
190
  Open3.popen3(producer.env, *producer.argv) do |producer_stdin, producer_stdout, producer_stderr, producer_wait|
177
191
  producer_stdin.close
@@ -1,3 +1,3 @@
1
1
  module KamalBackup
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kamal-backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - crmne