roro 0.3.21 → 0.3.22

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 43e30bd9aa551984852307e9c258049546a167e89aaab22e3f8b7256cec22a23
4
- data.tar.gz: 790ad729852cf34c8bbdfa6499ab325f399334d1df2c385d20e7ae5757dcd707
3
+ metadata.gz: d21bacda1161bc7f1cb8b57ebbca68cbe4f9647c2d02b33464c6a162f3661d31
4
+ data.tar.gz: d40e7d418705dd50e38e8d5a6f337d313f8cae3fadb1a37a7114c504cd8bbb46
5
5
  SHA512:
6
- metadata.gz: 4de76d1807c627790a721e968e458bcff335d9a972b8b496d5a1dfc494c8b750332eae75411dc689482bb3e60fab44319fa46cc95c63547cedfa5c849e527ce5
7
- data.tar.gz: b7f2647884d116fc849431070829e2806f244771580a532f57e65cabbf17d856bf209d76e425eee28e370eee90ef6d10f0ab8de10998503bc058da846387bb78
6
+ metadata.gz: af1f1072843ad1d6919afd41398c31ae7357a9d492bb8e811a3d9da825bef9eb1def20a5577f059655b22eceac1bc387b0760f710a257412202a61f6497d8818
7
+ data.tar.gz: ed48d94a0902e9123e4790b44d77249ddee40e4d122524fcfe5afe92a661ebc3903ff96cc75210e85e200eb66388033d824934b6675b976ca543aa39981ac2f5
data/.gitignore CHANGED
@@ -16,10 +16,12 @@ roro/**/*.key
16
16
  !/.gitignore
17
17
  *.gem
