jack-eb 0.0.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 +7 -0
- data/.gitignore +25 -0
- data/.rspec +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +107 -0
- data/Guardfile +12 -0
- data/LICENSE.txt +22 -0
- data/README.md +135 -0
- data/Rakefile +6 -0
- data/bin/jack +9 -0
- data/jack.gemspec +30 -0
- data/lib/jack.rb +14 -0
- data/lib/jack/cli.rb +54 -0
- data/lib/jack/cli/help.rb +107 -0
- data/lib/jack/config.rb +13 -0
- data/lib/jack/config/diff.rb +44 -0
- data/lib/jack/config/download.rb +66 -0
- data/lib/jack/config/sort.rb +19 -0
- data/lib/jack/config/transmit.rb +77 -0
- data/lib/jack/config/upload.rb +97 -0
- data/lib/jack/config/yaml_formatter.rb +30 -0
- data/lib/jack/create.rb +78 -0
- data/lib/jack/default/create.yml +1 -0
- data/lib/jack/ext/hash.rb +17 -0
- data/lib/jack/ui.rb +16 -0
- data/lib/jack/util.rb +20 -0
- data/lib/jack/version.rb +3 -0
- data/lib/jack/version_checker.rb +37 -0
- data/spec/fixtures/project/jack/cfg/stag-rails-app.cfg.yml +3 -0
- data/spec/lib/cli_spec.rb +44 -0
- data/spec/lib/config/diff_spec.rb +21 -0
- data/spec/lib/config/download_spec.rb +19 -0
- data/spec/lib/config/sort_spec.rb +16 -0
- data/spec/lib/config/transmit_spec.rb +41 -0
- data/spec/lib/config/upload_spec.rb +26 -0
- data/spec/lib/config/yaml_formatter_spec.rb +49 -0
- data/spec/lib/config_spec.rb +6 -0
- data/spec/lib/create_spec.rb +34 -0
- data/spec/lib/verison_checker_spec.rb +32 -0
- data/spec/spec_helper.rb +35 -0
- metadata +211 -0
@@ -0,0 +1,107 @@
|
|
1
|
+
module Jack
|
2
|
+
class CLI < Thor
|
3
|
+
class Help
|
4
|
+
class << self
|
5
|
+
def convention
|
6
|
+
<<-EOL
|
7
|
+
The configuration name is based on convention. An environment with the name of stag-rails-app-s1 results in the jack/cfg/stag-rails-app.cfg.yml being used. The convention can be overriden with the --cfg option.
|
8
|
+
EOL
|
9
|
+
end
|
10
|
+
|
11
|
+
def create
|
12
|
+
<<-EOL
|
13
|
+
Creates a new environment using the configuration in jack/cfg folder.
|
14
|
+
|
15
|
+
#{convention}
|
16
|
+
|
17
|
+
Example:
|
18
|
+
|
19
|
+
$ jack create stag-rails-app-s1
|
20
|
+
|
21
|
+
$ jack create -c myconfig stag-rails-app-s1
|
22
|
+
|
23
|
+
$ jack create -a myapp -c myconfig stag-rails-app-s1
|
24
|
+
EOL
|
25
|
+
end
|
26
|
+
|
27
|
+
def upload
|
28
|
+
<<-EOL
|
29
|
+
Uploads the specified template configuration in jack/cfg and applies it to the environment immediately.
|
30
|
+
|
31
|
+
#{convention}
|
32
|
+
|
33
|
+
Example:
|
34
|
+
|
35
|
+
$ jack config upload stag-rails-app-s1
|
36
|
+
|
37
|
+
$ jack config upload -a myapp -c myconfig stag-rails-app-s1
|
38
|
+
EOL
|
39
|
+
end
|
40
|
+
|
41
|
+
def download
|
42
|
+
<<-EOL
|
43
|
+
Downloads the environment's config to jack/cfg/[CONFIG_NAME].cfg.yml
|
44
|
+
|
45
|
+
#{convention}
|
46
|
+
|
47
|
+
Example:
|
48
|
+
|
49
|
+
$ jack config download stag-rails-app-s1
|
50
|
+
|
51
|
+
$ jack config download -a myapp -c myconfig stag-rails-app-s1
|
52
|
+
EOL
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def diff
|
57
|
+
<<-EOL
|
58
|
+
Diff local jack config vs environment config. The environment config is generated on the fly.
|
59
|
+
|
60
|
+
If you have colordiff installed the diff command will use make use of it. If you want to have your own custom diff, you can set your JACK_DIFF environment variable to it.
|
61
|
+
|
62
|
+
#{convention}
|
63
|
+
|
64
|
+
Example:
|
65
|
+
|
66
|
+
$ jack config diff stag-rails-app-s1
|
67
|
+
|
68
|
+
$ jack config diff -a myapp -c myconfig stag-rails-app-s1
|
69
|
+
EOL
|
70
|
+
end
|
71
|
+
|
72
|
+
def sort
|
73
|
+
<<-EOL
|
74
|
+
Reformats local jack config file to a sorted yaml format.
|
75
|
+
|
76
|
+
#{convention}
|
77
|
+
|
78
|
+
Example:
|
79
|
+
|
80
|
+
$ jack config sort stag-rails-app-s1
|
81
|
+
|
82
|
+
$ jack config sort -c myconfig stag-rails-app-s1 # env name doesnt matter here
|
83
|
+
EOL
|
84
|
+
end
|
85
|
+
|
86
|
+
# dumb thor bug, so this doesnt even show, leaving here in case Thor is fixed
|
87
|
+
def config
|
88
|
+
<<-EOL
|
89
|
+
Manage the environment's config. Can use this to download the environment's config to jack/cfg folder or upload config in jack/cfg folder and apply it to the environment.
|
90
|
+
|
91
|
+
Example:
|
92
|
+
|
93
|
+
$ jack config download stag-rails-app-s1
|
94
|
+
|
95
|
+
For more info:
|
96
|
+
|
97
|
+
$ jack help config
|
98
|
+
|
99
|
+
$ jack config help apply
|
100
|
+
|
101
|
+
$ jack config help download
|
102
|
+
EOL
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/jack/config.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Jack
|
4
|
+
module Config
|
5
|
+
autoload :Base, 'jack/config/base'
|
6
|
+
autoload :Diff, 'jack/config/diff'
|
7
|
+
autoload :Download, 'jack/config/download'
|
8
|
+
autoload :Sort, 'jack/config/sort'
|
9
|
+
autoload :Transmit, 'jack/config/transmit'
|
10
|
+
autoload :Upload, 'jack/config/upload'
|
11
|
+
autoload :YamlFormatter, 'jack/config/yaml_formatter'
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Jack
|
2
|
+
module Config
|
3
|
+
class Diff
|
4
|
+
attr_reader :transmit
|
5
|
+
def initialize(options={})
|
6
|
+
@options = options
|
7
|
+
@root = options[:root] || '.'
|
8
|
+
@env_name = options[:env_name]
|
9
|
+
@download = Jack::Config::Download.new(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
@download.get_current_cfg
|
14
|
+
do_diff(@download.current_path, @download.local_config_path)
|
15
|
+
cleanup_files
|
16
|
+
end
|
17
|
+
|
18
|
+
def do_diff(current, local)
|
19
|
+
UI.say "Comparing #{current} and #{local}"
|
20
|
+
return if @options[:noop]
|
21
|
+
sorter = YamlFormatter.new
|
22
|
+
sorter.process(current)
|
23
|
+
sorter.process(local)
|
24
|
+
# need to use system so that the diff shows up properly in the terminal
|
25
|
+
system(diff_command, @download.current_path, @download.local_config_path)
|
26
|
+
puts ""
|
27
|
+
end
|
28
|
+
|
29
|
+
def cleanup_files
|
30
|
+
return false if @options[:dirty]
|
31
|
+
@download.clean(silent=true)
|
32
|
+
end
|
33
|
+
|
34
|
+
def diff_command
|
35
|
+
return ENV['JACK_DIFF'] if ENV['JACK_DIFF']
|
36
|
+
if system("type colordiff > /dev/null 2>&1")
|
37
|
+
"colordiff"
|
38
|
+
else
|
39
|
+
"diff"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Jack
|
5
|
+
module Config
|
6
|
+
class Download < Transmit
|
7
|
+
include Util
|
8
|
+
|
9
|
+
attr_reader :current_path, :current_name
|
10
|
+
|
11
|
+
def initialize(options={})
|
12
|
+
super
|
13
|
+
@current_path = "#{@saved_configs}/current-#{timestamp}.cfg.yml"
|
14
|
+
@current_name = extract_name(@current_path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
download
|
19
|
+
end
|
20
|
+
|
21
|
+
def download
|
22
|
+
get_current_cfg
|
23
|
+
copy_to_local_cfg
|
24
|
+
clean
|
25
|
+
UI.say "Config downloaded to #{@local_config_path}".colorize(:green)
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_current_cfg
|
29
|
+
UI.say "Downloading config file..."
|
30
|
+
eb_config_save
|
31
|
+
end
|
32
|
+
|
33
|
+
# for specs
|
34
|
+
def eb_config_save
|
35
|
+
do_cmd("eb config save --cfg #{current_name} #{@env_name}", @options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def copy_to_local_cfg
|
39
|
+
UI.say "Writing to local config file: #{@local_config_path}"
|
40
|
+
dirname = File.dirname("#{@root}/#{@local_config_path}")
|
41
|
+
FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
|
42
|
+
do_copy_to_local_cfg
|
43
|
+
end
|
44
|
+
|
45
|
+
# for specs
|
46
|
+
def do_copy_to_local_cfg
|
47
|
+
return if @options[:noop]
|
48
|
+
local_path = "#{@root}/#{@local_config_path}"
|
49
|
+
FileUtils.cp(@current_path, local_path)
|
50
|
+
YamlFormatter.new.process(local_path)
|
51
|
+
end
|
52
|
+
|
53
|
+
# remove both the local download file and remote eb config
|
54
|
+
def clean(silent=false)
|
55
|
+
return if @options[:dirty]
|
56
|
+
UI.say "Cleaning up eb remote config and local files" unless silent
|
57
|
+
eb.delete_configuration_template(
|
58
|
+
application_name: @app_name,
|
59
|
+
template_name: current_name
|
60
|
+
) unless @options[:noop]
|
61
|
+
FileUtils.rm_f(@current_path)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Jack
|
4
|
+
module Config
|
5
|
+
class Sort < Transmit # for the local_config_path method
|
6
|
+
include Util
|
7
|
+
|
8
|
+
def initialize(options={})
|
9
|
+
super
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
YamlFormatter.new.process("#{@root}/#{local_config_path}")
|
15
|
+
UI.say "Reformatted the local config to a sorted yaml format at #{local_config_path}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Jack
|
5
|
+
module Config
|
6
|
+
class Transmit
|
7
|
+
include Util
|
8
|
+
|
9
|
+
attr_reader :local_config_path
|
10
|
+
def initialize(options={})
|
11
|
+
@options = options
|
12
|
+
@root = options[:root] || '.'
|
13
|
+
@env_name = options[:env_name]
|
14
|
+
@app_name = @options[:app_name] || app_name_convention(@env_name)
|
15
|
+
|
16
|
+
@saved_configs = "#{@root}/.elasticbeanstalk/saved_configs"
|
17
|
+
|
18
|
+
local_config_name = options[:cfg] || config_name_convention(@env_name)
|
19
|
+
@local_config_path = "jack/cfg/#{local_config_name}.cfg.yml"
|
20
|
+
|
21
|
+
sync_eb_config_yml
|
22
|
+
end
|
23
|
+
|
24
|
+
def eb_config_path
|
25
|
+
"#{@root}/.elasticbeanstalk/config.yml"
|
26
|
+
end
|
27
|
+
|
28
|
+
def sync_eb_config_yml(force=false)
|
29
|
+
# should break out to another class but too much work right now
|
30
|
+
create = Create.new(@options)
|
31
|
+
create.ensure_eb_init
|
32
|
+
do_sync_eb_config_yml(force)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# force flag for specs
|
38
|
+
def do_sync_eb_config_yml(force)
|
39
|
+
return if @options[:noop] and !force
|
40
|
+
envs = describe_environments
|
41
|
+
env = envs[:environments].first
|
42
|
+
if env
|
43
|
+
write_eb_config_yml(env.application_name, env.solution_stack_name)
|
44
|
+
else
|
45
|
+
UI.say "#{@env_name} could not be found".colorize(:red)
|
46
|
+
exit 0
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def write_eb_config_yml(application_name, solution_stack_name)
|
51
|
+
data = YAML.load_file(eb_config_path)
|
52
|
+
data['global']['application_name'] = application_name
|
53
|
+
data['global']['default_platform'] = solution_stack_name
|
54
|
+
dump = YAML.dump(data).gsub("!ruby/object:Hash", '')
|
55
|
+
dump = dump.split("\n")[1..-1].join("\n") # strip first line
|
56
|
+
File.write(eb_config_path, dump)
|
57
|
+
end
|
58
|
+
|
59
|
+
# useful for specs
|
60
|
+
def describe_environments
|
61
|
+
eb.describe_environments(environment_names: [@env_name])
|
62
|
+
end
|
63
|
+
|
64
|
+
def config_name_convention(env_name)
|
65
|
+
env_name.split('-')[0..-2].join('-')
|
66
|
+
end
|
67
|
+
|
68
|
+
def timestamp
|
69
|
+
Time.now.strftime "%Y-%m-%d_%H-%M-%S"
|
70
|
+
end
|
71
|
+
|
72
|
+
def extract_name(path)
|
73
|
+
path.split('/').last.sub('.cfg.yml','')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Jack
|
4
|
+
module Config
|
5
|
+
class Upload < Transmit
|
6
|
+
include Util
|
7
|
+
|
8
|
+
attr_reader :upload_path, :upload_name
|
9
|
+
|
10
|
+
def initialize(options={})
|
11
|
+
super
|
12
|
+
@upload_path = "#{@saved_configs}/#{@env_name}-#{timestamp}.cfg.yml"
|
13
|
+
@upload_name = extract_name(@upload_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
unless local_cfg_exist?
|
18
|
+
UI.say "#{local_config_path} does not exist, nothing to upload"
|
19
|
+
exit 0
|
20
|
+
end
|
21
|
+
compare
|
22
|
+
if confirm
|
23
|
+
upload
|
24
|
+
update_env
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def compare
|
29
|
+
Diff.new(@options).run
|
30
|
+
end
|
31
|
+
|
32
|
+
def upload
|
33
|
+
return false unless local_cfg_exist?
|
34
|
+
UI.say("Copying #{@local_config_path} to #{@upload_path} for the upload")
|
35
|
+
cp_to_save_configs
|
36
|
+
upload_to_eb
|
37
|
+
clean_up
|
38
|
+
end
|
39
|
+
|
40
|
+
def confirm
|
41
|
+
UI.say("Are you sure you want to update the environment with your the new config #{@config_path}?".colorize(:yellow))
|
42
|
+
UI.say(<<-EOL)
|
43
|
+
If the difference is not what you expected, you should say no.
|
44
|
+
A blank newline indicates that there was no difference.
|
45
|
+
If you want to download the config from the environment and
|
46
|
+
overwrite your #{@local_config_path} instead, you can use this command:
|
47
|
+
$ jack config download #{@env_name}
|
48
|
+
$ jack config help download # for more info
|
49
|
+
EOL
|
50
|
+
print "yes/no? [no] " unless @options[:silent]
|
51
|
+
answer = get_answer
|
52
|
+
answer =~ /^y/
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_answer
|
56
|
+
return 'y' if @options[:force]
|
57
|
+
$stdin.gets
|
58
|
+
end
|
59
|
+
|
60
|
+
def update_env
|
61
|
+
UI.say("Updating environment #{@env_name} with template #{upload_name}")
|
62
|
+
eb.update_environment(
|
63
|
+
environment_name: @env_name,
|
64
|
+
template_name: upload_name
|
65
|
+
) unless @options[:noop]
|
66
|
+
end
|
67
|
+
|
68
|
+
def local_cfg_exist?
|
69
|
+
File.exist?("#{@root}/#{@local_config_path}")
|
70
|
+
end
|
71
|
+
|
72
|
+
def cp_to_save_configs
|
73
|
+
ensure_folder_exist(@saved_configs)
|
74
|
+
FileUtils.cp("#{@root}/#{@local_config_path}", @upload_path)
|
75
|
+
end
|
76
|
+
|
77
|
+
def upload_to_eb
|
78
|
+
eb_config_put
|
79
|
+
end
|
80
|
+
|
81
|
+
# for specs
|
82
|
+
def eb_config_put
|
83
|
+
do_cmd("eb config put #{upload_name}", @options)
|
84
|
+
end
|
85
|
+
|
86
|
+
def clean_up
|
87
|
+
return if @options[:dirty]
|
88
|
+
FileUtils.rm_f(@upload_path)
|
89
|
+
end
|
90
|
+
|
91
|
+
def ensure_folder_exist(folder)
|
92
|
+
FileUtils.mkdir_p(folder) unless File.exist?(folder)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
module Jack
|
4
|
+
module Config
|
5
|
+
# Class does very specific formatting for the eb config files:
|
6
|
+
#
|
7
|
+
# * Makes sure that the keys are sorted so we can compare them
|
8
|
+
# * It also scripts out the generated DateModified and DateCreated Metadata
|
9
|
+
class YamlFormatter
|
10
|
+
def process(file)
|
11
|
+
data = YAML.load_file(file)
|
12
|
+
data = strip_metadata_dates(data)
|
13
|
+
dump = YAML.dump(data).gsub("!ruby/object:Hash", '')
|
14
|
+
dump = dump.split("\n")[1..-1].join("\n") + "\n" # strip first line
|
15
|
+
outfile = "#{file}.sorted"
|
16
|
+
File.open(outfile, 'w') { |f| f.write(dump) }
|
17
|
+
FileUtils.mv(outfile, file)
|
18
|
+
end
|
19
|
+
|
20
|
+
def strip_metadata_dates(data)
|
21
|
+
metadata = data['EnvironmentConfigurationMetadata']
|
22
|
+
if metadata
|
23
|
+
metadata.delete('DateModified')
|
24
|
+
metadata.delete('DateCreated')
|
25
|
+
end
|
26
|
+
data
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|