envault 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.travis.yml +16 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +4 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +20 -0
- data/README.md +180 -0
- data/Rakefile +25 -0
- data/bin/envault +6 -0
- data/envault.gemspec +33 -0
- data/lib/envault.rb +22 -0
- data/lib/envault/cli.rb +126 -0
- data/lib/envault/constants.rb +7 -0
- data/lib/envault/core.rb +118 -0
- data/lib/envault/environment.rb +7 -0
- data/lib/envault/formatter.rb +15 -0
- data/lib/envault/version.rb +4 -0
- data/spec/cli_spec.rb +39 -0
- data/spec/config/envault.yml +35 -0
- data/spec/core_spec.rb +145 -0
- data/spec/envault_spec.rb +8 -0
- data/spec/formatter_spec.rb +15 -0
- data/spec/spec_helper.rb +29 -0
- metadata +221 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: af2de945195b941624c2f5e2a992f3d8eea9eb80
|
4
|
+
data.tar.gz: 22faf369eead70da1d5e4bddf896b13df3318030
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dcd47c0296c6c41ba87c8a4e4d1b51bd3da4fa4be65dd5c0f17d34738b26d9472a27b586a33656c3402d6225e916376d133d6ebddc7be8e61ca7adf1e2ab1692
|
7
|
+
data.tar.gz: b186a443ff600835a0e04460c682ab4ff35d8602cc4b155eaa2bce7a961d72fa08dc4052244887db39029913d4088292ffa42c430db9bb55408ef894d0aeeccc
|
data/.document
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour --format documentation
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown --title "envault Documentation" --protected
|
data/ChangeLog.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2016 toyama0919
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
# envault [![Build Status](https://secure.travis-ci.org/toyama0919/envault.png?branch=master)](http://travis-ci.org/toyama0919/envault)
|
2
|
+
|
3
|
+
Encrypt secret information environment variables by yaml.
|
4
|
+
|
5
|
+
## Settings(Environment Variables)
|
6
|
+
```
|
7
|
+
export ENVAULT_PASSPHRASE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
8
|
+
export ENVAULT_SIGN_PASSPHRASE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
9
|
+
export ENVAULT_SALT=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
10
|
+
```
|
11
|
+
|
12
|
+
## Settings(yaml file)
|
13
|
+
```
|
14
|
+
development:
|
15
|
+
passphrase: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
|
16
|
+
sign_passphrase: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
|
17
|
+
salt: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
|
18
|
+
prefix: ENVAULT_
|
19
|
+
|
20
|
+
staging:
|
21
|
+
passphrase: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
22
|
+
sign_passphrase: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
23
|
+
salt: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
24
|
+
prefix: ENVAULT_
|
25
|
+
|
26
|
+
production:
|
27
|
+
passphrase: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
|
28
|
+
sign_passphrase: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
|
29
|
+
salt: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
|
30
|
+
prefix: ENVAULT_
|
31
|
+
```
|
32
|
+
|
33
|
+
## Encrypt and Decrypt
|
34
|
+
```bash
|
35
|
+
$ cat .env
|
36
|
+
USERNAME_A: hogehoge
|
37
|
+
USERNAME_B: fugafuga
|
38
|
+
USERNAME_C: mogomogo
|
39
|
+
PASSWORD_A: hogehoge
|
40
|
+
PASSWORD_B: fugafuga
|
41
|
+
PASSWORD_C: mogomogo
|
42
|
+
API_KEY_A: hogehoge
|
43
|
+
API_KEY_B: fugafuga
|
44
|
+
API_KEY_C: mogomogo
|
45
|
+
|
46
|
+
## encrypt file
|
47
|
+
$ envault -e -s .env -c envault.yml --profile staging -k '^PASSWORD_.*' '^API_KEY_.*' > .env.encrypt
|
48
|
+
$ cat .env.encrypt
|
49
|
+
USERNAME_A: "hogehoge"
|
50
|
+
USERNAME_B: "fugafuga"
|
51
|
+
USERNAME_C: "mogomogo"
|
52
|
+
ENVAULT_PASSWORD_A: "VmI4TkcwYXFRdnp3cTNINFo5NHZNWWtUakd4WE9iWDhJdFIzVnQydXlMaz0tLU5CS2JONW1FalorMGxsOGxUYmpXUFE9PQ==--3e301c251f5a7cf0e6280daa3bc14cc04c2cbff492758028c9e5fd6ddc72660e"
|
53
|
+
ENVAULT_PASSWORD_B: "QzI1eFZnampSZkk3QWxEYkZjemNlMVpmWWVEVFluZjhJV01zS3JKNUlvST0tLUNvWDdNWVFGMUMwVGEvaTNFMkJVU2c9PQ==--d58c39f5e71b382f2d2778e8c02c58339ed330e0dc31067ed6544fcb94397700"
|
54
|
+
ENVAULT_PASSWORD_C: "eGo0S3pLRWV0OFRrdVRzTmwvZlR3VkN6a2xjeHpvcHV0ZlZMenNOUm1Wbz0tLS80WjFuRzQrQ29uSU5SbDBSOGUyRlE9PQ==--7c2342c9533b70af50be5cf1dd12aa66f595263ea4c8aa347b185a7a8e57fb3c"
|
55
|
+
ENVAULT_API_KEY_A: "QThLSGF4VXNST3ZXL0VTVURzMlQ3aUE2aXppTlc5aUxUWk9Xa0hXS25NYz0tLTAxWlI0OU0zdnZXUG1MdmtYY2FZK0E9PQ==--fff50bafac593d6c50da369f1e040e0f6db8623299078ccda029bbeed12a93c7"
|
56
|
+
ENVAULT_API_KEY_B: "cWdFS21HdnArNlBzcFhremhFNTJzdzhtYkNwWUIrb2dzekFsbzZxQjRsQT0tLWZUZTdpYW1Bc2xqRXcvMjB4eDRNc1E9PQ==--edb6d0bace9f1cd4c9eeef0a9289d43fd6724625e601aa46e9ebb12f6405efb6"
|
57
|
+
ENVAULT_API_KEY_C: "YllDcDhYUTJGZWhTRjBaQTU4L3RlZitzYVN3OTV6OXhSbkZHbFBWaWF3cz0tLVo1MGFZVkNWQ3g2UXdwRlBFaW43MWc9PQ==--fd0642530754f235856f9ebba252bb34156666498433e05c2ce29573aad6ec69"
|
58
|
+
|
59
|
+
## decrypt file
|
60
|
+
$ envault -d -s .env.encrypt -c envault.yml --profile staging
|
61
|
+
USERNAME_A: "hogehoge"
|
62
|
+
USERNAME_B: "fugafuga"
|
63
|
+
USERNAME_C: "mogomogo"
|
64
|
+
PASSWORD_A: "hogehoge"
|
65
|
+
PASSWORD_B: "fugafuga"
|
66
|
+
PASSWORD_C: "mogomogo"
|
67
|
+
API_KEY_A: "hogehoge"
|
68
|
+
API_KEY_B: "fugafuga"
|
69
|
+
API_KEY_C: "mogomogo"
|
70
|
+
|
71
|
+
## if use other profile, Error
|
72
|
+
$ envault -d -s .env.encrypt -c envault.yml --profile production 1 ↵
|
73
|
+
/Users/toyama-h/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5/lib/active_support/message_verifier.rb:49:in `verify': ActiveSupport::MessageVerifier::InvalidSignature (ActiveSupport::MessageVerifier::InvalidSignature)
|
74
|
+
from /Users/toyama-h/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5/lib/active_support/message_encryptor.rb:64:in `decrypt_and_verify'
|
75
|
+
from /Users/toyama-h/Dropbox/github/envault/lib/envault/core.rb:51:in `block in decrypt_process'
|
76
|
+
from /Users/toyama-h/Dropbox/github/envault/lib/envault/core.rb:49:in `each'
|
77
|
+
from /Users/toyama-h/Dropbox/github/envault/lib/envault/core.rb:49:in `map'
|
78
|
+
from /Users/toyama-h/Dropbox/github/envault/lib/envault/core.rb:49:in `decrypt_process'
|
79
|
+
from /Users/toyama-h/Dropbox/github/envault/lib/envault/core.rb:44:in `decrypt_yaml'
|
80
|
+
from /Users/toyama-h/Dropbox/github/envault/lib/envault/cli.rb:74:in `block in decrypt_file'
|
81
|
+
from /Users/toyama-h/Dropbox/github/envault/lib/envault/cli.rb:73:in `each'
|
82
|
+
from /Users/toyama-h/Dropbox/github/envault/lib/envault/cli.rb:73:in `decrypt_file'
|
83
|
+
from /Users/toyama-h/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
|
84
|
+
from /Users/toyama-h/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
|
85
|
+
from /Users/toyama-h/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
|
86
|
+
from /Users/toyama-h/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
|
87
|
+
from /Users/toyama-h/Dropbox/github/envault/bin/envault:6:in `<top (required)>'
|
88
|
+
from /Users/toyama-h/bin/envault:17:in `load'
|
89
|
+
from /Users/toyama-h/bin/envault:17:in `<main>'
|
90
|
+
```
|
91
|
+
|
92
|
+
## reencrypt(config)
|
93
|
+
```bash
|
94
|
+
$ cat .envault.test
|
95
|
+
old_staging:
|
96
|
+
passphrase: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
|
97
|
+
sign_passphrase: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
|
98
|
+
salt: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
|
99
|
+
prefix: OLD_ENVAULT_
|
100
|
+
|
101
|
+
staging:
|
102
|
+
passphrase: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
103
|
+
sign_passphrase: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
104
|
+
salt: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
105
|
+
prefix: ENVAULT_
|
106
|
+
|
107
|
+
$ cat .env.encrypt
|
108
|
+
OLD_ENVAULT_A: "aaaaaaaaaaaaaa"
|
109
|
+
OLD_ENVAULT_B: "bbbbbbbbbbbbbbb"
|
110
|
+
C: "hoge"
|
111
|
+
|
112
|
+
$ envault reencrypt_file -s .env.encrypt -c ~/.envault --from_profile old_staging --to_profile staging --overwrite
|
113
|
+
|
114
|
+
$ cat .env.encrypt
|
115
|
+
ENVAULT_A: "ccccccccccccccc"
|
116
|
+
ENVAULT_B: "ddddddddddddddd"
|
117
|
+
C: "hoge"
|
118
|
+
|
119
|
+
```
|
120
|
+
|
121
|
+
## Load AND command(Environment Variables)
|
122
|
+
```bash
|
123
|
+
$ envault load -s .env.encrypt --command 'echo $PASSWORD_A'
|
124
|
+
hogehoge
|
125
|
+
```
|
126
|
+
|
127
|
+
## Load Application(Environment Variables)
|
128
|
+
```bash
|
129
|
+
require 'envault'
|
130
|
+
Envault.load('.env.encrypt')
|
131
|
+
p ENV['PASSWORD_A']
|
132
|
+
#=> hogehoge
|
133
|
+
```
|
134
|
+
|
135
|
+
## Load Application(Profile)
|
136
|
+
```bash
|
137
|
+
require 'envault'
|
138
|
+
Envault.load_with_profile('.env.encrypt', config: '.envault', profile: 'staging')
|
139
|
+
p ENV['PASSWORD_B']
|
140
|
+
#=> fugafuga
|
141
|
+
```
|
142
|
+
|
143
|
+
## Installation
|
144
|
+
|
145
|
+
Add this line to your application's Gemfile:
|
146
|
+
|
147
|
+
gem 'envault'
|
148
|
+
|
149
|
+
And then execute:
|
150
|
+
|
151
|
+
$ bundle
|
152
|
+
|
153
|
+
Or install it yourself as:
|
154
|
+
|
155
|
+
$ gem install envault
|
156
|
+
|
157
|
+
## Synopsis
|
158
|
+
|
159
|
+
$ envault
|
160
|
+
|
161
|
+
## Contributing
|
162
|
+
|
163
|
+
1. Fork it
|
164
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
165
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
166
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
167
|
+
5. Create new [Pull Request](../../pull/new/master)
|
168
|
+
|
169
|
+
## Information
|
170
|
+
|
171
|
+
* [Homepage](https://github.com/toyama0919/envault)
|
172
|
+
* [Issues](https://github.com/toyama0919/envault/issues)
|
173
|
+
* [Documentation](http://rubydoc.info/gems/envault/frames)
|
174
|
+
* [Email](mailto:toyama0919@gmail.com)
|
175
|
+
|
176
|
+
## Copyright
|
177
|
+
|
178
|
+
Copyright (c) 2016 toyama0919
|
179
|
+
|
180
|
+
See [LICENSE.txt](../LICENSE.txt) for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'bundler/setup'
|
7
|
+
rescue LoadError => e
|
8
|
+
abort e.message
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'rake'
|
12
|
+
|
13
|
+
|
14
|
+
require 'rubygems/tasks'
|
15
|
+
Gem::Tasks.new
|
16
|
+
|
17
|
+
require 'rspec/core/rake_task'
|
18
|
+
RSpec::Core::RakeTask.new
|
19
|
+
|
20
|
+
task :test => :spec
|
21
|
+
task :default => :spec
|
22
|
+
|
23
|
+
require 'yard'
|
24
|
+
YARD::Rake::YardocTask.new
|
25
|
+
task :doc => :yard
|
data/bin/envault
ADDED
data/envault.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.expand_path('../lib/envault/version', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "envault"
|
7
|
+
gem.version = Envault::VERSION
|
8
|
+
gem.summary = %q{Encrypt secret information environment variables by yaml.}
|
9
|
+
gem.description = %q{Encrypt secret information environment variables by yaml.}
|
10
|
+
gem.license = "MIT"
|
11
|
+
gem.authors = ["toyama0919"]
|
12
|
+
gem.email = "toyama0919@gmail.com"
|
13
|
+
gem.homepage = "https://github.com/toyama0919/envault"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
|
20
|
+
gem.required_ruby_version = '>= 2.1'
|
21
|
+
|
22
|
+
gem.add_dependency 'thor'
|
23
|
+
gem.add_dependency 'dotenv'
|
24
|
+
gem.add_dependency 'activesupport', ">=4", "<5"
|
25
|
+
|
26
|
+
gem.add_development_dependency 'bundler'
|
27
|
+
gem.add_development_dependency 'pry'
|
28
|
+
gem.add_development_dependency 'rake'
|
29
|
+
gem.add_development_dependency 'rspec', '~> 3.0'
|
30
|
+
gem.add_development_dependency 'rubocop', '~> 0.24.1'
|
31
|
+
gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
|
32
|
+
gem.add_development_dependency 'yard', '~> 0.8'
|
33
|
+
end
|
data/lib/envault.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'envault/version'
|
2
|
+
require 'envault/constants'
|
3
|
+
require 'envault/core'
|
4
|
+
require 'envault/cli'
|
5
|
+
require 'envault/environment'
|
6
|
+
require 'envault/formatter'
|
7
|
+
|
8
|
+
module Envault
|
9
|
+
def self.load(*source_files)
|
10
|
+
source_files = ['.env'] if source_files.empty?
|
11
|
+
params = ['load', '--sources', source_files]
|
12
|
+
Envault::CLI.start(params)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.load_with_profile(*source_files, config:, profile:)
|
16
|
+
source_files = ['.env'] if source_files.empty?
|
17
|
+
params = ['load', '--sources', source_files]
|
18
|
+
params.concat(['-c', config]) if config
|
19
|
+
params.concat(['--profile', profile]) if profile
|
20
|
+
Envault::CLI.start(params)
|
21
|
+
end
|
22
|
+
end
|
data/lib/envault/cli.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'erb'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Envault
|
6
|
+
class CLI < Thor
|
7
|
+
map '-e' => :encrypt_file
|
8
|
+
map '-d' => :decrypt_file
|
9
|
+
map '-r' => :reencrypt_file
|
10
|
+
map '-l' => :load
|
11
|
+
|
12
|
+
class_option :config, aliases: '-c', type: :string ,desc: 'config'
|
13
|
+
class_option :profile, aliases: '-p', type: :string, default: 'default',desc: 'profile'
|
14
|
+
class_option :debug, aliases: '--debug', type: :boolean, default: false, desc: 'debug'
|
15
|
+
class_option :prefix, type: :string, default: nil, desc: 'prefix'
|
16
|
+
def initialize(args = [], options = {}, config = {})
|
17
|
+
super(args, options, config)
|
18
|
+
@class_options = config[:shell].base.options
|
19
|
+
current_command = config[:current_command].name
|
20
|
+
unless SKIP_INITIALIZE_COMMANDS.include?(current_command)
|
21
|
+
@core = Core.new(
|
22
|
+
config: @class_options[:config],
|
23
|
+
profile: @class_options[:profile],
|
24
|
+
prefix: @class_options[:prefix],
|
25
|
+
debug: @class_options[:debug]
|
26
|
+
)
|
27
|
+
@logger = @core.logger
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "encrypt", "encrypt string. exp: envault encrypt -s hoge"
|
32
|
+
option :source, aliases: '-s', type: :string, required: true, desc: 'source', banner: 'source'
|
33
|
+
def encrypt
|
34
|
+
puts @core.cryptor.encrypt_and_sign(options[:source])
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "decrypt", "decrypt string. exp: envault decrypt -s hoge"
|
38
|
+
option :source, aliases: '-s', type: :string, required: true, desc: 'source'
|
39
|
+
def decrypt
|
40
|
+
puts @core.cryptor.decrypt_and_verify(options[:source])
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "-r", "reencrypt file. exp: envault -r -s .env.encrypt -c ~/.envault --from_profile staging --to_profile production"
|
44
|
+
option :source, aliases: '-s', type: :string, required: true, desc: 'source'
|
45
|
+
option :from_profile, type: :string, required: true, desc: 'from_profile'
|
46
|
+
option :to_profile, type: :string, required: true, desc: 'to_profile'
|
47
|
+
option :overwrite, type: :boolean, default: false, desc: 'overwrite'
|
48
|
+
def reencrypt_file
|
49
|
+
yaml = YAML.load_file(options[:source])
|
50
|
+
from = Core.new(
|
51
|
+
config: @class_options[:config],
|
52
|
+
profile: options[:from_profile],
|
53
|
+
prefix: @class_options[:prefix],
|
54
|
+
debug: @class_options[:debug]
|
55
|
+
)
|
56
|
+
cipher_keys = from.get_cipher_keys(yaml).map{ |cipher_key| cipher_key.gsub(/^#{from.prefix}/, '') }
|
57
|
+
decrypted = from.decrypt_yaml(options[:source])
|
58
|
+
to = Core.new(
|
59
|
+
config: @class_options[:config],
|
60
|
+
profile: options[:to_profile],
|
61
|
+
prefix: @class_options[:prefix],
|
62
|
+
debug: @class_options[:debug]
|
63
|
+
)
|
64
|
+
output = to.encrypt_process(decrypted, cipher_keys)
|
65
|
+
if options[:overwrite]
|
66
|
+
Formatter.write_escape_yaml(options[:source], output)
|
67
|
+
else
|
68
|
+
puts Formatter.escape_yaml(output)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "-e", "encrypt file. exp. envault -e -s .env -k '^PASSWORD_.*' '^API_KEY_.*'"
|
73
|
+
option :source, aliases: '-s', type: :array, required: true, desc: 'secret'
|
74
|
+
option :keys, aliases: '-k', type: :array, required: false, desc: 'keys'
|
75
|
+
option :plain_text, aliases: '-t', type: :array, default: [], required: false, desc: 'plain'
|
76
|
+
option :output, aliases: '-o', type: :string, default: nil, desc: 'output'
|
77
|
+
def encrypt_file
|
78
|
+
result = {}
|
79
|
+
options[:plain_text].each do |plain_text_path|
|
80
|
+
result = result.merge(YAML.load(ERB.new(File.read(plain_text_path)).result))
|
81
|
+
end
|
82
|
+
options[:source].each do |secret_yaml_path|
|
83
|
+
result = result.merge(@core.encrypt_yaml(secret_yaml_path, options[:keys]))
|
84
|
+
end
|
85
|
+
if options[:output]
|
86
|
+
Formatter.write_escape_yaml(options[:output], result)
|
87
|
+
else
|
88
|
+
puts Formatter.escape_yaml(result)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
desc "-d", "decrypt file. exp: envault -d -s .env"
|
93
|
+
option :source, aliases: '-s', type: :array, required: true, desc: 'source'
|
94
|
+
option :plain_text, aliases: '-t', type: :array, default: [], required: false, desc: 'plain_text'
|
95
|
+
option :output, aliases: '-o', type: :string, default: nil, desc: 'output'
|
96
|
+
def decrypt_file
|
97
|
+
result = {}
|
98
|
+
options[:plain_text].each do |plain_text_path|
|
99
|
+
result = result.merge(YAML.load(ERB.new(File.read(plain_text_path)).result))
|
100
|
+
end
|
101
|
+
options[:source].each do |encrypt_yaml_path|
|
102
|
+
result = result.merge(@core.decrypt_yaml(encrypt_yaml_path))
|
103
|
+
end
|
104
|
+
if options[:output]
|
105
|
+
Formatter.write_escape_yaml(options[:output], result)
|
106
|
+
else
|
107
|
+
puts Formatter.escape_yaml(result)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
desc "-l", "load environment. exp: envault -l -s .env --command 'echo $myhostname'"
|
112
|
+
option :sources, aliases: '-s', type: :array, required: true, default: [DEFAULT_SOURCE_FILE], desc: 'source'
|
113
|
+
option :command, type: :string, desc: 'source'
|
114
|
+
def load
|
115
|
+
options[:sources].each do |source|
|
116
|
+
begin
|
117
|
+
@core.load(source)
|
118
|
+
rescue => e
|
119
|
+
raise "error => [#{source}]\n#{e.message}\n#{e.backtrace.join("\n")}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
@logger.debug(ENV)
|
123
|
+
exec(options[:command]) if options[:command]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/envault/core.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'dotenv'
|
2
|
+
require 'pp'
|
3
|
+
require 'logger'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'active_support'
|
6
|
+
|
7
|
+
module Envault
|
8
|
+
class Core
|
9
|
+
attr_accessor :logger, :cryptor, :prefix
|
10
|
+
|
11
|
+
def initialize(config: nil, profile: nil, prefix: nil, debug: false)
|
12
|
+
@logger = Logger.new(STDOUT)
|
13
|
+
@logger.level = debug ? Logger::DEBUG : Logger::INFO
|
14
|
+
profile = get_profile(config, profile)
|
15
|
+
@cryptor = get_cryptor(profile[:passphrase] || '', profile[:sign_passphrase], profile[:salt] || '')
|
16
|
+
@prefix = prefix || profile[:prefix] || DEFAULT_ENV_PREFIX
|
17
|
+
end
|
18
|
+
|
19
|
+
def encrypt_yaml(path, keys = nil)
|
20
|
+
hash = YAML.load_file(path)
|
21
|
+
encrypt_process(hash, keys)
|
22
|
+
end
|
23
|
+
|
24
|
+
def encrypt_process(hash, keys = nil)
|
25
|
+
cipher_keys = get_cipher_keys(hash, keys)
|
26
|
+
encrypted = hash.map do |k, v|
|
27
|
+
if cipher_keys.include?(k)
|
28
|
+
[@prefix + k, @cryptor.encrypt_and_sign(v)]
|
29
|
+
else
|
30
|
+
[k, v]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
Hash[encrypted]
|
34
|
+
end
|
35
|
+
|
36
|
+
def decrypt_yaml(path)
|
37
|
+
hash = YAML.load_file(path)
|
38
|
+
decrypt_process(hash)
|
39
|
+
end
|
40
|
+
|
41
|
+
def decrypt_process(hash)
|
42
|
+
cipher_keys = get_cipher_keys(hash)
|
43
|
+
decrypted = hash.map do |k, v|
|
44
|
+
if cipher_keys.include?(k)
|
45
|
+
[k.gsub(/^#{@prefix}/, ''), @cryptor.decrypt_and_verify(v)]
|
46
|
+
else
|
47
|
+
[k, v]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
Hash[decrypted]
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_cipher_keys(hash, keys = ["^#{@prefix}.*"])
|
54
|
+
all_keys = hash.keys
|
55
|
+
if keys
|
56
|
+
regexps = []
|
57
|
+
keys.each do |key|
|
58
|
+
regexps << Regexp.new(key)
|
59
|
+
end
|
60
|
+
results = regexps.map do |regexp|
|
61
|
+
all_keys.select do |key|
|
62
|
+
regexp =~ key
|
63
|
+
end
|
64
|
+
end
|
65
|
+
results.flatten
|
66
|
+
else
|
67
|
+
all_keys
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def load(path = DEFAULT_SOURCE_FILE)
|
72
|
+
hash = decrypt_yaml(path)
|
73
|
+
|
74
|
+
Tempfile.create("dotenv-vault") do |f|
|
75
|
+
Formatter.write_escape_yaml(f.path, hash)
|
76
|
+
Dotenv.load(f.path)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def get_cryptor(passphrase, sign_passphrase, salt)
|
83
|
+
key = ActiveSupport::KeyGenerator.new(passphrase).generate_key(salt, 64)
|
84
|
+
signature_key = ActiveSupport::KeyGenerator.new(sign_passphrase).generate_key(salt, 64) if sign_passphrase
|
85
|
+
|
86
|
+
if signature_key
|
87
|
+
ActiveSupport::MessageEncryptor.new(key, signature_key, cipher: DEFAULT_CIPHER, digest: DEFAULT_DIGEST)
|
88
|
+
else
|
89
|
+
ActiveSupport::MessageEncryptor.new(key, cipher: DEFAULT_CIPHER, digest: DEFAULT_DIGEST)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_profile(config_path, profile_name)
|
94
|
+
return get_profile_form_env unless config_path
|
95
|
+
config = YAML.load_file(config_path)
|
96
|
+
return get_profile_form_env unless config
|
97
|
+
profile = config[profile_name]
|
98
|
+
unless profile
|
99
|
+
raise %Q{invalid profile [#{profile_name}].}
|
100
|
+
end
|
101
|
+
{
|
102
|
+
passphrase: profile['passphrase'],
|
103
|
+
sign_passphrase: profile['sign_passphrase'],
|
104
|
+
salt: profile['salt'],
|
105
|
+
prefix: profile['prefix']
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
def get_profile_form_env
|
110
|
+
{
|
111
|
+
passphrase: ENV['ENVAULT_PASSPHRASE'],
|
112
|
+
sign_passphrase: ENV['ENVAULT_SIGN_PASSPHRASE'],
|
113
|
+
salt: ENV['ENVAULT_SALT'],
|
114
|
+
prefix: ENV['ENVAULT_PREFIX']
|
115
|
+
}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Envault
|
2
|
+
class Formatter
|
3
|
+
def self.escape_yaml(hash)
|
4
|
+
lines = []
|
5
|
+
hash.map do |k, v|
|
6
|
+
lines << %Q{#{k}: #{v.inspect}}
|
7
|
+
end
|
8
|
+
lines.join("\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.write_escape_yaml(path, hash)
|
12
|
+
File.write(path, escape_yaml(hash))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'envault'
|
3
|
+
|
4
|
+
describe Envault::CLI do
|
5
|
+
before do
|
6
|
+
clear_env
|
7
|
+
ENV['ENVAULT_PASSPHRASE'] = 'ENV'
|
8
|
+
ENV['ENVAULT_SIGN_PASSPHRASE'] = 'ENV'
|
9
|
+
ENV['ENVAULT_SALT'] = 'ENV'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should stdout help" do
|
13
|
+
output = capture_stdout do
|
14
|
+
Envault::CLI.start(['help'])
|
15
|
+
end
|
16
|
+
expect(output).not_to eq(nil)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "encrypt options" do
|
20
|
+
output = capture_stdout do
|
21
|
+
Envault::CLI.start(['help', 'encrypt'])
|
22
|
+
end
|
23
|
+
expect(output).to include('-s,')
|
24
|
+
expect(output).to include('-c,')
|
25
|
+
expect(output).to include('-p,')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "decrypt options" do
|
29
|
+
output = capture_stdout do
|
30
|
+
Envault::CLI.start(['help', 'decrypt'])
|
31
|
+
end
|
32
|
+
expect(output).to include('-s,')
|
33
|
+
expect(output).to include('-c,')
|
34
|
+
expect(output).to include('-p,')
|
35
|
+
end
|
36
|
+
|
37
|
+
after do
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
a:
|
2
|
+
passphrase: 'p1'
|
3
|
+
sign_passphrase: 'sp1'
|
4
|
+
salt: 's1'
|
5
|
+
prefix: ENVAULT_
|
6
|
+
|
7
|
+
a1:
|
8
|
+
sign_passphrase: 'sp1'
|
9
|
+
salt: 's1'
|
10
|
+
prefix: ENVAULT_
|
11
|
+
|
12
|
+
a2:
|
13
|
+
passphrase: 'p1'
|
14
|
+
prefix: ENVAULT_
|
15
|
+
|
16
|
+
a3:
|
17
|
+
passphrase: 'p1'
|
18
|
+
sign_passphrase: 'sp1'
|
19
|
+
prefix: ENVAULT_
|
20
|
+
|
21
|
+
a4:
|
22
|
+
passphrase: 'p1'
|
23
|
+
salt: 's1'
|
24
|
+
prefix: ENVAULT_
|
25
|
+
|
26
|
+
a5:
|
27
|
+
salt: 's1'
|
28
|
+
prefix: ENVAULT_
|
29
|
+
|
30
|
+
b:
|
31
|
+
passphrase: 'p2'
|
32
|
+
sign_passphrase: 'sp2'
|
33
|
+
salt: 's2'
|
34
|
+
prefix: ENVAULT_
|
35
|
+
|
data/spec/core_spec.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'envault'
|
3
|
+
|
4
|
+
describe Envault::Core do
|
5
|
+
|
6
|
+
before do
|
7
|
+
clear_env
|
8
|
+
@config_path = File.expand_path("../config/envault.yml", __FILE__)
|
9
|
+
@core = Core.new(config: @config_path, profile: 'a')
|
10
|
+
@envs = {
|
11
|
+
'USERNAME_A' => 'hogehoge',
|
12
|
+
'PASSWORD_A' => 'hogehoge',
|
13
|
+
'API_KEY_A' => 'fugafuga'
|
14
|
+
}
|
15
|
+
@encrypted = @core.encrypt_process(@envs, ['PASSWORD_A', 'API_KEY_A'])
|
16
|
+
end
|
17
|
+
|
18
|
+
it "core not nil" do
|
19
|
+
expect(@core).not_to eq(nil)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "exist logger" do
|
23
|
+
expect(@core.logger).not_to eq(nil)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'profile ok case' do
|
27
|
+
it "encrypt envs" do
|
28
|
+
expect(@encrypted.keys).to eq(['USERNAME_A', 'ENVAULT_PASSWORD_A', 'ENVAULT_API_KEY_A'])
|
29
|
+
expect(@encrypted['USERNAME_A']).to eq('hogehoge')
|
30
|
+
expect(@encrypted['ENVAULT_PASSWORD_A']).not_to eq('hogehoge')
|
31
|
+
expect(@encrypted['ENVAULT_API_KEY_A']).not_to eq('hogehoge')
|
32
|
+
end
|
33
|
+
|
34
|
+
it "decrypt envs" do
|
35
|
+
expect(@core.decrypt_process(@encrypted)).to include(@envs)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "decrypt envs other instance" do
|
39
|
+
other = Core.new(config: @config_path, profile: 'a')
|
40
|
+
expect(other.decrypt_process(@encrypted)).to include(@envs)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'profile error case' do
|
45
|
+
it "cannot encrypt 1" do
|
46
|
+
other = Core.new(config: @config_path, profile: 'a1')
|
47
|
+
expect {
|
48
|
+
other.decrypt_process(@encrypted)
|
49
|
+
}.to raise_exception(ActiveSupport::MessageEncryptor::InvalidMessage)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "cannot encrypt 2" do
|
53
|
+
other = Core.new(config: @config_path, profile: 'a2')
|
54
|
+
expect {
|
55
|
+
other.decrypt_process(@encrypted)
|
56
|
+
}.to raise_exception(ActiveSupport::MessageVerifier::InvalidSignature)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "cannot encrypt 3 no salt" do
|
60
|
+
other = Core.new(config: @config_path, profile: 'a3')
|
61
|
+
expect {
|
62
|
+
other.decrypt_process(@encrypted)
|
63
|
+
}.to raise_exception(ActiveSupport::MessageVerifier::InvalidSignature)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "cannot encrypt 4 different sign_passphrase" do
|
67
|
+
other = Core.new(config: @config_path, profile: 'a4')
|
68
|
+
expect {
|
69
|
+
other.decrypt_process(@encrypted)
|
70
|
+
}.to raise_exception(ActiveSupport::MessageVerifier::InvalidSignature)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "cannot encrypt 5 different sign_passphrase" do
|
74
|
+
other = Core.new(config: @config_path, profile: 'a5')
|
75
|
+
expect {
|
76
|
+
other.decrypt_process(@encrypted)
|
77
|
+
}.to raise_exception(ActiveSupport::MessageVerifier::InvalidSignature)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "cannot encrypt" do
|
81
|
+
other = Core.new(config: @config_path, profile: 'b')
|
82
|
+
expect {
|
83
|
+
other.decrypt_process(@encrypted)
|
84
|
+
}.to raise_exception(ActiveSupport::MessageVerifier::InvalidSignature)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'environment variables' do
|
89
|
+
it "environment variables decrypt" do
|
90
|
+
ENV['ENVAULT_PASSPHRASE'] = 'p1'
|
91
|
+
ENV['ENVAULT_SIGN_PASSPHRASE'] = 'sp1'
|
92
|
+
ENV['ENVAULT_SALT'] = 's1'
|
93
|
+
ENV['ENVAULT_PREFIX'] = 'ENVAULT_'
|
94
|
+
other = Core.new
|
95
|
+
expect(other.decrypt_process(@encrypted)).to include(@envs)
|
96
|
+
clear_env
|
97
|
+
end
|
98
|
+
|
99
|
+
it "environment variables decrypt other prefix" do
|
100
|
+
ENV['ENVAULT_PASSPHRASE'] = 'p1'
|
101
|
+
ENV['ENVAULT_PREFIX'] = 'ENVAULT_OTHER_PREFIX_'
|
102
|
+
other = Core.new
|
103
|
+
decrypted = other.decrypt_process(@encrypted)
|
104
|
+
expect(@encrypted['USERNAME_A']).to eq('hogehoge')
|
105
|
+
expect(decrypted['ENVAULT_PASSWORD_A']).not_to eq('hogehoge')
|
106
|
+
expect(decrypted['ENVAULT_API_KEY_A']).not_to eq('fugafuga')
|
107
|
+
clear_env
|
108
|
+
end
|
109
|
+
|
110
|
+
it "environment variables cannot decrypt" do
|
111
|
+
ENV['ENVAULT_PASSPHRASE'] = 'p1'
|
112
|
+
ENV['ENVAULT_PREFIX'] = 'ENVAULT_'
|
113
|
+
other = Core.new
|
114
|
+
expect {
|
115
|
+
other.decrypt_process(@encrypted)
|
116
|
+
}.to raise_exception(ActiveSupport::MessageVerifier::InvalidSignature)
|
117
|
+
clear_env
|
118
|
+
end
|
119
|
+
|
120
|
+
it "environment variables cannot decrypt no salt" do
|
121
|
+
ENV['ENVAULT_PASSPHRASE'] = 'p1'
|
122
|
+
ENV['ENVAULT_SIGN_PASSPHRASE'] = 'sp1'
|
123
|
+
ENV['ENVAULT_PREFIX'] = 'ENVAULT_'
|
124
|
+
other = Core.new
|
125
|
+
expect {
|
126
|
+
other.decrypt_process(@encrypted)
|
127
|
+
}.to raise_exception(ActiveSupport::MessageVerifier::InvalidSignature)
|
128
|
+
clear_env
|
129
|
+
end
|
130
|
+
|
131
|
+
it "environment variables cannot decrypt no passphrase" do
|
132
|
+
ENV['ENVAULT_SIGN_PASSPHRASE'] = 'sp1'
|
133
|
+
ENV['ENVAULT_SALT'] = 's1'
|
134
|
+
ENV['ENVAULT_PREFIX'] = 'ENVAULT_'
|
135
|
+
other = Core.new
|
136
|
+
expect {
|
137
|
+
other.decrypt_process(@encrypted)
|
138
|
+
}.to raise_exception(ActiveSupport::MessageEncryptor::InvalidMessage)
|
139
|
+
clear_env
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
after do
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'envault'
|
3
|
+
|
4
|
+
describe Envault do
|
5
|
+
it "escape_yaml" do
|
6
|
+
@envs = {
|
7
|
+
'USERNAME_A' => 'hogehoge',
|
8
|
+
'PASSWORD_A' => 'hogehoge',
|
9
|
+
'API_KEY_A' => 'fugafuga'
|
10
|
+
}
|
11
|
+
|
12
|
+
yaml = Formatter.escape_yaml(@envs)
|
13
|
+
expect(yaml).to eq("USERNAME_A: \"hogehoge\"\nPASSWORD_A: \"hogehoge\"\nAPI_KEY_A: \"fugafuga\"")
|
14
|
+
end
|
15
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'envault/version'
|
3
|
+
|
4
|
+
include Envault
|
5
|
+
|
6
|
+
def capture_stdout
|
7
|
+
out = StringIO.new
|
8
|
+
$stdout = out
|
9
|
+
yield
|
10
|
+
return out.string
|
11
|
+
ensure
|
12
|
+
$stdout = STDOUT
|
13
|
+
end
|
14
|
+
|
15
|
+
def capture_stderr
|
16
|
+
out = StringIO.new
|
17
|
+
$stderr = out
|
18
|
+
yield
|
19
|
+
return out.string
|
20
|
+
ensure
|
21
|
+
$stderr = STDERR
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear_env
|
25
|
+
ENV['ENVAULT_PASSPHRASE'] = nil
|
26
|
+
ENV['ENVAULT_SIGN_PASSPHRASE'] = nil
|
27
|
+
ENV['ENVAULT_SALT'] = nil
|
28
|
+
ENV['ENVAULT_PREFIX'] = nil
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: envault
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- toyama0919
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dotenv
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4'
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '5'
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '4'
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '5'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: bundler
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: pry
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rake
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: rspec
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '3.0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '3.0'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rubocop
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: 0.24.1
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: 0.24.1
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: rubygems-tasks
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0.2'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - "~>"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0.2'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: yard
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - "~>"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0.8'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - "~>"
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0.8'
|
159
|
+
description: Encrypt secret information environment variables by yaml.
|
160
|
+
email: toyama0919@gmail.com
|
161
|
+
executables:
|
162
|
+
- envault
|
163
|
+
extensions: []
|
164
|
+
extra_rdoc_files: []
|
165
|
+
files:
|
166
|
+
- ".document"
|
167
|
+
- ".gitignore"
|
168
|
+
- ".rspec"
|
169
|
+
- ".travis.yml"
|
170
|
+
- ".yardopts"
|
171
|
+
- ChangeLog.md
|
172
|
+
- Gemfile
|
173
|
+
- LICENSE.txt
|
174
|
+
- README.md
|
175
|
+
- Rakefile
|
176
|
+
- bin/envault
|
177
|
+
- envault.gemspec
|
178
|
+
- lib/envault.rb
|
179
|
+
- lib/envault/cli.rb
|
180
|
+
- lib/envault/constants.rb
|
181
|
+
- lib/envault/core.rb
|
182
|
+
- lib/envault/environment.rb
|
183
|
+
- lib/envault/formatter.rb
|
184
|
+
- lib/envault/version.rb
|
185
|
+
- spec/cli_spec.rb
|
186
|
+
- spec/config/envault.yml
|
187
|
+
- spec/core_spec.rb
|
188
|
+
- spec/envault_spec.rb
|
189
|
+
- spec/formatter_spec.rb
|
190
|
+
- spec/spec_helper.rb
|
191
|
+
homepage: https://github.com/toyama0919/envault
|
192
|
+
licenses:
|
193
|
+
- MIT
|
194
|
+
metadata: {}
|
195
|
+
post_install_message:
|
196
|
+
rdoc_options: []
|
197
|
+
require_paths:
|
198
|
+
- lib
|
199
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
200
|
+
requirements:
|
201
|
+
- - ">="
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
version: '2.1'
|
204
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
requirements: []
|
210
|
+
rubyforge_project:
|
211
|
+
rubygems_version: 2.5.1
|
212
|
+
signing_key:
|
213
|
+
specification_version: 4
|
214
|
+
summary: Encrypt secret information environment variables by yaml.
|
215
|
+
test_files:
|
216
|
+
- spec/cli_spec.rb
|
217
|
+
- spec/config/envault.yml
|
218
|
+
- spec/core_spec.rb
|
219
|
+
- spec/envault_spec.rb
|
220
|
+
- spec/formatter_spec.rb
|
221
|
+
- spec/spec_helper.rb
|