18
18
  tmp/*
19
- !tmp/.keep
19
+ !tmp/.keep
20
20
  sandbox/*
21
- !sandbox/.keep
21
+ !sandbox/.keep
22
22
  !sandbox/greenfield
23
23
  sandbox/greenfield/*
24
24
  !sandbox/greenfield/.keep
25
- TUTORIAL.md
25
+ TUTORIAL.md
26
+
27
+ .idea
data/Guardfile CHANGED
@@ -1,15 +1,17 @@
1
1
  options = {
2
- all_on_start: false,
3
- all_after_pass: false,
2
+ all_on_start: true,
3
+ all_after_pass: false,
4
4
  }
5
5
 
6
6
  guard :minitest, options do
7
7
 
8
8
  watch(%r{^test/(.*)\/?(.*)_test\.rb$})
9
- watch(%r{^test/helpers/(.*)\.rb$}) { 'test' }
10
- watch(%r{^test/test_helper\.rb$}) { 'test' }
9
+ # watch(%r{^test/helpers/(.*)\.rb$}) { 'test' }
10
+ # watch(%r{^test/test_helper\.rb$}) { 'test' }
11
11
  watch(%r{^lib/roro/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
12
- watch(%r{^lib/roro/cli/(.+)\.rb$}) { |m| "test/cli/#{m[1]}_test.rb" }
13
- watch(%r{^lib/roro/cli/(.+)\.yml$}) { |m| "test/cli" }
14
- watch(%r{^lib/roro/cli/(.+)\.tt$}) { |m| "test/cli" }
12
+ # watch(%r{^lib/roro/(.+)\.rb$}) { "test/crypto_test.rb" }
13
+ # watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
14
+ # watch(%r{^lib/roro/cli/(.+)\.rb$}) { |m| "test/cli/#{m[1]}_test.rb" }
15
+ # watch(%r{^lib/roro/cli/(.+)\.yml$}) { |m| "test/cli" }
16
+ # watch(%r{^lib/roro/cli/(.+)\.tt$}) { |m| "test/cli" }
15
17
  end
data/lib/roro.rb CHANGED
@@ -5,5 +5,14 @@ require "roro/configurator"
5
5
  require "roro/crypto"
6
6
 
7
7
  module Roro
8
+ module Crypto
9
+ class KeyError < StandardError; end
10
+ class EnvironmentError < StandardError; end
11
+ class DataDestructionError < StandardError; end
12
+ class EncryptableError < StandardError; end
13
+ class DecryptableError < StandardError; end
14
+ end
15
+
16
+
8
17
  class Error < StandardError; end
9
18
  end
data/lib/roro/cli.rb CHANGED
@@ -1,14 +1,13 @@
1
1
 
2
- require 'roro/cli/generate/exposed'
3
- require 'roro/cli/generate/keys'
4
- require 'roro/cli/generate/obfuscated'
5
- require 'roro/cli/generate/story'
2
+ require 'roro/cli/generate/generate_exposed'
3
+ require 'roro/cli/generate/generate_keys'
4
+ require 'roro/cli/generate/generate_obfuscated'
5
+ require 'roro/cli/generate/generate_story'
6
6
  require 'roro/cli/greenfield/rails'
7
7
  require 'roro/cli/rollon'
8
8
  require 'roro/cli/rollon/rails/base/base'
9
9
  require 'roro/cli/rollon/rails/database/with_mysql'
10
10
  require 'roro/cli/rollon/rails/database/with_postgresql'
11
-
12
11
  require 'roro/cli/rollon/ruby_gem'
13
12
 
14
13
  module Roro
@@ -24,6 +23,10 @@ module Roro
24
23
  File.dirname(__FILE__) + '/stories'
25
24
  end
26
25
 
26
+ def self.test_fixture_root
27
+ File.dirname(__FILE__) + '/test/fixtures'
28
+ end
29
+
27
30
  def self.roro_environments
28
31
  %w(development production test staging ci)
29
32
  end
@@ -0,0 +1,18 @@
1
+ module Roro
2
+ class CLI < Thor
3
+
4
+ desc "generate::exposed", "Decrypts .env.enc files for all environments or those specified."
5
+ map "generate::exposed" => "generate_exposed"
6
+
7
+
8
+ def generate_exposed(*environments)
9
+ Roro::Crypto.expose(environments, './roro', '.env.enc')
10
+ end
11
+ # def generate_exposed(*args)
12
+ # environments = args.first ? [args.first] : gather_environments
13
+ # environments.each do |environment|
14
+ # Roro::Crypto.expose(environment, 'roro')
15
+ # end
16
+ # end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ module Roro
2
+
3
+ class CLI < Thor
4
+ map "generate::key" => "generate_keys"
5
+ method_option :environment, type: :hash, default: {}, desc: "Generates a key for each argument.", banner: "development, staging"
6
+
7
+ desc "generate::keys", "Generates a key for each <environment>.env file."
8
+ map "generate::keys" => "generate_keys"
9
+
10
+ def generate_keys(*environments)
11
+ Roro::Crypto.generate_keys(environments, './roro', '.env')
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,34 @@
1
+ require 'roro/crypto'
2
+
3
+ module Roro
4
+
5
+ class CLI < Thor
6
+
7
+ desc "generate::obfuscated", "Encrypts .env files for safe storage."
8
+ map "generate::obfuscated" => "generate_obfuscated"
9
+
10
+ def generate_obfuscated(*environments)
11
+ Roro::Crypto.obfuscate(environments, './roro', '.env')
12
+ end
13
+
14
+ no_commands do
15
+
16
+ def check_for_obfuscatable(environments)
17
+ if environments.empty?
18
+ msg = "No .env files matching the
19
+ pattern roro/**/*.env'. Please create one."
20
+ raise Roro::Error.new(msg)
21
+ end
22
+ end
23
+
24
+ def check_for_keys(environments)
25
+ environments.each do |e|
26
+ unless File.exist?("roro/keys/#{e}.key")
27
+ msg = "No #{e} key file at roro/keys/{e}.key. Please generate one."
28
+ raise Roro::Error.new(msg)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/roro/crypto.rb CHANGED
@@ -11,63 +11,103 @@ module Roro::Crypto
11
11
  Base64.encode64(@new_key)
12
12
  end
13
13
 
14
- def write_to_file(data, filename)
15
- File.open(filename, "w") { |io| io.write data }
14
+ def source_files(dir, pattern)
15
+ Dir.glob(dir + "/**/*#{pattern}")
16
16
  end
17
17
 
18
- def generate_key_file(directory, environment)
19
- write_to_file(generate_key, directory + "/" + environment + ".key")
18
+ def gather_environments(dir, ext)
19
+ environments = []
20
+ source_files(dir, ext).each do |source_file|
21
+ environments << source_file.split('/').last.split('.').first
22
+ end
23
+ if environments.empty?
24
+ raise EnvironmentError, "No files in the #{dir} directory matching #{ext}"
25
+ else
26
+ environments.uniq
27
+ end
20
28
  end
21
29
 
