roro 0.3.21 → 0.3.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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==