jack-eb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/jack/create.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
module Jack
|
4
|
+
class Create
|
5
|
+
include Util
|
6
|
+
|
7
|
+
def initialize(options={})
|
8
|
+
@options = options
|
9
|
+
@root = options[:root] || '.'
|
10
|
+
@env_name = options[:env_name]
|
11
|
+
@app_name = options[:app_name] || app_name_convention(@env_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
ensure_eb_init
|
16
|
+
create_env
|
17
|
+
end
|
18
|
+
|
19
|
+
def ensure_eb_init
|
20
|
+
unless File.exist?("#{@root}/.elasticbeanstalk/config.yml")
|
21
|
+
do_cmd(%Q|eb init -p "#{platform}" "#{@app_name}"|, @options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def platform
|
26
|
+
create_yaml['platform'] || latest_docker_platform
|
27
|
+
end
|
28
|
+
|
29
|
+
def latest_docker_platform
|
30
|
+
return if @options[:noop] # for cli spec
|
31
|
+
solution_stacks.grep(/Docker/).reject {|x| x =~ /Preconfigured/}.sort.last
|
32
|
+
end
|
33
|
+
|
34
|
+
# for specs
|
35
|
+
def solution_stacks
|
36
|
+
eb.list_available_solution_stacks.solution_stacks
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_env
|
40
|
+
command = build_command
|
41
|
+
do_cmd(command, @options)
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_command
|
45
|
+
@cfg = upload_cfg
|
46
|
+
flags = create_yaml.inject("") {|s,(k,v)| s << %{--#{k} "#{v}" } ; s }.strip
|
47
|
+
"eb create --nohang #{flags} #{@cfg}#{cname}#{@env_name}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def create_yaml
|
51
|
+
return @create_yaml if @create_yaml
|
52
|
+
|
53
|
+
project_file = "#{@root}/jack/create.yml"
|
54
|
+
project = File.exist?(project_file) ? YAML.load_file(project_file) : {}
|
55
|
+
|
56
|
+
user_file = "#{ENV['HOME']}/.jack/create.yml"
|
57
|
+
user = File.exist?(user_file) ? YAML.load_file(user_file) : {}
|
58
|
+
|
59
|
+
default_file = File.expand_path("../default/create.yml", __FILE__)
|
60
|
+
default = YAML.load_file(default_file)
|
61
|
+
|
62
|
+
@create_yaml = default.merge(project.merge(user))
|
63
|
+
end
|
64
|
+
|
65
|
+
def upload_cfg
|
66
|
+
@upload = Config::Upload.new(@options)
|
67
|
+
if @upload.local_cfg_exist?
|
68
|
+
@upload.upload
|
69
|
+
cfg = "--cfg #{@upload.upload_name} "
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def cname
|
74
|
+
"--cname #{@env_name} "
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
keyname: default
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# http://www.dzone.com/snippets/generating-yaml-hashes-sorted
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
class Hash
|
5
|
+
# Replacing the to_yaml function so it'll serialize hashes sorted (by their keys)
|
6
|
+
#
|
7
|
+
# Original function is in /usr/lib/ruby/1.8/yaml/rubytypes.rb
|
8
|
+
def to_yaml( opts = {} )
|
9
|
+
YAML::quick_emit( object_id, opts ) do |out|
|
10
|
+
out.map( taguri, to_yaml_style ) do |map|
|
11
|
+
sort.each do |k, v| # <-- here's my addition (the 'sort')
|
12
|
+
map.add( k, v )
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/jack/ui.rb
ADDED
data/lib/jack/util.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Jack
|
2
|
+
module Util
|
3
|
+
def do_cmd(command, options={})
|
4
|
+
UI.say "Running: #{command.colorize(:green)}" unless options[:silent]
|
5
|
+
return command if options[:noop]
|
6
|
+
out = `#{command}`
|
7
|
+
UI.say out unless options[:silent]
|
8
|
+
end
|
9
|
+
|
10
|
+
def app_name_convention(env_name)
|
11
|
+
env_name.split('-')[1] # convention
|
12
|
+
end
|
13
|
+
|
14
|
+
def eb
|
15
|
+
region = ENV['AWS_REGION'] || 'us-east-1'
|
16
|
+
@@eb ||= Aws::ElasticBeanstalk::Client.new(region: region)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
data/lib/jack/version.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Jack
|
2
|
+
class VersionChecker
|
3
|
+
REQUIRED_VERSION = "3.1.2"
|
4
|
+
|
5
|
+
def run
|
6
|
+
leave("eb cli tool is not installed") unless system("type eb > /dev/null 2>&1")
|
7
|
+
leave("eb version is too low") unless check
|
8
|
+
end
|
9
|
+
|
10
|
+
def check
|
11
|
+
major, minor, patch = parse_version(get_version)
|
12
|
+
r_major, r_minor, r_patch = normalize_version(REQUIRED_VERSION)
|
13
|
+
(major > r_major) ||
|
14
|
+
(major == r_major && minor > r_minor) ||
|
15
|
+
(major == r_major && minor == r_minor && patch >= r_patch)
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_version
|
19
|
+
`eb --version`
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_version(version)
|
23
|
+
parsed = version.match(/EB CLI (\d+\.\d+\.\d+)/)[1]
|
24
|
+
normalize_version(parsed)
|
25
|
+
end
|
26
|
+
|
27
|
+
def normalize_version(parsed)
|
28
|
+
parsed.split('.').collect(&:to_i)
|
29
|
+
end
|
30
|
+
|
31
|
+
# for specs
|
32
|
+
def leave(message='')
|
33
|
+
puts("SORRY: #{message}, please install at least version #{REQUIRED_VERSION}")
|
34
|
+
exit 0
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jack::CLI do
|
4
|
+
before(:all) do
|
5
|
+
@args = "stag-rails-app-s9 --root spec/fixtures/project --noop --force"
|
6
|
+
FileUtils.rm_rf("spec/fixtures/project/.elasticbeanstalk")
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "jack" do
|
10
|
+
it "should create environment" do
|
11
|
+
out = execute("bin/jack create #{@args}")
|
12
|
+
# puts out
|
13
|
+
expect(out).to include('eb create')
|
14
|
+
expect(out).to include('--cname stag-rails-app-s9')
|
15
|
+
expect(out).to include('--keyname "default"')
|
16
|
+
expect(out).to include('--cfg stag-rails-app')
|
17
|
+
expect(out).to include('stag-rails-app-s9')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should upload and apply config to environment" do
|
21
|
+
out = execute("bin/jack config upload #{@args}")
|
22
|
+
# puts out
|
23
|
+
expect(out).to include('eb config put')
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should download config from environment" do
|
27
|
+
out = execute("bin/jack config download #{@args}")
|
28
|
+
# puts out
|
29
|
+
expect(out).to include("Config downloaded")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should diff local config from eb environment config" do
|
33
|
+
out = execute("bin/jack config diff #{@args}")
|
34
|
+
# puts out
|
35
|
+
expect(out).to include("Comparing")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should reformat the local config to a sorted yaml format" do
|
39
|
+
out = execute("bin/jack config sort #{@args}")
|
40
|
+
# puts out
|
41
|
+
expect(out).to include("Reformatted the local config")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jack::Config do
|
4
|
+
before(:all) do
|
5
|
+
Jack::UI.mute = true
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:diff) { Jack::Config::Diff.new(test_options) }
|
9
|
+
|
10
|
+
describe "diff" do
|
11
|
+
it "diff do_diff" do
|
12
|
+
expect(diff).to receive(:do_diff)
|
13
|
+
diff.run
|
14
|
+
end
|
15
|
+
|
16
|
+
it "diff diff_command" do
|
17
|
+
command = diff.diff_command
|
18
|
+
expect(command).to match /diff/
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jack::Config do
|
4
|
+
before(:all) do
|
5
|
+
Jack::UI.mute = true
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:download) { Jack::Config::Download.new(test_options) }
|
9
|
+
|
10
|
+
describe "download" do
|
11
|
+
it "download" do
|
12
|
+
# mock methods way down deep to test code paths, test reads weird though
|
13
|
+
expect(download).to receive(:eb_config_save)
|
14
|
+
expect(download).to receive(:do_copy_to_local_cfg)
|
15
|
+
download.download
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jack::Config do
|
4
|
+
before(:all) do
|
5
|
+
Jack::UI.mute = true
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:sort) { Jack::Config::Sort.new(test_options) }
|
9
|
+
|
10
|
+
describe "sort" do
|
11
|
+
it "process" do
|
12
|
+
# not much to check just for syntax errors
|
13
|
+
sort.run
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe Jack::Config do
|
5
|
+
before(:all) do
|
6
|
+
Jack::UI.mute = true
|
7
|
+
fake_eb_config
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:transmit) { Jack::Config::Transmit.new(test_options) }
|
11
|
+
|
12
|
+
def fake_eb_config
|
13
|
+
input = <<-EOL
|
14
|
+
---
|
15
|
+
global:
|
16
|
+
application_name: blah
|
17
|
+
default_platform: 64bit Amazon Linux 2014.09 v1.2.0 running Docker 1.3.3
|
18
|
+
EOL
|
19
|
+
file = "#{@root}/.elasticbeanstalk/config.yml"
|
20
|
+
File.open(file, 'w') { |file| file.write(input) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def mock
|
24
|
+
{environments: [OpenStruct.new(
|
25
|
+
application_name: "myapp",
|
26
|
+
solution_stack_name: "my solution stack")]}
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "transmit" do
|
30
|
+
it "sync_eb_config_yml" do
|
31
|
+
expect(transmit).to receive(:describe_environments).and_return(mock)
|
32
|
+
transmit.sync_eb_config_yml(true)
|
33
|
+
|
34
|
+
data = YAML.load_file(transmit.eb_config_path)
|
35
|
+
global = data['global']
|
36
|
+
expect(global['application_name']).to eq "myapp"
|
37
|
+
expect(global['default_platform']).to eq "my solution stack"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jack::Config::Upload do
|
4
|
+
before(:all) do
|
5
|
+
Jack::UI.mute = true
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:upload) { Jack::Config::Upload.new(test_options.merge(silent: true)) }
|
9
|
+
|
10
|
+
describe "upload" do
|
11
|
+
it "upload code paths" do
|
12
|
+
exist = upload.local_cfg_exist?
|
13
|
+
expect(exist).to be true # checking fixture
|
14
|
+
# mock methods way down deep to test code paths, test reads weird though
|
15
|
+
expect(upload).to receive(:eb_config_put)
|
16
|
+
upload.upload
|
17
|
+
end
|
18
|
+
|
19
|
+
it "upload flow" do
|
20
|
+
expect(upload).to receive(:compare)
|
21
|
+
expect(upload).to receive(:upload)
|
22
|
+
expect(upload).to receive(:update_env)
|
23
|
+
upload.run
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jack::Config::YamlFormatter do
|
4
|
+
let(:sorter) { Jack::Config::YamlFormatter.new }
|
5
|
+
|
6
|
+
describe "sorter" do
|
7
|
+
it "process should sort the keys" do
|
8
|
+
input = <<-EOL
|
9
|
+
EnvironmentConfigurationMetadata:
|
10
|
+
Description: test.
|
11
|
+
Foo: 1
|
12
|
+
AWSConfigurationTemplateVersion: 1.1.0.0
|
13
|
+
EOL
|
14
|
+
file = "spec/fixtures/fake.cfg.yml"
|
15
|
+
|
16
|
+
File.open(file, 'w') { |file| file.write(input) }
|
17
|
+
sorter.process(file)
|
18
|
+
output = File.read(file)
|
19
|
+
|
20
|
+
expect(output).to eq <<-EOL
|
21
|
+
AWSConfigurationTemplateVersion: 1.1.0.0
|
22
|
+
EnvironmentConfigurationMetadata:
|
23
|
+
Description: test.
|
24
|
+
Foo: 1
|
25
|
+
EOL
|
26
|
+
end
|
27
|
+
|
28
|
+
it "process should strip date modified and created" do
|
29
|
+
input = <<-EOL
|
30
|
+
EnvironmentConfigurationMetadata:
|
31
|
+
DateModified: '1425215243000'
|
32
|
+
Description: test.
|
33
|
+
DateCreated: '1425215243000'
|
34
|
+
AWSConfigurationTemplateVersion: 1.1.0.0
|
35
|
+
EOL
|
36
|
+
file = "spec/fixtures/fake.cfg.yml"
|
37
|
+
|
38
|
+
File.open(file, 'w') { |file| file.write(input) }
|
39
|
+
sorter.process(file)
|
40
|
+
output = File.read(file)
|
41
|
+
|
42
|
+
expect(output).to eq <<-EOL
|
43
|
+
AWSConfigurationTemplateVersion: 1.1.0.0
|
44
|
+
EnvironmentConfigurationMetadata:
|
45
|
+
Description: test.
|
46
|
+
EOL
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jack::Create do
|
4
|
+
before(:all) do
|
5
|
+
@create = Jack::Create.new(test_options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def solution_stacks
|
9
|
+
["64bit Amazon Linux 2014.09 v1.2.0 running Docker 1.3.3", "64bit Amazon Linux 2014.03 v1.0.0 running Docker 1.0.0", "64bit Amazon Linux 2014.03 v1.0.1 running Docker 1.0.0", "64bit Amazon Linux 2014.03 v1.0.4 running Docker 0.9.0", "64bit Amazon Linux 2014.03 v1.0.5 running Docker 0.9.0", "64bit Debian jessie v1.2.0 running Go 1.3 (Preconfigured - Docker)", "64bit Debian jessie v1.2.0 running Go 1.4 (Preconfigured - Docker)"]
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "jack" do
|
13
|
+
it "create environment" do
|
14
|
+
command = @create.build_command
|
15
|
+
# puts "command = #{command }"
|
16
|
+
expect(command).to include('eb create')
|
17
|
+
expect(command).to include('--cname stag-rails-app-s9')
|
18
|
+
expect(command).to include('--keyname "default"')
|
19
|
+
expect(command).to include('--cfg stag-rails-app')
|
20
|
+
expect(command).to include('stag-rails-app-s9')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "create_yaml" do
|
24
|
+
data = @create.create_yaml
|
25
|
+
expect(data["keyname"]).to eq "default"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "list solution stacks" do
|
29
|
+
@create = Jack::Create.new(test_options.merge(noop: false))
|
30
|
+
expect(@create).to receive(:solution_stacks).and_return(solution_stacks)
|
31
|
+
expect(@create.latest_docker_platform).to eq "64bit Amazon Linux 2014.09 v1.2.0 running Docker 1.3.3"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|