22
- def source_files(directory=nil, extension=nil)
23
- Dir.glob(directory + "/**/*#{extension}")
30
+ def generate_keys(keys, dir, ext)
31
+ (keys.empty? ? gather_environments(dir, ext) : keys).each do |key|
32
+ write_to_file generate_key, "#{dir}/keys/#{key}.key"
33
+ end
24
34
  end
25
35
 
26
- def build_cipher(environment)
27
- @cipher = OpenSSL::Cipher.new 'AES-128-CBC'
28
- @salt = '8 octets'
29
- @pass_phrase = get_key(environment)
30
- @cipher.encrypt.pkcs5_keyivgen @pass_phrase, @salt
36
+ def expose(environments, dir, ext)
37
+ if environments.empty?
38
+ environments = gather_environments('./roro/keys', '.key')
39
+ end
40
+ environments.each do |environment|
41
+ pattern = "#{environment}*#{ext}"
42
+
43
+ exposable = source_files(dir, pattern)
44
+ if exposable.empty?
45
+ puts "No #{environment} files in ./roro matching #{pattern}"
46
+ end
47
+ source_files(dir, pattern).each do |file|
48
+ decrypt(file, environment)
49
+ end
50
+ end
31
51
  end
32
52
 
33
- def encrypt(file, environment=nil)
34
- environment ||= file.split('.')[-2].split('/').last
35
- build_cipher(environment)
53
+ def obfuscate(envs, dir, ext)
54
+ environments = envs.empty? ? gather_environments(dir, ext) : envs
55
+ environments.each do |environment|
56
+ pattern = "#{environment}*#{ext}"
57
+ get_key(environment)
58
+ encryptable_files = source_files(dir, pattern)
59
+ if encryptable_files.empty?
60
+ puts "No #{environment} files in ./roro matching #{pattern}"
61
+ end
62
+ encryptable_files.each do |file|
63
+ encrypt(file, environment)
64
+ end
65
+ end
66
+ end
67
+
68
+ def write_to_file(data, filename)
69
+ if File.exist?(filename)
70
+ raise DataDestructionError, "Existing file at #{filename}. Please remove it and try again."
71
+ else
72
+ File.open(filename, "w") { |io| io.write data }
73
+ end
74
+ end
75
+
76
+
77
+ def encrypt(file, key)
78
+ build_cipher(key)
36
79
  encrypted = @cipher.update(File.read file) + @cipher.final
37
80
  write_to_file(Base64.encode64(encrypted), file + '.enc')
38
81
  end
39
-
40
- def decrypt(file, environment=nil)
41
- environment ||= file.split('.')[-3].split('/').last
42
- build_cipher(environment)
82
+
83
+ def decrypt(file, key)
84
+ build_cipher(key)
43
85
  encrypted = Base64.decode64 File.read(file)
44
86
  @cipher.decrypt.pkcs5_keyivgen @pass_phrase, @salt
45
87
  decrypted = @cipher.update(encrypted) + @cipher.final
46
88
  decrypted_file = file.split('.enc').first
47
89
  write_to_file decrypted, decrypted_file
48
90
  end
49
-
50
- def obfuscate(env=nil, dir=nil, ext=nil)
51
- ext = ext || "#{env}.env"
52
- source_files(dir, ext).each { |file| encrypt(file, env) }
53
- end
54
-
55
- def expose(env=nil, dir=nil, ext=nil)
56
- ext = ext || "#{env}.env.enc"
57
- source_files(dir, ext).each { |file| decrypt(file, env) }
58
- end
59
-
60
- def get_key(environment, directory=nil)
91
+
92
+ def get_key(environment, dir='roro')
61
93
  env_key = environment.upcase + '_KEY'
62
- key_file = source_files('./.', "#{directory}/#{environment}.key").first
94
+ key_file = Dir.glob("roro/keys/#{environment}.key").first
63
95
  case
64
96
  when ENV[env_key].nil? && key_file.nil?
65
- raise DeployKeyError, "No #{env_key} set."
97
+ raise KeyError, "No #{env_key} set. Please set one as a variable or in a file."
66
98
  when ENV[env_key]
67
99
  ENV[env_key]
68
100
  when File.exist?(key_file)
69
101
  File.read(key_file).strip
70
102
  end
71
103
  end
