sanctum 0.8.2 → 0.8.5.rc1
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/.gitignore +3 -3
- data/.gitlab-ci.yml +22 -0
- data/.rubocop.yml +39 -0
- data/Dockerfile +31 -0
- data/Gemfile.lock +47 -26
- data/README.md +11 -4
- data/docker-compose.override.yml_sample +11 -0
- data/docker-compose.test.yml +17 -0
- data/docker-compose.yml +19 -0
- data/lib/sanctum/cli.rb +9 -0
- data/lib/sanctum/command.rb +1 -0
- data/lib/sanctum/command/base.rb +56 -1
- data/lib/sanctum/command/check.rb +1 -1
- data/lib/sanctum/command/pull.rb +1 -1
- data/lib/sanctum/command/push.rb +13 -10
- data/lib/sanctum/command/sanctum.example.yaml +8 -5
- data/lib/sanctum/command/update.rb +96 -0
- data/lib/sanctum/get_config/options.rb +3 -3
- data/lib/sanctum/vault_secrets.rb +36 -12
- data/lib/sanctum/vault_transit.rb +8 -2
- data/lib/sanctum/version.rb +1 -1
- data/sanctum.gemspec +8 -6
- metadata +51 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7669c1c9dff3c31915cef379c1d95ce55a58e21a8c785f4b543d7a8b55dff42f
|
|
4
|
+
data.tar.gz: 9d87df11f2f28a3ae833271c6ea35329f82d4f08767765bc3383ef5ae66fccba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 144efff039e4dead3c2d14c7557aef22cde70972b9d2130ef7f94acc8dd1f7a28349382e51d81ca927d40d8e434d8a2cf1d366c52d0394a6a5246296151deef0
|
|
7
|
+
data.tar.gz: 216aedadda62921b7941b52aab144a57a3152dce5f23db1e5febe19d001c4af679c46f53c6c91b2d24b966ca27cb0eeb1a858b01fc56d6582755bcda9ae5fbf8
|
data/.gitignore
CHANGED
data/.gitlab-ci.yml
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
image:
|
|
3
|
+
name: docker/compose:1.23.2
|
|
4
|
+
entrypoint: ["/bin/sh", "-c"]
|
|
5
|
+
|
|
6
|
+
variables:
|
|
7
|
+
COMPOSE_FILE: 'docker-compose.test.yml'
|
|
8
|
+
|
|
9
|
+
stages:
|
|
10
|
+
- test
|
|
11
|
+
|
|
12
|
+
before_script:
|
|
13
|
+
- docker version
|
|
14
|
+
- docker info
|
|
15
|
+
- docker-compose version
|
|
16
|
+
|
|
17
|
+
testing:
|
|
18
|
+
stage: test
|
|
19
|
+
script:
|
|
20
|
+
- docker-compose build
|
|
21
|
+
- docker-compose run -T --rm sanctum ls -lart -hu
|
|
22
|
+
- docker-compose run -T --rm sanctum bundle exec rspec
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
require: rubocop-rspec
|
|
3
|
+
|
|
4
|
+
Rails:
|
|
5
|
+
Enabled: false
|
|
6
|
+
|
|
7
|
+
AllCops:
|
|
8
|
+
DefaultFormatter: progress
|
|
9
|
+
DisplayCopNames: true
|
|
10
|
+
Exclude: []
|
|
11
|
+
CacheRootDirectory: cache/
|
|
12
|
+
|
|
13
|
+
Bundler/OrderedGems:
|
|
14
|
+
Enabled: false
|
|
15
|
+
|
|
16
|
+
RSpec/ExampleLength:
|
|
17
|
+
Max: 25
|
|
18
|
+
|
|
19
|
+
Style/FormatString:
|
|
20
|
+
Enabled: false
|
|
21
|
+
|
|
22
|
+
Style/FormatStringToken:
|
|
23
|
+
Enabled: false
|
|
24
|
+
|
|
25
|
+
Style/StringLiterals:
|
|
26
|
+
EnforcedStyle: double_quotes
|
|
27
|
+
ConsistentQuotesInMultiline: true
|
|
28
|
+
|
|
29
|
+
Style/TrailingCommaInHashLiteral:
|
|
30
|
+
EnforcedStyleForMultiline: consistent_comma
|
|
31
|
+
|
|
32
|
+
Style/TrailingCommaInArrayLiteral:
|
|
33
|
+
EnforcedStyleForMultiline: consistent_comma
|
|
34
|
+
|
|
35
|
+
Style/TrailingUnderscoreVariable:
|
|
36
|
+
Enabled: false
|
|
37
|
+
|
|
38
|
+
Metrics/MethodLength:
|
|
39
|
+
Max: 25
|
data/Dockerfile
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
FROM ruby:2.5-alpine
|
|
2
|
+
|
|
3
|
+
USER root
|
|
4
|
+
|
|
5
|
+
ENV VERSION 1.0.2
|
|
6
|
+
ADD https://releases.hashicorp.com/vault/${VERSION}/vault_${VERSION}_linux_amd64.zip /tmp/
|
|
7
|
+
ADD https://releases.hashicorp.com/vault/${VERSION}/vault_${VERSION}_SHA256SUMS /tmp/
|
|
8
|
+
ADD https://releases.hashicorp.com/vault/${VERSION}/vault_${VERSION}_SHA256SUMS.sig /tmp/
|
|
9
|
+
|
|
10
|
+
# Install additional dependencies
|
|
11
|
+
# As well as nice to haves locally
|
|
12
|
+
RUN apk --no-cache add git vim busybox-extras curl gnupg build-base \
|
|
13
|
+
&& until gpg --keyserver hkp://p80.pool.sks-keyservers.net --recv-key 0x348FFC4C; do echo "Retry"; sleep 30; done \
|
|
14
|
+
&& gpg --verify /tmp/vault_${VERSION}_SHA256SUMS.sig \
|
|
15
|
+
&& cat /tmp/vault_${VERSION}_SHA256SUMS | grep linux_amd64 | sha256sum /tmp/vault_${VERSION}_linux_amd64.zip \
|
|
16
|
+
&& unzip /tmp/vault_${VERSION}_linux_amd64.zip \
|
|
17
|
+
&& mv vault /usr/local/bin/ \
|
|
18
|
+
&& rm -rf /tmp/*
|
|
19
|
+
|
|
20
|
+
# Setup up app directory
|
|
21
|
+
ENV APP_HOME /usr/src/app/
|
|
22
|
+
WORKDIR $APP_HOME
|
|
23
|
+
|
|
24
|
+
# Add app code
|
|
25
|
+
COPY . $APP_HOME
|
|
26
|
+
|
|
27
|
+
# Install gems
|
|
28
|
+
RUN bundle install --jobs=8
|
|
29
|
+
|
|
30
|
+
# Install sanctum gem
|
|
31
|
+
RUN bundle exec rake install
|
data/Gemfile.lock
CHANGED
|
@@ -1,49 +1,70 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
sanctum (0.8.
|
|
5
|
-
gli (~> 2)
|
|
6
|
-
hashdiff (~> 0)
|
|
7
|
-
vault (~> 0)
|
|
4
|
+
sanctum (0.8.5.rc1)
|
|
5
|
+
gli (~> 2.18)
|
|
6
|
+
hashdiff (~> 0.3)
|
|
7
|
+
vault (~> 0.12)
|
|
8
8
|
|
|
9
9
|
GEM
|
|
10
10
|
remote: https://rubygems.org/
|
|
11
11
|
specs:
|
|
12
|
-
|
|
12
|
+
ast (2.4.0)
|
|
13
|
+
aws-sigv4 (1.0.3)
|
|
13
14
|
coderay (1.1.2)
|
|
14
15
|
diff-lcs (1.3)
|
|
15
|
-
gli (2.
|
|
16
|
-
hashdiff (0.3.
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
gli (2.18.0)
|
|
17
|
+
hashdiff (0.3.8)
|
|
18
|
+
jaro_winkler (1.5.2)
|
|
19
|
+
method_source (0.9.2)
|
|
20
|
+
parallel (1.13.0)
|
|
21
|
+
parser (2.6.0.0)
|
|
22
|
+
ast (~> 2.4.0)
|
|
23
|
+
powerpack (0.1.2)
|
|
24
|
+
pry (0.12.2)
|
|
19
25
|
coderay (~> 1.1.0)
|
|
20
26
|
method_source (~> 0.9.0)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
rspec-
|
|
25
|
-
rspec-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
rainbow (3.0.0)
|
|
28
|
+
rake (12.3.2)
|
|
29
|
+
rspec (3.8.0)
|
|
30
|
+
rspec-core (~> 3.8.0)
|
|
31
|
+
rspec-expectations (~> 3.8.0)
|
|
32
|
+
rspec-mocks (~> 3.8.0)
|
|
33
|
+
rspec-core (3.8.0)
|
|
34
|
+
rspec-support (~> 3.8.0)
|
|
35
|
+
rspec-expectations (3.8.2)
|
|
29
36
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
30
|
-
rspec-support (~> 3.
|
|
31
|
-
rspec-mocks (3.
|
|
37
|
+
rspec-support (~> 3.8.0)
|
|
38
|
+
rspec-mocks (3.8.0)
|
|
32
39
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
33
|
-
rspec-support (~> 3.
|
|
34
|
-
rspec-support (3.
|
|
35
|
-
|
|
40
|
+
rspec-support (~> 3.8.0)
|
|
41
|
+
rspec-support (3.8.0)
|
|
42
|
+
rubocop (0.63.1)
|
|
43
|
+
jaro_winkler (~> 1.5.1)
|
|
44
|
+
parallel (~> 1.10)
|
|
45
|
+
parser (>= 2.5, != 2.5.1.1)
|
|
46
|
+
powerpack (~> 0.1)
|
|
47
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
48
|
+
ruby-progressbar (~> 1.7)
|
|
49
|
+
unicode-display_width (~> 1.4.0)
|
|
50
|
+
rubocop-rspec (1.32.0)
|
|
51
|
+
rubocop (>= 0.60.0)
|
|
52
|
+
ruby-progressbar (1.10.0)
|
|
53
|
+
unicode-display_width (1.4.1)
|
|
54
|
+
vault (0.12.0)
|
|
36
55
|
aws-sigv4
|
|
37
56
|
|
|
38
57
|
PLATFORMS
|
|
39
58
|
ruby
|
|
40
59
|
|
|
41
60
|
DEPENDENCIES
|
|
42
|
-
bundler (~> 1.
|
|
43
|
-
pry (~> 0)
|
|
44
|
-
rake (~>
|
|
61
|
+
bundler (~> 1.0)
|
|
62
|
+
pry (~> 0.12.0)
|
|
63
|
+
rake (~> 12.0)
|
|
45
64
|
rspec (~> 3.0)
|
|
65
|
+
rubocop (~> 0.63.0)
|
|
66
|
+
rubocop-rspec (~> 1.32.0)
|
|
46
67
|
sanctum!
|
|
47
68
|
|
|
48
69
|
BUNDLED WITH
|
|
49
|
-
1.
|
|
70
|
+
1.17.2
|
data/README.md
CHANGED
|
@@ -42,6 +42,7 @@ sanctum config - Generate an example config file.
|
|
|
42
42
|
sanctum create - Create an encrypted local file.
|
|
43
43
|
sanctum edit - Edit an encrypted local file.
|
|
44
44
|
sanctum view - View an encrypted local file.
|
|
45
|
+
sanctum update - Update secrets backend to v2 api.
|
|
45
46
|
```
|
|
46
47
|
|
|
47
48
|
|
|
@@ -80,9 +81,14 @@ The configuration file is a Hash represented in YAML format with three possible
|
|
|
80
81
|
* At lease one application/target definition is required.
|
|
81
82
|
|
|
82
83
|
## Roadmap
|
|
83
|
-
*
|
|
84
|
+
* <strike>Add vault v2 api support</strike>
|
|
85
|
+
* <strike>Add upgrade option for v2 api</strike>
|
|
86
|
+
* If transit key doesn't exist try to create it(automatically)
|
|
87
|
+
* If secrets mount doesn't exist try to create it(automatically)
|
|
88
|
+
* <strike>Better/more Tests</strike>
|
|
84
89
|
* Built in Backup features
|
|
85
90
|
* Performance optimizations
|
|
91
|
+
* Reorganize/cleanup code(add adapters, etc)
|
|
86
92
|
|
|
87
93
|
## Backup scenario.
|
|
88
94
|
One possible use case for sanctum is for backing up vault secrets. This feature is NOT built in yet.
|
|
@@ -111,10 +117,11 @@ This would allow you to be able to quickly decrypt local secrets in a disaster r
|
|
|
111
117
|
3. Restore the key to your locally running vault instance.
|
|
112
118
|
|
|
113
119
|
## Development
|
|
114
|
-
|
|
115
|
-
After checking out the repo, run `
|
|
120
|
+
Install [docker](https://docs.docker.com/install/) and [docker-compose](https://docs.docker.com/compose/install/)
|
|
121
|
+
After checking out the repo, run `docker-compose build`. To run tests run `docker-compose run --rm sanctum bundle exec rspec`.
|
|
116
122
|
|
|
117
|
-
To
|
|
123
|
+
To release a new version, `cp docker-compose.override.yml_sample docker-compose.override.yml` and add gem credentials. Update the version number in `version.rb`.
|
|
124
|
+
then run `docker-compose run --rm sanctum bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
118
125
|
|
|
119
126
|
## Contributing
|
|
120
127
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: '3.4'
|
|
3
|
+
|
|
4
|
+
services:
|
|
5
|
+
sanctum:
|
|
6
|
+
build:
|
|
7
|
+
context: "."
|
|
8
|
+
command: /bin/true
|
|
9
|
+
depends_on:
|
|
10
|
+
- vault
|
|
11
|
+
vault:
|
|
12
|
+
image: vault:1.0.2
|
|
13
|
+
environment:
|
|
14
|
+
SKIP_SETCAP: "true"
|
|
15
|
+
VAULT_DEV_ROOT_TOKEN_ID: "514c55f0-c452-99e3-55e0-8301b770b92c"
|
|
16
|
+
VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8200"
|
|
17
|
+
command: ["vault", "server", "-dev"]
|
data/docker-compose.yml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: '3.4'
|
|
3
|
+
|
|
4
|
+
services:
|
|
5
|
+
sanctum:
|
|
6
|
+
build:
|
|
7
|
+
context: "."
|
|
8
|
+
command: /bin/true
|
|
9
|
+
depends_on:
|
|
10
|
+
- vault
|
|
11
|
+
volumes:
|
|
12
|
+
- ".:/usr/src/app"
|
|
13
|
+
vault:
|
|
14
|
+
image: vault:1.0.2
|
|
15
|
+
environment:
|
|
16
|
+
SKIP_SETCAP: "true"
|
|
17
|
+
VAULT_DEV_ROOT_TOKEN_ID: "514c55f0-c452-99e3-55e0-8301b770b92c"
|
|
18
|
+
VAULT_DEV_LISTEN_ADDRESS: "0.0.0.0:8200"
|
|
19
|
+
command: ["vault", "server", "-dev"]
|
data/lib/sanctum/cli.rb
CHANGED
|
@@ -95,6 +95,15 @@ module Sanctum
|
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
desc 'Update secrets mount'
|
|
99
|
+
command :update do |c|
|
|
100
|
+
common_options c, :config, :force
|
|
101
|
+
c.flag [:targets, :t], desc: 'Comma seperated list of targets', required: true
|
|
102
|
+
c.action do
|
|
103
|
+
Command::Update.new(@options_hash).run
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
98
107
|
pre do |_,_,options,_|
|
|
99
108
|
@options_hash = GetConfig::ConfigMerge.new(config_file: options[:c], targets: options[:t], force: options[:force]).final_options
|
|
100
109
|
Colorizer.colorize = @options_hash[:sanctum][:color]
|
data/lib/sanctum/command.rb
CHANGED
data/lib/sanctum/command/base.rb
CHANGED
|
@@ -17,7 +17,8 @@ module Sanctum
|
|
|
17
17
|
@args = args
|
|
18
18
|
|
|
19
19
|
@transit_key = options.fetch(:vault).fetch(:transit_key)
|
|
20
|
-
|
|
20
|
+
# TODO: Fix, to much is happening to targets in this initializer!
|
|
21
|
+
@targets = update_prefix_or_path(set_secrets_version(options.fetch(:sync)))
|
|
21
22
|
@config_file = options.fetch(:config_file)
|
|
22
23
|
end
|
|
23
24
|
|
|
@@ -25,6 +26,60 @@ module Sanctum
|
|
|
25
26
|
@vault_client ||= VaultClient.build(options[:vault][:url], options[:vault][:token])
|
|
26
27
|
end
|
|
27
28
|
|
|
29
|
+
private
|
|
30
|
+
# TODO: Fix! This is a bit hacky, will update once vault-ruby gets updated with better support for v2 api
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Internal: gets information about mounts that the user has permissions on
|
|
34
|
+
# Returns: hash
|
|
35
|
+
def mounts_info
|
|
36
|
+
@mounts_info ||= vault_client.request(:get, "/v1/sys/internal/ui/mounts")
|
|
37
|
+
rescue Vault::HTTPClientError
|
|
38
|
+
warn red(
|
|
39
|
+
"Unable to gather info about mounts this maybe due to vault connectivity or permissions"\
|
|
40
|
+
"\nTo list info about mounts you have permissions to have following permissions added"\
|
|
41
|
+
"\npath \"sys/internal/ui/mounts\" { capabilities = [\"read\"] }"\
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Internal: automatically detect the api version of the secrets mount
|
|
47
|
+
# and adds :secrets_version to hash if it doesn't exist
|
|
48
|
+
#
|
|
49
|
+
# Parameter: is an array of hashes: [{}, {}]
|
|
50
|
+
# Returns array of hashes: [{:name=>"vault-test", :prefix=>"vault-test", :path=>"vault/vault-test", :secrets_version=>"2"},{}]
|
|
51
|
+
def set_secrets_version(targets)
|
|
52
|
+
mounts_hash = mounts_info
|
|
53
|
+
|
|
54
|
+
targets.each do |h|
|
|
55
|
+
next if h.key?(:secrets_version)
|
|
56
|
+
|
|
57
|
+
# If mount options is nil default to api version 1 otherwise use version value
|
|
58
|
+
if mounts_hash.dig(:data, :secret, "#{h[:prefix]}/".to_sym, :options).nil?
|
|
59
|
+
h[:secrets_version] = "1"
|
|
60
|
+
else
|
|
61
|
+
h[:secrets_version] = mounts_hash.dig(:data, :secret, "#{h[:prefix]}/".to_sym, :options, :version)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
rescue Vault::VaultError
|
|
65
|
+
warn red(
|
|
66
|
+
"Unable to automatically determine secrets_version. This maybe due to vault connectivity or permissions"\
|
|
67
|
+
"\nTry again, or you could explicitly add `secrets_version:` to your sanctum.yaml to bypass auto detect"
|
|
68
|
+
)
|
|
69
|
+
raise
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Internal, add /data to prefix or path if secrets_version == "2"
|
|
73
|
+
# Parameter is an array of hashes: [{}, {}]
|
|
74
|
+
# Returns array of hashes: [{:name=>"vault-test", :prefix=>"vault-test/data", :path=>"vault/vault-test/data", :secrets_version=>"2"},{}]
|
|
75
|
+
def update_prefix_or_path(targets)
|
|
76
|
+
targets.each do |h|
|
|
77
|
+
next unless h[:secrets_version] == "2"
|
|
78
|
+
|
|
79
|
+
h[:prefix] = h[:prefix].include?("/data") ? h[:prefix] : "#{h[:prefix]}/data"
|
|
80
|
+
h[:path] = h[:path].include?("/data") ? h[:path] : "#{h[:path]}/data"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
28
83
|
end
|
|
29
84
|
end
|
|
30
85
|
end
|
|
@@ -12,7 +12,7 @@ module Sanctum
|
|
|
12
12
|
local_secrets = VaultTransit.decrypt(vault_client, local_secrets, transit_key)
|
|
13
13
|
|
|
14
14
|
# Recursively get vault secrets for each prefix specified in sanctum.yaml
|
|
15
|
-
secrets_list = VaultSecrets.new(vault_client, target[:prefix]).
|
|
15
|
+
secrets_list = VaultSecrets.new(vault_client, target[:prefix], target[:secrets_version]).get_all
|
|
16
16
|
|
|
17
17
|
# Only one entry in this hash (which will be the target).
|
|
18
18
|
tree = secrets_list.values.first
|
data/lib/sanctum/command/pull.rb
CHANGED
|
@@ -14,7 +14,7 @@ module Sanctum
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
# Recursively get vault secrets for each prefix specified in sanctum.yaml
|
|
17
|
-
secrets_list = VaultSecrets.new(vault_client, target[:prefix]).
|
|
17
|
+
secrets_list = VaultSecrets.new(vault_client, target[:prefix], target[:secrets_version]).get_all
|
|
18
18
|
secrets_list.each do |k,v|
|
|
19
19
|
|
|
20
20
|
vault_secrets = build_vault_secrets(v, [target[:path]])
|
data/lib/sanctum/command/push.rb
CHANGED
|
@@ -14,14 +14,14 @@ module Sanctum
|
|
|
14
14
|
force = target.fetch(:force) {options[:sanctum][:force]}
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
# Build array of local paths by recursively searching for local files for each
|
|
17
|
+
# Build array of local paths by recursively searching for local files for each path specified in sanctum.yaml
|
|
18
18
|
local_paths = get_local_paths(File.join(File.dirname(config_file), target[:path]))
|
|
19
19
|
|
|
20
20
|
local_secrets = build_local_secrets(local_paths)
|
|
21
|
-
vault_secrets = build_vault_secrets(local_paths, target[:prefix], target[:path])
|
|
21
|
+
vault_secrets = build_vault_secrets(local_paths, target[:prefix], target[:path], target[:secrets_version])
|
|
22
22
|
|
|
23
23
|
# Compare secrets
|
|
24
|
-
# vault_secrets
|
|
24
|
+
# vault_secrets prefix have been mapped to local_paths to make comparison easier
|
|
25
25
|
differences = compare_secrets(vault_secrets, local_secrets, target[:name], "push")
|
|
26
26
|
next if differences.nil?
|
|
27
27
|
|
|
@@ -36,21 +36,24 @@ module Sanctum
|
|
|
36
36
|
|
|
37
37
|
if force
|
|
38
38
|
warn red("#{target[:name]}: Forcefully writing differences to vault(push)")
|
|
39
|
-
VaultTransit.write_to_vault(vault_client, vault_secrets)
|
|
39
|
+
VaultTransit.write_to_vault(vault_client, vault_secrets, target[:secrets_version])
|
|
40
40
|
else
|
|
41
41
|
#Confirm with user, and write to local file if approved
|
|
42
42
|
next unless confirmed_with_user?
|
|
43
|
-
VaultTransit.write_to_vault(vault_client, vault_secrets)
|
|
43
|
+
VaultTransit.write_to_vault(vault_client, vault_secrets, target[:secrets_version])
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
# Right now this duplicates a bit of logic that already exists in
|
|
49
|
+
# VaultSecrets client.
|
|
50
|
+
# TODO: remove this method once code is rearranged
|
|
51
|
+
def read_remote(paths, prefix, secrets_version)
|
|
49
52
|
tmp_hash = Hash.new
|
|
50
53
|
paths.each do |k,v|
|
|
51
54
|
p = File.join(prefix, k)
|
|
52
55
|
unless vault_client.logical.read(p).nil?
|
|
53
|
-
v = vault_client.logical.read(p).data
|
|
56
|
+
v = secrets_version == "2" ? vault_client.logical.read(p).data[:data] : vault_client.logical.read(p).data
|
|
54
57
|
tmp_hash["#{k}"] = v
|
|
55
58
|
else
|
|
56
59
|
next
|
|
@@ -77,7 +80,7 @@ module Sanctum
|
|
|
77
80
|
local_secrets = VaultTransit.decrypt(vault_client, local_secrets, transit_key)
|
|
78
81
|
end
|
|
79
82
|
|
|
80
|
-
def build_vault_secrets(local_paths, target_prefix, target_path)
|
|
83
|
+
def build_vault_secrets(local_paths, target_prefix, target_path, secrets_version)
|
|
81
84
|
# Map local_paths into vault_paths
|
|
82
85
|
vault_paths = local_paths.map{|x| x.gsub(File.join(File.dirname(config_file), target_path), "")}
|
|
83
86
|
|
|
@@ -86,9 +89,9 @@ module Sanctum
|
|
|
86
89
|
# We will not for example, see differences if a secret exists in vault but not locally.
|
|
87
90
|
|
|
88
91
|
# Read secrets from vault
|
|
89
|
-
vault_secrets = read_remote(vault_paths, target_prefix)
|
|
92
|
+
vault_secrets = read_remote(vault_paths, target_prefix, secrets_version)
|
|
90
93
|
|
|
91
|
-
# To make comparing a bit easier map vault_secrets
|
|
94
|
+
# To make comparing a bit easier map vault_secrets prefixs back local_paths
|
|
92
95
|
# Convert to json, then read, to make keys strings vs symbols
|
|
93
96
|
vault_secrets = JSON(map_local_path(vault_secrets, target_path).to_json)
|
|
94
97
|
end
|
|
@@ -18,15 +18,18 @@ vault:
|
|
|
18
18
|
|
|
19
19
|
sync:
|
|
20
20
|
# sync is an array of hashes of sync target configurations
|
|
21
|
-
# at least one app definition is REQUIRED
|
|
21
|
+
# at least one app definition is REQUIRED
|
|
22
|
+
# Fields:
|
|
22
23
|
# name - (required) Friendly name of the sync target.
|
|
23
24
|
# prefix - (required) The vault prefix(secret mount) to synchronize to.
|
|
24
|
-
# path - (required) The relative filesystem path
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
# the configuration file.
|
|
25
|
+
# path - (required) The relative filesystem path that gets synchronized
|
|
26
|
+
# with Vault. This path is calculated relative to the directory containing
|
|
27
|
+
# the sanctum configuration file.
|
|
28
28
|
# force - Whether or not to force push, pull actions (no user input)
|
|
29
29
|
# This inherits the setting from the `sanctum` section.
|
|
30
|
+
# secrets_version - The k/v secrets version `1`, or `2`. Sanctum will try to detect this automatically
|
|
31
|
+
# if not valued. This does not apply to `generic` secrets backend.
|
|
32
|
+
# see https://www.vaultproject.io/docs/secrets/kv/index.html
|
|
30
33
|
#- name: app-foo
|
|
31
34
|
#prefix: secrets/app-foo
|
|
32
35
|
#path: vault/app-foo
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require "pathname"
|
|
2
|
+
|
|
3
|
+
module Sanctum
|
|
4
|
+
module Command
|
|
5
|
+
class Update < Base
|
|
6
|
+
def run
|
|
7
|
+
targets.each do |target|
|
|
8
|
+
# Use command line if force: true
|
|
9
|
+
if options[:cli][:force]
|
|
10
|
+
force = options[:cli][:force]
|
|
11
|
+
else
|
|
12
|
+
force = target.fetch(:force) {options[:sanctum][:force]}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
update_mount(target, force)
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def update_mount(target, force)
|
|
23
|
+
data = { options: { version: "2" }, listing_visability: "unauth" }.to_json
|
|
24
|
+
pre_upgrade_warning
|
|
25
|
+
|
|
26
|
+
if force
|
|
27
|
+
warn yellow("\nUpgrading #{target[:prefix]}")
|
|
28
|
+
upgrade_response = vault_client.request(:post, "/v1/sys/mounts/#{target[:prefix]}/tune", data)
|
|
29
|
+
upgrade_response.nil? ? nothing_happened_warning : (warn yellow("#{upgrade_response}"))
|
|
30
|
+
else
|
|
31
|
+
already_upgraded_warning if target[:secrets_version] == "2"
|
|
32
|
+
warn yellow("#{vault_client.request(:post, "/v1/sys/mounts/#{target[:prefix]}/tune", data)}") if confirm_upgrade?(target)
|
|
33
|
+
end
|
|
34
|
+
post_upgrade_warning(target)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def pre_upgrade_warning
|
|
38
|
+
warn yellow(
|
|
39
|
+
"\nPlease read 'Upgrading from Version 1' documentation BEFORE you upgrade"\
|
|
40
|
+
"\nThe addition of `/data`, and `/metadata` endpoints will break applications that are depending on v1 endpoints"\
|
|
41
|
+
"\nYou will want to update permissions policies, and applications BEFORE you upgrade"\
|
|
42
|
+
"\nhttps://www.vaultproject.io/docs/secrets/kv/kv-v2.html#upgrading-from-version-1"\
|
|
43
|
+
)
|
|
44
|
+
additional_acl_warning
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def post_upgrade_warning(target)
|
|
48
|
+
warn yellow(
|
|
49
|
+
"\nOnce the upgrade has been completed, make sure you update your sanctum.yaml."\
|
|
50
|
+
"\nPlease add the `secrets_version: 2` key to the #{target[:prefix]} config."
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def additional_acl_warning
|
|
55
|
+
warn yellow(
|
|
56
|
+
"\nIf you use policies to limit secrets access you may need to have your permissions updated"\
|
|
57
|
+
"\nSee https://www.vaultproject.io/docs/secrets/kv/kv-v2.html#acl-rules for more info"\
|
|
58
|
+
"\nSpecifically you may need add something similar to the following:"\
|
|
59
|
+
"\npath \"<secrets_mount>/data/*\" { capabilities = [\"list\",\"read\",\"create\",\"update\",\"delete\"] }"\
|
|
60
|
+
"\npath \"<secrets_mount>/metadata/*\" { capabilities = [\"list\",\"read\",\"create\",\"update\",\"delete\"] }"\
|
|
61
|
+
"\npath \"<secrets_mount>/destroy/*\" { capabilities = [\"update\"] }"\
|
|
62
|
+
"\npath \"<secrets_mount>/delete/*\" { capabilities = [\"update\"] }"\
|
|
63
|
+
"\npath \"<secrets_mount>/undelete/*\" { capabilities = [\"update\"] }"
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def already_upgraded_warning
|
|
68
|
+
raise red(
|
|
69
|
+
"Mount appears to have already been updated. This could be due to `secrets_version: 2` specified"\
|
|
70
|
+
"\nin sanctum.yaml, or the mount having already been upgraded."\
|
|
71
|
+
"\nTo try anyway you can pass `--force` on the command line"
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def nothing_happened_warning
|
|
76
|
+
warn yellow(
|
|
77
|
+
"Request was successfull but returned a nil response, this generally means the mount has is already upgraded!"
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def confirm_upgrade?(target)
|
|
82
|
+
warn yellow("\nUpgrading will make the mount temporarily unavailable")
|
|
83
|
+
warn yellow("Would you like to continue?: ")
|
|
84
|
+
question = STDIN.gets.chomp.upcase
|
|
85
|
+
|
|
86
|
+
if ["Y", "YES"].include? question
|
|
87
|
+
warn yellow("\nUpgrading #{target[:prefix]}")
|
|
88
|
+
true
|
|
89
|
+
else
|
|
90
|
+
warn yellow("\nSkipping....\n")
|
|
91
|
+
false
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -6,15 +6,15 @@ module Sanctum
|
|
|
6
6
|
class DefaultOptions
|
|
7
7
|
attr_reader :config_file
|
|
8
8
|
|
|
9
|
-
def initialize(config_file=nil)
|
|
9
|
+
def initialize(config_file = nil)
|
|
10
10
|
@config_file = config_file
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def run
|
|
14
14
|
{
|
|
15
15
|
config_file: config_file.nil? ? config_file_search : config_file,
|
|
16
|
-
sanctum: {
|
|
17
|
-
vault: { url: "https://127.0.0.1:8200"
|
|
16
|
+
sanctum: { color: true, force: false },
|
|
17
|
+
vault: { token: get_vault_token, url: "https://127.0.0.1:8200" },
|
|
18
18
|
}
|
|
19
19
|
end
|
|
20
20
|
|
|
@@ -1,26 +1,39 @@
|
|
|
1
1
|
module Sanctum
|
|
2
2
|
class VaultSecrets
|
|
3
3
|
include Colorizer
|
|
4
|
-
attr_reader :vault_client, :prefix
|
|
4
|
+
attr_reader :vault_client, :prefix, :secrets_version
|
|
5
5
|
|
|
6
|
-
def initialize(vault_client, prefix)
|
|
6
|
+
def initialize(vault_client, prefix, secrets_version="1")
|
|
7
7
|
@vault_client = vault_client
|
|
8
8
|
@prefix = prefix
|
|
9
|
+
@secrets_version = secrets_version
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
# API version 2 uses /metadata path to list, but /data to read.
|
|
13
|
+
#TODO Fix, change list_prefix back to prefix at some point. Use new kv from vault-ruby once it's updated
|
|
14
|
+
def get_all
|
|
15
|
+
raise yellow("Warning: Vault prefix: '#{prefix}' does not exist.. ") if invalid_prefix?
|
|
15
16
|
|
|
16
17
|
secrets_from_vault = Hash.new
|
|
17
|
-
secrets_from_vault[prefix] = JSON(list_recursive(
|
|
18
|
+
secrets_from_vault[prefix] = JSON(list_recursive(list_prefix).to_json)
|
|
18
19
|
secrets_from_vault
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
private
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
# API version 2 uses /metadata path to list, but /data to read.
|
|
25
|
+
# TODO remove method and use kv from vault-ruby once available.
|
|
26
|
+
def list_prefix
|
|
27
|
+
if secrets_version == "2"
|
|
28
|
+
prefix.include?("/data") ? prefix.sub(/data/, "metadata") : "#{prefix}/metadata"
|
|
29
|
+
else
|
|
30
|
+
prefix
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# TODO Fix, change list_prefix back to prefix at some point. Use new kv from vault-ruby once it's updated
|
|
35
|
+
def list_recursive(list_prefix, parent = '')
|
|
36
|
+
me = File.join(parent, list_prefix)
|
|
24
37
|
result = vault_client.logical.list(me).inject({}) do |hash, item|
|
|
25
38
|
case item
|
|
26
39
|
when /.*\/$/
|
|
@@ -33,14 +46,25 @@ module Sanctum
|
|
|
33
46
|
result
|
|
34
47
|
end
|
|
35
48
|
|
|
49
|
+
# Used by list_recursive method only
|
|
50
|
+
# API version 2 uses /metadata path to list, but /data to read.
|
|
51
|
+
# TODO Update to use kv from vault-ruby once available.
|
|
36
52
|
def read_data(item, parent = '')
|
|
37
53
|
me = File.join(parent, item)
|
|
38
|
-
|
|
54
|
+
|
|
55
|
+
# me will contain /metadata if secrets_version 2 due to list_prefix method
|
|
56
|
+
if secrets_version == "2"
|
|
57
|
+
me = me.sub(/metadata/, "data")
|
|
58
|
+
vault_client.logical.read(me).data[:data]
|
|
59
|
+
else
|
|
60
|
+
vault_client.logical.read(me).data
|
|
61
|
+
end
|
|
39
62
|
end
|
|
40
63
|
|
|
64
|
+
# API version 2 uses /metadata path to list, but /data to read.
|
|
65
|
+
# TODO Fix, change list_prefix back to prefix at some point. Use new kv from vault-ruby once it's updated
|
|
41
66
|
def invalid_prefix?
|
|
42
|
-
vault_client.logical.list(
|
|
67
|
+
vault_client.logical.list(list_prefix).empty?
|
|
43
68
|
end
|
|
44
|
-
|
|
45
69
|
end
|
|
46
70
|
end
|
|
@@ -34,13 +34,14 @@ module Sanctum
|
|
|
34
34
|
def self.write_to_file(vault_client, secrets, transit_key)
|
|
35
35
|
secrets = encrypt(vault_client, secrets, transit_key)
|
|
36
36
|
secrets.each do |k, v|
|
|
37
|
+
create_path(k)
|
|
37
38
|
File.write(k, v.data[:ciphertext])
|
|
38
39
|
end
|
|
39
40
|
end
|
|
40
41
|
|
|
41
|
-
def self.write_to_vault(vault_client, secrets)
|
|
42
|
+
def self.write_to_vault(vault_client, secrets, secrets_version="1")
|
|
42
43
|
secrets.each do |k, v|
|
|
43
|
-
vault_client.logical.write(k, v)
|
|
44
|
+
secrets_version == "2" ? vault_client.logical.write(k, data: v) : vault_client.logical.write(k, v)
|
|
44
45
|
end
|
|
45
46
|
end
|
|
46
47
|
|
|
@@ -56,5 +57,10 @@ module Sanctum
|
|
|
56
57
|
!vault_client.logical.read(transit_key.to_path).nil?
|
|
57
58
|
end
|
|
58
59
|
|
|
60
|
+
def self.create_path(path)
|
|
61
|
+
path = Pathname.new(path).parent.to_path
|
|
62
|
+
FileUtils.mkdir_p(path) unless File.directory?(path)
|
|
63
|
+
end
|
|
64
|
+
|
|
59
65
|
end
|
|
60
66
|
end
|
data/lib/sanctum/version.rb
CHANGED
data/sanctum.gemspec
CHANGED
|
@@ -23,12 +23,14 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
spec.executables = "sanctum"
|
|
24
24
|
spec.require_paths = ["lib"]
|
|
25
25
|
|
|
26
|
-
spec.add_dependency 'vault', '~> 0'
|
|
27
|
-
spec.add_dependency 'hashdiff', '~> 0'
|
|
28
|
-
spec.add_dependency 'gli', '~> 2'
|
|
26
|
+
spec.add_dependency 'vault', '~> 0.12'
|
|
27
|
+
spec.add_dependency 'hashdiff', '~> 0.3'
|
|
28
|
+
spec.add_dependency 'gli', '~> 2.18'
|
|
29
29
|
|
|
30
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
|
31
|
-
spec.add_development_dependency 'pry', '~> 0'
|
|
32
|
-
spec.add_development_dependency 'rake', '~>
|
|
30
|
+
spec.add_development_dependency 'bundler', '~> 1.0'
|
|
31
|
+
spec.add_development_dependency 'pry', '~> 0.12.0'
|
|
32
|
+
spec.add_development_dependency 'rake', '~> 12.0'
|
|
33
33
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
34
|
+
spec.add_development_dependency 'rubocop', '~> 0.63.0'
|
|
35
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 1.32.0'
|
|
34
36
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sanctum
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.5.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Corban Raun
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2019-02-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: vault
|
|
@@ -16,84 +16,84 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0'
|
|
19
|
+
version: '0.12'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0'
|
|
26
|
+
version: '0.12'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: hashdiff
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
33
|
+
version: '0.3'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
40
|
+
version: '0.3'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: gli
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '2'
|
|
47
|
+
version: '2.18'
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '2'
|
|
54
|
+
version: '2.18'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: bundler
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '1.
|
|
61
|
+
version: '1.0'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '1.
|
|
68
|
+
version: '1.0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: pry
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version:
|
|
75
|
+
version: 0.12.0
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
82
|
+
version: 0.12.0
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
84
|
name: rake
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
87
|
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
89
|
+
version: '12.0'
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
96
|
+
version: '12.0'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: rspec
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,6 +108,34 @@ dependencies:
|
|
|
108
108
|
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
110
|
version: '3.0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rubocop
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: 0.63.0
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: 0.63.0
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rubocop-rspec
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: 1.32.0
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: 1.32.0
|
|
111
139
|
description: Syncs encrypted content from the filesystem to the Vault secrets store.
|
|
112
140
|
email:
|
|
113
141
|
- corban@raunco.co
|
|
@@ -117,7 +145,10 @@ extensions: []
|
|
|
117
145
|
extra_rdoc_files: []
|
|
118
146
|
files:
|
|
119
147
|
- ".gitignore"
|
|
148
|
+
- ".gitlab-ci.yml"
|
|
120
149
|
- ".rspec"
|
|
150
|
+
- ".rubocop.yml"
|
|
151
|
+
- Dockerfile
|
|
121
152
|
- Gemfile
|
|
122
153
|
- Gemfile.lock
|
|
123
154
|
- LICENSE.txt
|
|
@@ -126,6 +157,9 @@ files:
|
|
|
126
157
|
- bin/console
|
|
127
158
|
- bin/sanctum
|
|
128
159
|
- bin/setup
|
|
160
|
+
- docker-compose.override.yml_sample
|
|
161
|
+
- docker-compose.test.yml
|
|
162
|
+
- docker-compose.yml
|
|
129
163
|
- lib/sanctum.rb
|
|
130
164
|
- lib/sanctum/cli.rb
|
|
131
165
|
- lib/sanctum/colorize_string.rb
|
|
@@ -141,6 +175,7 @@ files:
|
|
|
141
175
|
- lib/sanctum/command/pull.rb
|
|
142
176
|
- lib/sanctum/command/push.rb
|
|
143
177
|
- lib/sanctum/command/sanctum.example.yaml
|
|
178
|
+
- lib/sanctum/command/update.rb
|
|
144
179
|
- lib/sanctum/command/view.rb
|
|
145
180
|
- lib/sanctum/get_config.rb
|
|
146
181
|
- lib/sanctum/get_config/config_file.rb
|
|
@@ -169,9 +204,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
169
204
|
version: 2.5.0
|
|
170
205
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
171
206
|
requirements:
|
|
172
|
-
- - "
|
|
207
|
+
- - ">"
|
|
173
208
|
- !ruby/object:Gem::Version
|
|
174
|
-
version:
|
|
209
|
+
version: 1.3.1
|
|
175
210
|
requirements: []
|
|
176
211
|
rubyforge_project:
|
|
177
212
|
rubygems_version: 2.7.6
|