rkseal 0.1.0 → 0.1.1
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/README.md +10 -7
- data/lib/rkseal/cli.rb +7 -17
- data/lib/rkseal/kubeseal.rb +27 -133
- data/lib/rkseal/version.rb +1 -1
- data/rkseal.gemspec +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e119d50bf74489108689a815572225254b7dba2e0efcaa0f5e2a70b23bb84624
|
|
4
|
+
data.tar.gz: 8ab17b1fc3043580cebb850395321a92bbba7c78052531a3814f8ab888c37acb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fd59fede38ef24369b8aca1c8de658be6e3cfb9300a5d96ebe4f0d5b5bcdec500f2949cb6073be2a053d7a1aaeafa809676f53f0b70ca175c062e19a15491cb2
|
|
7
|
+
data.tar.gz: 89516ab7c39d5ad37070bc83017d37fa2ecc707594079d6973456490a63f814d3355d70eb86fa7663ee8a6bee36fcaabc349d543868efcdda9839f3fe2794815
|
data/README.md
CHANGED
|
@@ -63,7 +63,7 @@ example to make this obvious. Pass `--string-data` to decode the **whole** buffe
|
|
|
63
63
|
- `--local` — force the offline local edit without contacting the cluster at all (see below).
|
|
64
64
|
- `--string-data` — decode the live Secret's `data` into plaintext `stringData` for editing,
|
|
65
65
|
instead of showing it as raw base64.
|
|
66
|
-
- `--cert`, `--controller-name`, `--controller-namespace
|
|
66
|
+
- `--cert`, `--controller-name`, `--controller-namespace` — control which
|
|
67
67
|
controller certificate is used to re-seal (same as `create`).
|
|
68
68
|
- **No-op short-circuit:** if you save the buffer without changing anything, `rkseal` writes
|
|
69
69
|
no file (re-sealing identical input would only produce a spurious ciphertext diff). Because
|
|
@@ -98,7 +98,6 @@ online `edit`.
|
|
|
98
98
|
TLS / dockerconfig / binary payloads).
|
|
99
99
|
- `--string-data` — seed the buffer with a plaintext `stringData` block instead of base64
|
|
100
100
|
`data`, so you type values in clear (folded into `data` on save).
|
|
101
|
-
- `--refresh-cert` — bypass the cached controller cert and re-fetch it for this run.
|
|
102
101
|
- The controller certificate is resolved up front, so an unreachable controller fails fast
|
|
103
102
|
**before** you start editing.
|
|
104
103
|
|
|
@@ -106,23 +105,27 @@ online `edit`.
|
|
|
106
105
|
|
|
107
106
|
- `--deploy` / `--yes` — same deploy semantics as `edit` (opt-in, context-confirmed; `--yes`
|
|
108
107
|
skips the prompt).
|
|
109
|
-
- `--cert`, `--controller-name`, `--controller-namespace
|
|
108
|
+
- `--cert`, `--controller-name`, `--controller-namespace`.
|
|
110
109
|
|
|
111
110
|
### `validate` flags
|
|
112
111
|
|
|
113
112
|
- `--file <path>` — validate an arbitrary SealedSecret manifest instead of the local
|
|
114
113
|
`<secret-name>.yaml` (then `NAMESPACE`/`NAME` are optional).
|
|
115
|
-
- `--cert`, `--controller-name`, `--controller-namespace
|
|
114
|
+
- `--cert`, `--controller-name`, `--controller-namespace`.
|
|
116
115
|
|
|
117
116
|
### `view` flags
|
|
118
117
|
|
|
119
118
|
- `--reveal` — decode `data` and print values as plaintext `stringData` (default shows raw
|
|
120
119
|
base64, consistent with `edit`). Read-only: `view` never writes a file or opens an editor.
|
|
121
120
|
|
|
122
|
-
###
|
|
121
|
+
### Controller certificate
|
|
123
122
|
|
|
124
|
-
`create`, `edit`, `reencrypt`, and `validate`
|
|
125
|
-
|
|
123
|
+
`create`, `edit`, `reencrypt`, and `validate` resolve the controller's public cert from, in
|
|
124
|
+
order: `--cert <file|URL>`, the `SEALED_SECRETS_CERT` env var (both offline — nothing is
|
|
125
|
+
contacted), otherwise a fresh `--fetch-cert` from the live controller. **The cert is never
|
|
126
|
+
cached on disk** — it is re-fetched every run, so a seal is always bound to the current kube
|
|
127
|
+
context's controller key. For offline or reproducible (GitOps/CI) seals, pin `--cert` or
|
|
128
|
+
`SEALED_SECRETS_CERT` to a committed certificate.
|
|
126
129
|
|
|
127
130
|
## Requirements
|
|
128
131
|
|
data/lib/rkseal/cli.rb
CHANGED
|
@@ -83,8 +83,6 @@ module RKSeal
|
|
|
83
83
|
desc: "sealed-secrets controller name"
|
|
84
84
|
method_option :"controller-namespace", type: :string,
|
|
85
85
|
desc: "controller namespace"
|
|
86
|
-
method_option :"refresh-cert", type: :boolean, default: false,
|
|
87
|
-
desc: "Bypass the cert cache and re-fetch from the controller"
|
|
88
86
|
method_option :"from-file", type: :array,
|
|
89
87
|
desc: "Pre-seed key=path value(s) into the buffer before editing"
|
|
90
88
|
method_option :"no-edit", type: :boolean, default: false,
|
|
@@ -163,8 +161,6 @@ module RKSeal
|
|
|
163
161
|
desc: "sealed-secrets controller name"
|
|
164
162
|
method_option :"controller-namespace", type: :string,
|
|
165
163
|
desc: "controller namespace"
|
|
166
|
-
method_option :"refresh-cert", type: :boolean, default: false,
|
|
167
|
-
desc: "Bypass the cert cache and re-fetch from the controller"
|
|
168
164
|
# Edit an existing SealedSecret. Reads current values from the cluster; if
|
|
169
165
|
# the Secret is absent there but a local <NAME>.yaml exists, automatically
|
|
170
166
|
# falls back to the offline local edit. `--local` forces the offline path.
|
|
@@ -201,8 +197,6 @@ module RKSeal
|
|
|
201
197
|
desc: "sealed-secrets controller name"
|
|
202
198
|
method_option :"controller-namespace", type: :string,
|
|
203
199
|
desc: "controller namespace"
|
|
204
|
-
method_option :"refresh-cert", type: :boolean, default: false,
|
|
205
|
-
desc: "Bypass the cert cache and re-fetch from the controller"
|
|
206
200
|
# Re-encrypt an existing SealedSecret to the newest controller key.
|
|
207
201
|
#
|
|
208
202
|
# @param namespace [String] target namespace.
|
|
@@ -238,8 +232,6 @@ module RKSeal
|
|
|
238
232
|
desc: "sealed-secrets controller name"
|
|
239
233
|
method_option :"controller-namespace", type: :string,
|
|
240
234
|
desc: "controller namespace"
|
|
241
|
-
method_option :"refresh-cert", type: :boolean, default: false,
|
|
242
|
-
desc: "Bypass the cert cache and re-fetch from the controller"
|
|
243
235
|
# Validate a SealedSecret (local <NAME>.yaml, or --file <path>).
|
|
244
236
|
#
|
|
245
237
|
# @param namespace [String, nil] target namespace (omit with --file).
|
|
@@ -428,22 +420,20 @@ module RKSeal
|
|
|
428
420
|
end
|
|
429
421
|
|
|
430
422
|
# Build the kubeseal adapter from the cert/controller options. Dashed option
|
|
431
|
-
# names are string keys (Thor does not auto-underscore them).
|
|
432
|
-
# bypasses the cert cache (`Kubeseal.new(refresh_cert:)`); it defaults to
|
|
433
|
-
# false for every command that builds a kubeseal adapter.
|
|
423
|
+
# names are string keys (Thor does not auto-underscore them).
|
|
434
424
|
#
|
|
435
|
-
# The controller name/namespace are Kubernetes identifiers that flow
|
|
436
|
-
#
|
|
437
|
-
# as the positional args) -- this
|
|
438
|
-
#
|
|
425
|
+
# The controller name/namespace are Kubernetes identifiers that flow straight
|
|
426
|
+
# into kubeseal's `--controller-name`/`--controller-namespace` flags, so they
|
|
427
|
+
# are validated as DNS-1123 here (same gate as the positional args) -- this
|
|
428
|
+
# rejects flag-injection (`-oyaml`, a leading `-`) and NUL before any value
|
|
429
|
+
# reaches the shell-out.
|
|
439
430
|
def build_kubeseal
|
|
440
431
|
controller_name = validated_controller("controller-name")
|
|
441
432
|
controller_namespace = validated_controller("controller-namespace")
|
|
442
433
|
Kubeseal.new(
|
|
443
434
|
cert: options["cert"],
|
|
444
435
|
controller_name: controller_name,
|
|
445
|
-
controller_namespace: controller_namespace
|
|
446
|
-
refresh_cert: options.fetch("refresh-cert", false)
|
|
436
|
+
controller_namespace: controller_namespace
|
|
447
437
|
)
|
|
448
438
|
end
|
|
449
439
|
|
data/lib/rkseal/kubeseal.rb
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "open3"
|
|
4
|
-
require "fileutils"
|
|
5
|
-
require "securerandom"
|
|
6
4
|
|
|
7
5
|
module RKSeal
|
|
8
6
|
# Thin adapter over the `kubeseal` binary.
|
|
@@ -19,9 +17,11 @@ module RKSeal
|
|
|
19
17
|
# stub a single seam (or stub the public methods directly). The runner must
|
|
20
18
|
# never echo stdin (the plaintext Secret) into logs or error messages.
|
|
21
19
|
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
20
|
+
# The controller certificate is never cached on disk: an explicit `--cert` or
|
|
21
|
+
# `SEALED_SECRETS_CERT` is used offline, otherwise it is fetched fresh from the
|
|
22
|
+
# live controller on every invocation. This keeps a seal always bound to the
|
|
23
|
+
# current context's controller key -- no stale or cross-cluster cert can sneak
|
|
24
|
+
# in (see {#ensure_cert!}).
|
|
25
25
|
class Kubeseal
|
|
26
26
|
BINARY = "kubeseal"
|
|
27
27
|
|
|
@@ -32,13 +32,6 @@ module RKSeal
|
|
|
32
32
|
cluster_wide: "cluster-wide"
|
|
33
33
|
}.freeze
|
|
34
34
|
|
|
35
|
-
# kubeseal's own defaults for the controller's identity. Used to name the
|
|
36
|
-
# cache entry consistently when the caller does not override them, so a run
|
|
37
|
-
# with implicit defaults and a run with explicit-but-identical flags share
|
|
38
|
-
# one cached cert.
|
|
39
|
-
DEFAULT_CONTROLLER_NAME = "sealed-secrets-controller"
|
|
40
|
-
DEFAULT_CONTROLLER_NAMESPACE = "kube-system"
|
|
41
|
-
|
|
42
35
|
# Substring kubeseal prints to stderr when the controller could decrypt-test
|
|
43
36
|
# the SealedSecret but it is NOT valid. Anything else on a non-zero
|
|
44
37
|
# `--validate` exit is treated as operational (CommandError), not a verdict.
|
|
@@ -48,16 +41,13 @@ module RKSeal
|
|
|
48
41
|
# @param controller_name [String, nil] `--controller-name` value.
|
|
49
42
|
# @param controller_namespace [String, nil] `--controller-namespace` value.
|
|
50
43
|
# @param cert [String, nil] `--cert <file|URL>` source; when nil and no env
|
|
51
|
-
# cert is present, the cert is fetched from the controller
|
|
52
|
-
# @param refresh_cert [Boolean] when true, ignore any cached cert and
|
|
53
|
-
# overwrite it with a freshly fetched one (wired to `--refresh-cert`).
|
|
44
|
+
# cert is present, the cert is fetched fresh from the controller per seal.
|
|
54
45
|
def initialize(binary: BINARY, controller_name: nil, controller_namespace: nil,
|
|
55
|
-
cert: nil
|
|
46
|
+
cert: nil)
|
|
56
47
|
@binary = binary
|
|
57
48
|
@controller_name = controller_name
|
|
58
49
|
@controller_namespace = controller_namespace
|
|
59
50
|
@cert = cert
|
|
60
|
-
@refresh_cert = refresh_cert
|
|
61
51
|
end
|
|
62
52
|
|
|
63
53
|
# Verify the kubeseal binary is present and executable; raise otherwise.
|
|
@@ -73,13 +63,12 @@ module RKSeal
|
|
|
73
63
|
"Install it from https://github.com/bitnami-labs/sealed-secrets/releases."
|
|
74
64
|
end
|
|
75
65
|
|
|
76
|
-
#
|
|
77
|
-
# editor opens. When an offline cert is configured (`--cert`
|
|
78
|
-
# `SEALED_SECRETS_CERT` env var) nothing is contacted. Otherwise the
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
# cached copy and refetches.
|
|
66
|
+
# Confirm the encryption certificate is obtainable up front so a flow fails
|
|
67
|
+
# fast before any editor opens. When an offline cert is configured (`--cert`
|
|
68
|
+
# or the `SEALED_SECRETS_CERT` env var) nothing is contacted. Otherwise the
|
|
69
|
+
# controller is probed with `--fetch-cert`; the fetched PEM is intentionally
|
|
70
|
+
# discarded -- {#seal} re-fetches at seal time, so the freshest controller
|
|
71
|
+
# key is always used and nothing is persisted between invocations.
|
|
83
72
|
#
|
|
84
73
|
# @return [void]
|
|
85
74
|
# @raise [RKSeal::CommandError] if no offline cert is configured and the
|
|
@@ -87,17 +76,17 @@ module RKSeal
|
|
|
87
76
|
def ensure_cert!
|
|
88
77
|
return if offline_cert?
|
|
89
78
|
|
|
90
|
-
|
|
79
|
+
fetch_cert
|
|
91
80
|
nil
|
|
92
81
|
end
|
|
93
82
|
|
|
94
83
|
# Seal a Secret manifest into a SealedSecret.
|
|
95
84
|
#
|
|
96
85
|
# Pipes `manifest_yaml` to kubeseal on stdin with `-o yaml` and the resolved
|
|
97
|
-
# `--scope`.
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
86
|
+
# `--scope`. An explicit `--cert` is passed straight through; otherwise no
|
|
87
|
+
# `--cert` is given and kubeseal resolves the cert itself -- from
|
|
88
|
+
# `SEALED_SECRETS_CERT`, or failing that fresh from the live controller.
|
|
89
|
+
# Returns the SealedSecret YAML on stdout.
|
|
101
90
|
#
|
|
102
91
|
# @param manifest_yaml [String] a full Secret manifest (from
|
|
103
92
|
# {RKSeal::Secret#to_manifest}).
|
|
@@ -158,11 +147,10 @@ module RKSeal
|
|
|
158
147
|
# entry untouched. This is what powers the offline `edit --local` flow,
|
|
159
148
|
# where kept keys must stay byte-for-byte unchanged.
|
|
160
149
|
#
|
|
161
|
-
# The certificate is resolved
|
|
162
|
-
#
|
|
163
|
-
#
|
|
164
|
-
#
|
|
165
|
-
# existing file, so `-o` is NOT forced here.
|
|
150
|
+
# The certificate is resolved exactly like {#seal}: an explicit `--cert` is
|
|
151
|
+
# passed through, otherwise kubeseal resolves it itself (env var, else fresh
|
|
152
|
+
# from the controller). The output format is inherited from the existing
|
|
153
|
+
# file, so `-o` is NOT forced here.
|
|
166
154
|
#
|
|
167
155
|
# @param manifest_yaml [String] Secret manifest with the items to add.
|
|
168
156
|
# @param file [String] path to the existing SealedSecret to merge into.
|
|
@@ -218,30 +206,12 @@ module RKSeal
|
|
|
218
206
|
ENV.fetch("SEALED_SECRETS_CERT", "")
|
|
219
207
|
end
|
|
220
208
|
|
|
221
|
-
#
|
|
222
|
-
#
|
|
223
|
-
#
|
|
209
|
+
# The cert file/URL to pass to `--cert`, or nil to let kubeseal resolve it
|
|
210
|
+
# itself. Only an explicit `--cert` is forwarded; with none configured we
|
|
211
|
+
# pass nil so kubeseal reads SEALED_SECRETS_CERT or fetches fresh from the
|
|
212
|
+
# controller (the env var is never passed as a path -- kubeseal reads it).
|
|
224
213
|
def resolved_cert_path
|
|
225
|
-
|
|
226
|
-
return nil unless env_cert.strip.empty?
|
|
227
|
-
|
|
228
|
-
resolve_cached_cert_path
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
# Return the path to a usable cached controller PEM, fetching and writing it
|
|
232
|
-
# first if absent (or if a refresh was requested). The cert is public, so the
|
|
233
|
-
# cache file is world-readable.
|
|
234
|
-
def cert_cache
|
|
235
|
-
@cert_cache ||= CertCache.new(
|
|
236
|
-
controller_namespace: @controller_namespace || DEFAULT_CONTROLLER_NAMESPACE,
|
|
237
|
-
controller_name: @controller_name || DEFAULT_CONTROLLER_NAME
|
|
238
|
-
)
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
def resolve_cached_cert_path
|
|
242
|
-
return cert_cache.path if !@refresh_cert && cert_cache.exist?
|
|
243
|
-
|
|
244
|
-
cert_cache.write(fetch_cert)
|
|
214
|
+
@cert
|
|
245
215
|
end
|
|
246
216
|
|
|
247
217
|
# Whether kubeseal's stderr from a failed `--validate` is a validity verdict
|
|
@@ -302,81 +272,5 @@ module RKSeal
|
|
|
302
272
|
def command_label(argv)
|
|
303
273
|
[@binary, *argv].join(" ")
|
|
304
274
|
end
|
|
305
|
-
|
|
306
|
-
# On-disk cache for the controller's PUBLIC certificate, so repeated seals do
|
|
307
|
-
# not each hit the cluster for `--fetch-cert`. The cert is public, hence the
|
|
308
|
-
# world-readable 0644 perms. One entry per controller identity, under the XDG
|
|
309
|
-
# cache dir:
|
|
310
|
-
# ${XDG_CACHE_HOME:-$HOME/.cache}/rkseal/<namespace>/<name>.pem
|
|
311
|
-
#
|
|
312
|
-
# The namespace is a path segment rather than a `<namespace>-<name>` prefix
|
|
313
|
-
# so two distinct identities can never collide on one file (e.g. `a-b`/`c`
|
|
314
|
-
# vs `a`/`b-c`); a DNS-1123 name contains no `/`, so the layout is
|
|
315
|
-
# unambiguous. Writes go through a temp file + atomic rename so a concurrent
|
|
316
|
-
# seal never reads a half-written cert.
|
|
317
|
-
#
|
|
318
|
-
# Defined inline (not a separate file) so this adapter stays self-contained
|
|
319
|
-
# and adds no new top-level require.
|
|
320
|
-
class CertCache
|
|
321
|
-
DIR_PERMS = 0o755
|
|
322
|
-
FILE_PERMS = 0o644
|
|
323
|
-
|
|
324
|
-
# @param controller_namespace [String]
|
|
325
|
-
# @param controller_name [String]
|
|
326
|
-
def initialize(controller_namespace:, controller_name:)
|
|
327
|
-
@controller_namespace = controller_namespace
|
|
328
|
-
@controller_name = controller_name
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
# @return [String] absolute path to this controller's cached PEM.
|
|
332
|
-
def path
|
|
333
|
-
File.join(cache_dir, @controller_namespace, "#{@controller_name}.pem")
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
# @return [Boolean] whether a cached PEM already exists.
|
|
337
|
-
def exist?
|
|
338
|
-
File.exist?(path)
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
# @return [String] the cached PEM contents.
|
|
342
|
-
def read
|
|
343
|
-
File.read(path)
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
# Persist a freshly fetched PEM (overwriting any existing entry) and return
|
|
347
|
-
# its path so the caller can hand it to `--cert`.
|
|
348
|
-
#
|
|
349
|
-
# @param pem [String] certificate contents.
|
|
350
|
-
# @return [String] the cache path that now holds the PEM.
|
|
351
|
-
def write(pem)
|
|
352
|
-
FileUtils.mkdir_p(File.dirname(path), mode: DIR_PERMS)
|
|
353
|
-
write_atomically(pem)
|
|
354
|
-
path
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
private
|
|
358
|
-
|
|
359
|
-
# Write the PEM to a uniquely-named temp file in the same directory, then
|
|
360
|
-
# rename it over the target. rename(2) is atomic within one filesystem, so
|
|
361
|
-
# a concurrent seal sees either the old cert or the new one -- never a
|
|
362
|
-
# half-written file. The temp file carries the final 0644 perms and is
|
|
363
|
-
# removed if the rename never happens (e.g. an error mid-write).
|
|
364
|
-
def write_atomically(pem)
|
|
365
|
-
tmp = File.join(File.dirname(path), ".#{File.basename(path)}.#{SecureRandom.hex(8)}.tmp")
|
|
366
|
-
File.write(tmp, pem)
|
|
367
|
-
File.chmod(FILE_PERMS, tmp)
|
|
368
|
-
File.rename(tmp, path)
|
|
369
|
-
ensure
|
|
370
|
-
File.unlink(tmp) if tmp && File.exist?(tmp)
|
|
371
|
-
end
|
|
372
|
-
|
|
373
|
-
# ${XDG_CACHE_HOME:-$HOME/.cache}/rkseal
|
|
374
|
-
def cache_dir
|
|
375
|
-
base = ENV.fetch("XDG_CACHE_HOME", nil)
|
|
376
|
-
base = File.join(Dir.home, ".cache") if base.nil? || base.strip.empty?
|
|
377
|
-
File.join(base, "rkseal")
|
|
378
|
-
end
|
|
379
|
-
end
|
|
380
275
|
end
|
|
381
|
-
# rubocop:enable Metrics/ClassLength
|
|
382
276
|
end
|
data/lib/rkseal/version.rb
CHANGED
data/rkseal.gemspec
CHANGED
|
@@ -48,6 +48,7 @@ Gem::Specification.new do |spec|
|
|
|
48
48
|
|
|
49
49
|
# Development dependencies. Versions are intentionally left as compatible ranges
|
|
50
50
|
# rather than hard pins until the toolchain is proven on Ruby 4.0.2.
|
|
51
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
51
52
|
spec.add_development_dependency "rspec", "~> 3.13"
|
|
52
53
|
spec.add_development_dependency "rubocop", "~> 1.60"
|
|
53
54
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rkseal
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Piotr Wojcieszonek
|
|
@@ -37,6 +37,20 @@ dependencies:
|
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '0.2'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rake
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '13.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '13.0'
|
|
40
54
|
- !ruby/object:Gem::Dependency
|
|
41
55
|
name: rspec
|
|
42
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -121,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
121
135
|
- !ruby/object:Gem::Version
|
|
122
136
|
version: '0'
|
|
123
137
|
requirements: []
|
|
124
|
-
rubygems_version: 4.0.
|
|
138
|
+
rubygems_version: 4.0.10
|
|
125
139
|
specification_version: 4
|
|
126
140
|
summary: Interactively create and edit Kubernetes SealedSecrets via $EDITOR.
|
|
127
141
|
test_files: []
|