104
+
105
+ private
106
+ def build_cipher(environment)
107
+ @cipher = OpenSSL::Cipher.new 'AES-128-CBC'
108
+ @salt = '8 octets'
109
+ @pass_phrase = get_key(environment)
110
+ @cipher.encrypt.pkcs5_keyivgen @pass_phrase, @salt
111
+ end
72
112
  end
73
113
  end
File without changes
@@ -28,7 +28,7 @@ RUN gem install bundler:2.1.4
28
28
  WORKDIR ${APP_HOME}
29
29
 
30
30
  ## Create a Gemfile with just the Rails gem inside:
31
- RUN echo -e "source 'https://rubygems.org'\ngem 'rails'" > Gemfile
31
+ RUN echo -e "source 'https://rubygems.org'\ngem 'rails', '6.1.3.1'" > Gemfile
32
32
 
33
33
  ## Bundle to install rails:
34
34
  RUN bundle install
File without changes
data/lib/roro/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Roro
2
- VERSION = "0.3.21"
2
+ VERSION = "0.3.22"
3
3
  end
data/roro.gemspec CHANGED
@@ -35,6 +35,7 @@ Gem::Specification.new do |spec|
35
35
  spec.add_development_dependency 'bundler', '~> 2.1', '>= 2.1.4'
36
36
  spec.add_development_dependency 'byebug', '~> 11.1', '>= 11.1.3'
37
37
  spec.add_development_dependency 'handsome_fencer-test', '~> 0.2.2'
38
+ spec.add_development_dependency 'minitest-focus'
38
39
  spec.add_development_dependency 'readline'
39
40
  spec.add_development_dependency 'mocha', '~> 1.11', '>= 1.11.2'
40
41
 
@@ -0,0 +1 @@
1
+ RORO_ENV=development
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.21
4
+ version: 0.3.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - schadenfred
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-06 00:00:00.000000000 Z
11
+ date: 2021-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem-release
@@ -132,6 +132,20 @@ dependencies:
132
132
  - - "~>"
133
133
  - !ruby/object:Gem::Version
134
134
  version: 0.2.2
135
+ - !ruby/object:Gem::Dependency
136
+ name: minitest-focus
137
+ requirement: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ type: :development
143
+ prerelease: false
144
+ version_requirements: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
135
149
  - !ruby/object:Gem::Dependency
136
150
  name: readline
137
151
  requirement: !ruby/object:Gem::Requirement
@@ -194,11 +208,11 @@ files:
194
208
  - docker-compose.yml
195
209
  - lib/roro.rb
196
210
  - lib/roro/cli.rb
197
- - lib/roro/cli/generate/exposed.rb
198
211
  - lib/roro/cli/generate/generate.rb
199
- - lib/roro/cli/generate/keys.rb
200
- - lib/roro/cli/generate/obfuscated.rb
201
- - lib/roro/cli/generate/story.rb
212
+ - lib/roro/cli/generate/generate_exposed.rb
213
+ - lib/roro/cli/generate/generate_keys.rb
214
+ - lib/roro/cli/generate/generate_obfuscated.rb
215
+ - lib/roro/cli/generate/generate_story.rb
202
216
  - lib/roro/cli/greenfield/rails.rb
203
217
  - lib/roro/cli/rollon.rb
204
218
  - lib/roro/cli/rollon/rails/base/base.rb
@@ -253,6 +267,7 @@ files:
253
267
  - lib/roro/templates/base/roro/roro/containers/app/.keep
254
268
  - lib/roro/templates/base/roro/roro/containers/frontend/.keep
255
269
  - lib/roro/templates/base/roro/roro/docker-entrypoint.sh.tt
270
+ - lib/roro/templates/base/roro/roro/keys/.keep
256
271
  - lib/roro/templates/rails/.circleci/.keep
257
272
  - lib/roro/templates/rails/.circleci/config.yml.tt
258
273
  - lib/roro/templates/rails/.circleci/jobs/_build.yml
@@ -279,6 +294,7 @@ files:
279
294
  - lib/roro/templates/rails/roro/containers/app/Dockerfile.tt
280
295
  - lib/roro/templates/rails/roro/containers/frontend/.keep
281
296
  - lib/roro/templates/rails/roro/docker-entrypoint.sh
297
+ - lib/roro/templates/rails/roro/keys/.keep
282
298
  - lib/roro/templates/rails/roro/kube/.keep
283
299
  - lib/roro/templates/rails/roro/kube/certificate.yml.tt
284
300
  - lib/roro/templates/rails/roro/kube/cluster-issuer.yml.tt
