aldagai 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/README.md +77 -19
- data/aldagai.gemspec +14 -10
- data/exe/aldagai +6 -0
- data/lib/aldagai.rb +6 -5
- data/lib/aldagai/cli.rb +65 -0
- data/lib/aldagai/colors.rb +37 -0
- data/lib/aldagai/config.rb +21 -0
- data/lib/aldagai/encryptor.rb +25 -0
- data/lib/aldagai/exceptions/base_exception.rb +4 -0
- data/lib/aldagai/exceptions/editor_not_present_exception.rb +17 -0
- data/lib/aldagai/exceptions/not_enoght_variables_exception.rb +20 -0
- data/lib/aldagai/generators/install.rb +47 -0
- data/lib/aldagai/generators/install/.aldagai.secret +1 -0
- data/lib/aldagai/generators/install/.development +0 -0
- data/lib/aldagai/generators/install/.production +0 -0
- data/lib/aldagai/generators/install/.staging +0 -0
- data/lib/aldagai/variable_manager_facade.rb +17 -0
- data/lib/aldagai/variable_managers/base.rb +199 -0
- data/lib/aldagai/variable_managers/interactive.rb +38 -0
- data/lib/aldagai/variable_managers/normal.rb +5 -0
- data/lib/aldagai/version.rb +1 -1
- metadata +64 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb870504be79756afb9a198fb22d7a3f70159c6b7c748a94f159c534689e0b1e
|
4
|
+
data.tar.gz: 8e834230479e131361e3f502c667d4c00f203d4b438df9a9731a326d71500bbf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 536b96db6c9b648697cf3a1854600fd452f3bcad36b712525f3e0bb1074158f57e65db6fbf180da7a16d00740683f33fc8d588dfea873d92db4cfc4894961a32
|
7
|
+
data.tar.gz: bea9d7b28248de1e0c4d31c9775c398cb5e6ffed4a302121728e2fec92e02060c90bd798afc2dc9f2d5f402eb506b98c83a25363c75b88ef84c0e685d6afeb44
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/README.md
CHANGED
@@ -1,35 +1,93 @@
|
|
1
|
-
|
1
|
+
The aim of this gem is to help developers promoting heroku variables during the deployment process.
|
2
2
|
|
3
|
-
|
3
|
+
## Getting Started
|
4
4
|
|
5
|
-
|
5
|
+
* Add aldagai to you Gemfile
|
6
6
|
|
7
|
-
|
7
|
+
```
|
8
|
+
source 'https://rubygems.org'
|
8
9
|
|
9
|
-
|
10
|
+
# More gems
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
```
|
12
|
+
gem 'aldagai', '0.1.1'
|
13
|
+
```
|
14
14
|
|
15
|
-
|
15
|
+
* Run the following command to install aldagai in your application
|
16
16
|
|
17
|
-
$ bundle
|
17
|
+
$ bundle exec aldagai install
|
18
18
|
|
19
|
-
|
19
|
+
This command will create the file `.aldagai.secret` with the secret used to encrypt your
|
20
|
+
variables, and one file for each of the environments. This command will also add the
|
21
|
+
`.aldagai.secret` to your `.gitignore` file.
|
20
22
|
|
21
|
-
|
23
|
+
* Add a new environment variable to each of your applications on the pipeline (by default we assume
|
24
|
+
that you have 3 different environments development, staging, and production) with the name
|
25
|
+
`ALDAGAI_SECRET` containing the same string that you have on the file `.aldagai.secret`
|
22
26
|
|
23
|
-
|
27
|
+
$ heroku config:set ALDAGAI_SECRET="MySuperSecretPasswordUsingForEncryptTheMessage" -a yourapp
|
24
28
|
|
25
|
-
|
29
|
+
* Generate a new api token to intereact with heroku api
|
26
30
|
|
27
|
-
|
31
|
+
$ heroku plugins:install heroku-cli-oauth
|
32
|
+
$ heroku authorizations:create -d "YouApp"
|
28
33
|
|
29
|
-
|
34
|
+
* Add a new environment variables to intereact with heroku api. One of those variables should be
|
35
|
+
named `ALDAGAI_HEROKU_TOKEN` with the value that was generated by the previous command, and the
|
36
|
+
other one should be named `ALDAGAI_APP_NAME` with the name of the application in heroku, and
|
37
|
+
then another one named `ALDAGAI_PIPELINE_ENV` indicating the envrionment of the PIPELINE for
|
38
|
+
example `development`.
|
30
39
|
|
31
|
-
|
40
|
+
### Aldagai Generators
|
32
41
|
|
33
|
-
|
42
|
+
#### install
|
34
43
|
|
35
|
-
|
44
|
+
$ bundle exec aldagai install
|
45
|
+
|
46
|
+
Install aldagai on your application
|
47
|
+
|
48
|
+
### Aldagai Commands
|
49
|
+
|
50
|
+
A list of all commands available through aldagai with their different options
|
51
|
+
|
52
|
+
#### add
|
53
|
+
|
54
|
+
*Normal Mode*
|
55
|
+
|
56
|
+
$ bundle exec aldagai add VARIABLE_NAME --values 1 2 3
|
57
|
+
|
58
|
+
Values are the variables that are going to be promoted to the different environments (by default we
|
59
|
+
use 3 environments development, staging, and production)
|
60
|
+
|
61
|
+
*Interactive Mode*
|
62
|
+
|
63
|
+
$ export EDITOR=vim
|
64
|
+
$ bundle exec aldagai add VARIABLE_NAME -i
|
65
|
+
|
66
|
+
Variables values are obtained from what you type on your prefered editor, values are separated by a
|
67
|
+
blank line.
|
68
|
+
|
69
|
+
#### show
|
70
|
+
|
71
|
+
$ bundle exec aldagai show VARIABLE_NAME
|
72
|
+
|
73
|
+
Show the VARIABLE_NAME if that variable is going to be deployed (either if is going to be removed or
|
74
|
+
modified, this is checked locally)
|
75
|
+
|
76
|
+
#### list
|
77
|
+
|
78
|
+
$ bundle exec aldagai list
|
79
|
+
|
80
|
+
Show all variables that are going to be deployed (either if is going to be removed or modified, this
|
81
|
+
is checked locally)
|
82
|
+
|
83
|
+
#### delete
|
84
|
+
|
85
|
+
$ bundle exec aldagai delete
|
86
|
+
|
87
|
+
Enqueue a variable to be deleted.
|
88
|
+
|
89
|
+
#### clear
|
90
|
+
|
91
|
+
Clear all file, creating a new start point for the next deploy.
|
92
|
+
|
93
|
+
Note: Variables that are already and are identicall to what heroku has are not being promoted.
|
data/aldagai.gemspec
CHANGED
@@ -1,25 +1,29 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require 'aldagai/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'aldagai'
|
8
8
|
spec.version = Aldagai::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Pablo Ifran']
|
10
|
+
spec.email = ['pabloifran@gmail.com']
|
11
11
|
|
12
|
-
spec.summary =
|
12
|
+
spec.summary = 'Promote environment variables on heroku'
|
13
13
|
spec.description = 'Make zero downtime deployments easier allowing developers to promote environment variables'
|
14
14
|
spec.homepage = 'https://github.com/elpic/aldagai'
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
17
|
f.match(%r{^(test|spec|features)/})
|
18
18
|
end
|
19
|
-
spec.bindir =
|
19
|
+
spec.bindir = 'exe'
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
-
spec.require_paths = [
|
21
|
+
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.
|
24
|
-
spec.
|
23
|
+
spec.add_dependency 'platform-api', '~> 2.1.0'
|
24
|
+
spec.add_dependency 'thor'
|
25
|
+
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.15'
|
27
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.2'
|
25
29
|
end
|
data/exe/aldagai
ADDED
data/lib/aldagai.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
require 'openssl'
|
2
|
+
require 'digest'
|
3
|
+
require 'aldagai/version'
|
4
|
+
require 'aldagai/version'
|
5
|
+
require 'aldagai/config'
|
6
|
+
require 'aldagai/encryptor'
|
data/lib/aldagai/cli.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'aldagai/colors'
|
3
|
+
require 'aldagai/variable_manager_facade'
|
4
|
+
require 'aldagai/generators/install'
|
5
|
+
require 'aldagai/exceptions/base_exception'
|
6
|
+
require 'aldagai/exceptions/not_enoght_variables_exception'
|
7
|
+
|
8
|
+
module Aldagai
|
9
|
+
class CLI < Thor
|
10
|
+
using Aldagai::Colors
|
11
|
+
|
12
|
+
desc 'install', 'Install aldagai in your application'
|
13
|
+
def install
|
14
|
+
Aldagai::Generators::Install.start
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'add NAME', 'Add a variable with NAME to be promoted to all environments'
|
18
|
+
method_option :values, type: :array, required: false, default: []
|
19
|
+
method_option :interactive, type: :boolean, default: false, aliases: '-i'
|
20
|
+
def add(name)
|
21
|
+
@manager = Aldagai::VariableManagerFacade.build_for(options[:interactive])
|
22
|
+
|
23
|
+
@manager.add(name, options[:values])
|
24
|
+
rescue Aldagai::BaseException => exception
|
25
|
+
puts exception.to_s.red
|
26
|
+
exit(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'clear', 'Clear all the variables that were deployed usefull after a deploy'
|
30
|
+
def clear
|
31
|
+
@manager = Aldagai::NormalVariableManager.new
|
32
|
+
|
33
|
+
@manager.clear
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'delete NAME', 'Delete the variable with NAME, this will be promoted to all environments'
|
37
|
+
def delete(name)
|
38
|
+
@manager = Aldagai::NormalVariableManager.new
|
39
|
+
|
40
|
+
@manager.delete(name)
|
41
|
+
end
|
42
|
+
|
43
|
+
desc 'show NAME', 'Show the variable NAME that is going to be promoted to all environments'
|
44
|
+
def show(name)
|
45
|
+
@manager = Aldagai::NormalVariableManager.new
|
46
|
+
|
47
|
+
@manager.show(name)
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'list', 'Show all variables that are going to be promoted'
|
51
|
+
def list
|
52
|
+
@manager = Aldagai::NormalVariableManager.new
|
53
|
+
|
54
|
+
@manager.list
|
55
|
+
end
|
56
|
+
|
57
|
+
desc 'set', 'set'
|
58
|
+
def set
|
59
|
+
@manager = Aldagai::NormalVariableManager.new
|
60
|
+
|
61
|
+
@manager.set
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Aldagai
|
2
|
+
module Colors
|
3
|
+
|
4
|
+
refine String do
|
5
|
+
|
6
|
+
def red
|
7
|
+
colorize(31)
|
8
|
+
end
|
9
|
+
|
10
|
+
def green
|
11
|
+
colorize(32)
|
12
|
+
end
|
13
|
+
|
14
|
+
def yellow
|
15
|
+
colorize(33)
|
16
|
+
end
|
17
|
+
|
18
|
+
def blue
|
19
|
+
colorize(34)
|
20
|
+
end
|
21
|
+
|
22
|
+
def pink
|
23
|
+
colorize(35)
|
24
|
+
end
|
25
|
+
|
26
|
+
def light_blue
|
27
|
+
colorize(36)
|
28
|
+
end
|
29
|
+
|
30
|
+
def colorize(color_code)
|
31
|
+
"\e[#{color_code}m#{self}\e[0m"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Aldagai
|
2
|
+
class Config
|
3
|
+
|
4
|
+
def secret
|
5
|
+
ENV['ALDAGAI_SECRET'] || read_secret_from_file
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def read_secret_from_file
|
11
|
+
path = File.expand_path('./.aldagai.secret')
|
12
|
+
|
13
|
+
if File.exists?(path)
|
14
|
+
File.read(path)
|
15
|
+
else
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Aldagai
|
2
|
+
class Encryptor
|
3
|
+
|
4
|
+
def initialize(secret)
|
5
|
+
@secret = secret
|
6
|
+
end
|
7
|
+
|
8
|
+
def encrypt(plain)
|
9
|
+
cipher = OpenSSL::Cipher::AES256.new(:CBC).encrypt
|
10
|
+
cipher.key = Digest::SHA256.digest(@secret)
|
11
|
+
|
12
|
+
(cipher.update(plain) + cipher.final).unpack('H*')[0].upcase
|
13
|
+
end
|
14
|
+
|
15
|
+
def decrypt(encrypted)
|
16
|
+
cipher = OpenSSL::Cipher::AES256.new(:CBC).decrypt
|
17
|
+
cipher.key = Digest::SHA256.digest(@secret)
|
18
|
+
|
19
|
+
string = [encrypted].pack('H*').unpack('C*').pack('c*')
|
20
|
+
|
21
|
+
cipher.update(string) + cipher.final
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative './base_exception'
|
2
|
+
|
3
|
+
module Aldagai
|
4
|
+
class EditorNotPresentException < Aldagai::BaseException
|
5
|
+
|
6
|
+
def to_s
|
7
|
+
message = <<-MESSAGE
|
8
|
+
In order to access interactive mode you neet to set an environment variable with the editor
|
9
|
+
you want to use. For example you can run the following command on a terminal
|
10
|
+
export EDITOR=vim. This will use vim to enter your variables.
|
11
|
+
MESSAGE
|
12
|
+
|
13
|
+
message.gsub(/\s+/, ' ').strip
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative './base_exception'
|
2
|
+
|
3
|
+
module Aldagai
|
4
|
+
class NotEnoghtVariablesException < Aldagai::BaseException
|
5
|
+
|
6
|
+
def initialize(required_variables)
|
7
|
+
@required_variables = required_variables
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
message = <<-MESSAGE
|
12
|
+
Not enoght variables, #{@required_variables} are required. You can set them
|
13
|
+
using --values (-v) for normal mode or your preferred editor using interactive mode (-i)
|
14
|
+
MESSAGE
|
15
|
+
|
16
|
+
message.gsub(/\s+/, ' ').strip
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'thor/group'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module Aldagai
|
5
|
+
module Generators
|
6
|
+
class Install < Thor::Group
|
7
|
+
|
8
|
+
include Thor::Actions
|
9
|
+
|
10
|
+
def self.source_root
|
11
|
+
File.dirname(__FILE__) + '/install'
|
12
|
+
end
|
13
|
+
|
14
|
+
def copy_secret
|
15
|
+
template('.aldagai.secret', '.aldagai.secret')
|
16
|
+
end
|
17
|
+
|
18
|
+
def copy_environments
|
19
|
+
template('.development', '.development')
|
20
|
+
template('.staging', '.staging')
|
21
|
+
template('.production', '.production')
|
22
|
+
end
|
23
|
+
|
24
|
+
def ignore_secret
|
25
|
+
create_file '.gitignore', '', skip: true
|
26
|
+
append_to_file '.gitignore', '.aldagai.secret'
|
27
|
+
end
|
28
|
+
|
29
|
+
def say_next_instructions
|
30
|
+
say ''
|
31
|
+
say 'What is next:', :blue
|
32
|
+
say ''
|
33
|
+
say '* Run `$ heroku plugins:install heroku-cli-oauth`', :blue
|
34
|
+
say '* Run `$ heroku authorizations:create -d "YouApp"` and copy the Token', :blue
|
35
|
+
say '* Set ALDAGAI_HEROKU_TOKEN on heroku with the Token that was just generated', :blue
|
36
|
+
say '* Set ALDAGAI_APP_NAME on heroku with the name of the application', :blue
|
37
|
+
say '* Set ALDAGAI_PIPELINE_ENV on heroku with the name of the environment on the pipeline', :blue
|
38
|
+
say '* Add `bundle exec aldagai set` to release part on the Procfile', :blue
|
39
|
+
say ''
|
40
|
+
say 'For more information about release phase go to ' +
|
41
|
+
'https://devcenter.heroku.com/articles/release-phase', :green
|
42
|
+
say ''
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= SecureRandom.hex %>
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'aldagai/variable_managers/base'
|
2
|
+
require 'aldagai/variable_managers/interactive'
|
3
|
+
require 'aldagai/variable_managers/normal'
|
4
|
+
|
5
|
+
module Aldagai
|
6
|
+
class VariableManagerFacade
|
7
|
+
|
8
|
+
def self.build_for(interactive)
|
9
|
+
if interactive
|
10
|
+
Aldagai::InteractiveVariableManager.new
|
11
|
+
else
|
12
|
+
Aldagai::NormalVariableManager.new
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'platform-api'
|
2
|
+
require 'aldagai/colors'
|
3
|
+
|
4
|
+
module Aldagai
|
5
|
+
class VariableManager
|
6
|
+
using Aldagai::Colors
|
7
|
+
|
8
|
+
DEFAULT_ENVIRONMENTS = [
|
9
|
+
'development',
|
10
|
+
'staging',
|
11
|
+
'production',
|
12
|
+
]
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@config = Aldagai::Config.new
|
16
|
+
@encryptor = Aldagai::Encryptor.new(@config.secret)
|
17
|
+
end
|
18
|
+
|
19
|
+
def add(name, variables)
|
20
|
+
if environments.length == variables.length
|
21
|
+
environments.zip(variables).each do |environment, value|
|
22
|
+
lines = lines_for_environment_without(environment, name)
|
23
|
+
|
24
|
+
rewrite_file_with_lines(environment, lines) do |file|
|
25
|
+
file.puts @encryptor.encrypt("#{name.upcase}=#{value}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
else
|
29
|
+
raise Aldagai::NotEnoghtVariablesException.new(environments.length)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete(name)
|
34
|
+
environments.each do |environment|
|
35
|
+
lines = lines_for_environment_without(environment, name)
|
36
|
+
|
37
|
+
rewrite_file_with_lines(environment, lines) do |file|
|
38
|
+
file.puts @encryptor.encrypt("#{name.upcase}=")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def show(name)
|
44
|
+
puts "\n ==== Variable actions ====\n".blue
|
45
|
+
|
46
|
+
environments.each do |environment|
|
47
|
+
line = line_for_environment_with(environment, name)
|
48
|
+
|
49
|
+
if line
|
50
|
+
name, value = line.split('=')
|
51
|
+
value = value_presence(value)
|
52
|
+
|
53
|
+
log_variable_will_be_added_or_removed(name, value, environment)
|
54
|
+
else
|
55
|
+
log_no_variables_promoted(environment)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
log_empty_line
|
60
|
+
end
|
61
|
+
|
62
|
+
def list
|
63
|
+
puts "\n ==== Variable actions ====\n".blue
|
64
|
+
|
65
|
+
environments.each do |environment|
|
66
|
+
lines = lines_for_environment(environment)
|
67
|
+
|
68
|
+
if lines.empty?
|
69
|
+
log_no_variables_promoted(environment)
|
70
|
+
else
|
71
|
+
lines.each do |line|
|
72
|
+
name, value = line.split('=')
|
73
|
+
value = value_presence(value)
|
74
|
+
|
75
|
+
log_variable_will_be_added_or_removed(name, value, environment)
|
76
|
+
end
|
77
|
+
|
78
|
+
log_empty_line
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
log_empty_line
|
83
|
+
end
|
84
|
+
|
85
|
+
def clear
|
86
|
+
environments.each do |environment|
|
87
|
+
rewrite_file_with_lines(environment, [])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def set
|
92
|
+
heroku = PlatformAPI.connect_oauth(ENV['ALDAGAI_HEROKU_TOKEN'])
|
93
|
+
lines = lines_for_environment(ENV['ALDAGAI_PIPELINE_ENV'])
|
94
|
+
|
95
|
+
if lines.empty?
|
96
|
+
log_no_variables_promoted(environment)
|
97
|
+
else
|
98
|
+
variables = {}
|
99
|
+
|
100
|
+
lines.each do |line|
|
101
|
+
name, value = line.split('=')
|
102
|
+
value = value_presence(value)
|
103
|
+
|
104
|
+
log_variable_was_added_or_removed(name, value)
|
105
|
+
|
106
|
+
variables.merge!({name => value})
|
107
|
+
end
|
108
|
+
|
109
|
+
heroku.config_var.update(ENV['ALDAGAI_APP_NAME'], variables)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def environments
|
116
|
+
DEFAULT_ENVIRONMENTS
|
117
|
+
end
|
118
|
+
|
119
|
+
def rewrite_file_with_lines(environment, lines, &block)
|
120
|
+
open(environment_file(environment), 'w') do |file|
|
121
|
+
file.truncate(0)
|
122
|
+
|
123
|
+
lines.each do |line|
|
124
|
+
file.puts line
|
125
|
+
end
|
126
|
+
|
127
|
+
block.call(file) if block_given?
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def log_empty_line
|
132
|
+
puts ''
|
133
|
+
end
|
134
|
+
|
135
|
+
def log_variable_will_be_added_or_removed(name, value, environment)
|
136
|
+
if value
|
137
|
+
puts " ➥ add variable \"#{name}\" with value \"#{value}\" in #{environment}".green
|
138
|
+
else
|
139
|
+
puts " ➥ remove variable \"#{name}\" from #{environment}".red
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def log_variable_was_added_or_removed(name, value)
|
144
|
+
if value
|
145
|
+
puts " ➥ variable \"#{name}\" was added".green
|
146
|
+
else
|
147
|
+
puts " ➥ variable \"#{name}\" was removed".red
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def log_no_variables_promoted(environment)
|
152
|
+
puts " ✘ no variable/s are not going to be promoted to #{environment}".red
|
153
|
+
end
|
154
|
+
|
155
|
+
def lines_for_environment(environment)
|
156
|
+
file = environment_file(environment)
|
157
|
+
lines = File.exists?(file) && File.readlines(file) || []
|
158
|
+
|
159
|
+
lines.map(&decrypt_line_proc)
|
160
|
+
end
|
161
|
+
|
162
|
+
def lines_for_environment_without(environment, name)
|
163
|
+
lines_for_environment(environment).select(&does_not_match_line_proc(name))
|
164
|
+
end
|
165
|
+
|
166
|
+
def lines_for_environment_with(environment, name)
|
167
|
+
lines_for_environment(environment).select(&match_line_proc(name))
|
168
|
+
end
|
169
|
+
|
170
|
+
def line_for_environment_with(environment, name)
|
171
|
+
lines_for_environment(environment).find(&match_line_proc(name))
|
172
|
+
end
|
173
|
+
|
174
|
+
def decrypt_line_proc
|
175
|
+
proc { |line| (decrypt_line(line)) }
|
176
|
+
end
|
177
|
+
|
178
|
+
def match_line_proc(name)
|
179
|
+
proc { |line| (line.start_with?("#{name.upcase}=")) }
|
180
|
+
end
|
181
|
+
|
182
|
+
def does_not_match_line_proc(name)
|
183
|
+
proc { |line| !(line.start_with?("#{name.upcase}=")) }
|
184
|
+
end
|
185
|
+
|
186
|
+
def environment_file(environment)
|
187
|
+
File.expand_path("./.#{environment}")
|
188
|
+
end
|
189
|
+
|
190
|
+
def decrypt_line(line)
|
191
|
+
@encryptor.decrypt(line.gsub("\n", ''))
|
192
|
+
end
|
193
|
+
|
194
|
+
def value_presence(value)
|
195
|
+
value && value.strip != '' ? value : nil
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
module Aldagai
|
4
|
+
class InteractiveVariableManager < VariableManager
|
5
|
+
|
6
|
+
def add(name, _variables)
|
7
|
+
if ENV['EDITOR'].nil?
|
8
|
+
raise Aldagai::EditorNotPresentException.new
|
9
|
+
end
|
10
|
+
|
11
|
+
super(name, process_variables)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def process_variables
|
17
|
+
@read_variables ||= read_variables
|
18
|
+
end
|
19
|
+
|
20
|
+
def read_variables
|
21
|
+
file = nil
|
22
|
+
|
23
|
+
begin
|
24
|
+
file = Tempfile.new('variables')
|
25
|
+
|
26
|
+
system("#{ENV['EDITOR']} #{file.path}")
|
27
|
+
|
28
|
+
(file.read || '').split("\n")
|
29
|
+
ensure
|
30
|
+
if file
|
31
|
+
file.close
|
32
|
+
file.unlink
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
data/lib/aldagai/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aldagai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pablo Ifran
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04
|
11
|
+
date: 2018-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: platform-api
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
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'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: bundler
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,22 +66,55 @@ dependencies:
|
|
38
66
|
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.2'
|
41
83
|
description: Make zero downtime deployments easier allowing developers to promote
|
42
84
|
environment variables
|
43
85
|
email:
|
44
86
|
- pabloifran@gmail.com
|
45
|
-
executables:
|
87
|
+
executables:
|
88
|
+
- aldagai
|
46
89
|
extensions: []
|
47
90
|
extra_rdoc_files: []
|
48
91
|
files:
|
49
92
|
- ".gitignore"
|
93
|
+
- ".rspec"
|
50
94
|
- Gemfile
|
51
95
|
- README.md
|
52
96
|
- Rakefile
|
53
97
|
- aldagai.gemspec
|
54
98
|
- bin/console
|
55
99
|
- bin/setup
|
100
|
+
- exe/aldagai
|
56
101
|
- lib/aldagai.rb
|
102
|
+
- lib/aldagai/cli.rb
|
103
|
+
- lib/aldagai/colors.rb
|
104
|
+
- lib/aldagai/config.rb
|
105
|
+
- lib/aldagai/encryptor.rb
|
106
|
+
- lib/aldagai/exceptions/base_exception.rb
|
107
|
+
- lib/aldagai/exceptions/editor_not_present_exception.rb
|
108
|
+
- lib/aldagai/exceptions/not_enoght_variables_exception.rb
|
109
|
+
- lib/aldagai/generators/install.rb
|
110
|
+
- lib/aldagai/generators/install/.aldagai.secret
|
111
|
+
- lib/aldagai/generators/install/.development
|
112
|
+
- lib/aldagai/generators/install/.production
|
113
|
+
- lib/aldagai/generators/install/.staging
|
114
|
+
- lib/aldagai/variable_manager_facade.rb
|
115
|
+
- lib/aldagai/variable_managers/base.rb
|
116
|
+
- lib/aldagai/variable_managers/interactive.rb
|
117
|
+
- lib/aldagai/variable_managers/normal.rb
|
57
118
|
- lib/aldagai/version.rb
|
58
119
|
homepage: https://github.com/elpic/aldagai
|
59
120
|
licenses: []
|