aldagai 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|