@@ -310,8 +326,8 @@ files:
310
326
  - roro.gemspec
311
327
  - roro/containers/.keep
312
328
  - roro/containers/app/Dockerfile
329
+ - roro/containers/app/dotenv
313
330
  - roro/containers/ruby_image/Dockerfile
314
- - roro/containers/ruby_image/ci.env.enc
315
331
  - roro/keys/.keep
316
332
  - sandbox/.keep
317
333
  - tmp/.keep
@@ -1,14 +0,0 @@
1
- module Roro
2
- class CLI < Thor
3
-
4
- desc "generate::exposed", "Generate private .env files from encrypted .env.enc files inside the roro directory."
5
- map "generate::exposed" => "generate_exposed"
6
-
7
- def generate_exposed(*args)
8
- environments = args.first ? [args.first] : gather_environments
9
- environments.each do |environment|
10
- Roro::Crypto.expose(environment, 'roro')
11
- end
12
- end
13
- end
14
- end
@@ -1,69 +0,0 @@
1
- module Roro
2
-
3
- class CLI < Thor
4
-
5
- desc "generate::key", "Generate a key inside roro/keys. Takes the name of
6
- an environment as an argument to private .env files from
7
- encrypted .env.enc files inside the roro directory.
8
- Expose encrypted files"
9
-
10
- map "generate::key" => "generate_key"
11
- method_option :environment, type: :hash, default: {}, desc: "Pass a list of environment variables like so: env:var", banner: "development, staging"
12
-
13
- def generate_key(*args)
14
- generate_key_or_keys(*args)
15
- end
16
-
17
- desc "generate::keys", "Generate keys for each environment inside roro/keys.
18
- If you have .env files like 'roro/containers/app/[staging_env].env' and
19
- 'roro/[circle_ci_env].env' it will generate '/roro/keys/[staging_env].key'
20
- and '/roro/keys/[circle_ci_env].key'."
21
- map "generate::keys" => "generate_keys"
22
-
23
- def generate_keys(*args)
24
- generate_key(*args)
25
- end
26
-
27
- no_commands do
28
-
29
- def generate_key_or_keys(*args)
30
- environments = args.first ? [args.first] : gather_environments
31
- environments.each do |environment|
32
-
33
- confirm_files_decrypted?(environment)
34
- create_file "roro/keys/#{environment}.key", encoded_key
35
- end
36
- end
37
-
38
- def encoded_key
39
- @cipher = OpenSSL::Cipher.new 'AES-128-CBC'
40
- @salt = '8 octets'
41
- @new_key = @cipher.random_key
42
- Base64.encode64(@new_key)
43
- end
44
-
45
- def gather_environments
46
- environments = []
47
- ['.env', '.env.enc'].each do |extension|
48
- Roro::Crypto.source_files('roro', extension).each do |env_file|
49
- environments << env_file.split('/').last.split(extension).last
50
- end
51
- end
52
- environments.uniq
53
- end
54
-
55
- def confirm_files_decrypted?(environment)
56
- orphan_encrypted = []
57
- Roro::Crypto.source_files('.', '.env.enc').each do |file|
58
- unless File.exist? file.split('.enc').first
59
- orphan_encrypted << file
60
- end
61
- end
62
- if !orphan_encrypted.empty?
63
- raise Roro::Error.new("You have an encrypted files (.env.enc) #{orphan_encrypted} that do not have corresponding decrypted files (.env). Please decrypt or remove these encrypted files before generating a new key for #{environment}.")
64
- end
65
- true
66
- end
67
- end
68
- end
69
- end
@@ -1,17 +0,0 @@
1
- require 'roro/crypto'
2
-
3
- module Roro
4
-
5
- class CLI < Thor
6
-
7
- desc "generate::obfuscated", "obfuscates any files matching the pattern ./roro/**/*.env"
8
- map "generate::obfuscated" => "generate_obfuscated"
9
-
10
- def generate_obfuscated(*args)
11
- environments = args.first ? [args.first] : gather_environments
12
- environments.each do |environment|
13
- Roro::Crypto.obfuscate(environment, 'roro')
14
- end
15
- end
16
- end
17
- end
@@ -1,2 +0,0 @@
1
- CP3WnhLldqGcoPdCRgAkzUiXdTYdd166oDCRsXDbJi+YWczgX53oaJsRNlu8
2
- S/cvOkds770ID3hmbcNXwfyR4A==