gantree 0.2.1 → 0.2.2

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
  SHA1:
3
- metadata.gz: 1c3b0df61434de815c1b8c0bec26a34cd9825a8d
4
- data.tar.gz: c5184888c18fd79d0333b1d1181e97c927589550
3
+ metadata.gz: b4eeaa7b24460976ccace19ae646dd0931d636ec
4
+ data.tar.gz: fb5b8c1c4a71871ff27a7e00198cc87e39ff08db
5
5
  SHA512:
6
- metadata.gz: 9487ce2f6d98c478e8dc84d2f90961ef29ff39e12f2af3ccd635e2ac92fb2619e25b04eb566d66d2e5631e630e2b3aa73074846e3eff284c115a12a171dc8c5a
7
- data.tar.gz: 4b84e2ace1c8d72f0b22afd6a21ed8dc34327050ab698eb31ecaf086c1cf684c1500ac1e09a459ebb3a8f1edd0029c965018a7fc06c2c9831b5d35e4910106c4
6
+ metadata.gz: 89d1fb7dcd07039ef35cae14cf9e714f8eafaee4fc1355f1f402fcace8d38b5ff555f7ef0d80087521ba929c4fbbcab187f7513ca7884c857d7c2249e7668a8a
7
+ data.tar.gz: 12e419db24780d79c26608f1206e325b75df28aefa66fa2be0e429bc4f92a7aa9ca92081bf650a5f55ed47c1d2e3f1dfdb2fbae3201146218ff2eaa6b23d7b05
data/Gemfile CHANGED
@@ -12,3 +12,5 @@ gem "webmock"
12
12
  gem "cloudformation-ruby-dsl"
13
13
  gem "archive-zip"
14
14
  gem "json"
15
+ gem "slackr"
16
+ gem "highline"
data/Gemfile.lock CHANGED
@@ -33,6 +33,7 @@ GEM
33
33
  guard-rspec (4.3.1)
34
34
  guard (~> 2.1)
35
35
  rspec (>= 2.14, < 4.0)
36
+ highline (1.6.21)
36
37
  io-like (0.3.0)
37
38
  json (1.8.1)
38
39
  listen (2.7.9)
@@ -43,6 +44,7 @@ GEM
43
44
  method_source (0.8.2)
44
45
  mini_portile (0.6.0)
45
46
  multi_json (1.10.1)
47
+ multipart-post (2.0.0)
46
48
  nokogiri (1.6.3.1)
47
49
  mini_portile (= 0.6.0)
48
50
  pry (0.10.1)
@@ -71,6 +73,8 @@ GEM
71
73
  multi_json
72
74
  simplecov-html (~> 0.8.0)
73
75
  simplecov-html (0.8.0)
76
+ slackr (0.0.6)
77
+ multipart-post (~> 2.0.0)
74
78
  slop (3.6.0)
75
79
  thor (0.19.1)
76
80
  timers (1.1.0)
@@ -89,7 +93,9 @@ DEPENDENCIES
89
93
  guard
90
94
  guard-bundler
91
95
  guard-rspec
96
+ highline
92
97
  json
93
98
  rake
94
99
  rspec
100
+ slackr
95
101
  webmock
data/gantree.gemspec CHANGED
@@ -26,6 +26,8 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency "cloudformation-ruby-dsl"
27
27
  spec.add_dependency "archive-zip"
28
28
  spec.add_dependency "json"
29
+ spec.add_dependency "slackr"
30
+ spec.add_dependency "highline"
29
31
 
30
32
  spec.add_development_dependency "bundler", "~> 1.3"
31
33
  spec.add_development_dependency "rake"
data/lib/gantree/cfn.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'cloudformation-ruby-dsl'
2
+ require "highline/import"
2
3
  require_relative 'cfn/master'
3
4
  require_relative 'cfn/beanstalk'
4
5
  require_relative 'cfn/resources'
@@ -31,7 +32,6 @@ module Gantree
31
32
  env_type: env_type,
32
33
  }
33
34
  @options = options.merge(additional_options)
34
- @options[:rds_enabled] = rds_enabled?
35
35
  end
36
36
 
37
37
  def check_credentials
@@ -40,20 +40,66 @@ module Gantree
40
40
  end
41
41
 
42
42
  def create
43
+ @options[:rds_enabled] = rds_enabled? if @options[:rds]
43
44
  create_cfn_if_needed
44
- generate("master", MasterTemplate.new(@options).create)
45
- generate("beanstalk", BeanstalkTemplate.new(@options).create)
46
- generate("resources", ResourcesTemplate.new(@options).create)
47
- puts "All templates created"
48
- puts "*** OPTIONS + ADDITIONAL pt 2"
49
- puts @options
50
- create_aws_cfn_stack if @options[:dry_run].nil?
45
+ create_all_templates
46
+ upload_templates unless @options[:dry_run]
47
+ create_aws_cfn_stack unless @options[:dry_run]
48
+ end
49
+
50
+ def update
51
+ puts "Updating stack from local cfn repo"
52
+ unless @options[:dry_run] then
53
+ upload_templates
54
+ template = AWS::S3.new.buckets["#{@options[:cfn_bucket]}/#{@env}"].objects["#{@env}-master.cfn.json"]
55
+ @cfm.stacks[@options[:stack_name]].update(:template => template)
56
+ end
57
+ end
58
+
59
+ def delete
60
+ if @options[:force]
61
+ input = "y"
62
+ else
63
+ input = ask "Are you sure? (y|n)"
64
+ end
65
+ if input == "y" || @options[:force]
66
+ puts "Deleting stack from aws"
67
+ @cfm.stacks[@options[:stack_name]].delete unless @options[:dry_run]
68
+ else
69
+ puts "canceling..."
70
+ end
51
71
  end
52
72
 
53
73
  def create_cfn_if_needed
54
74
  Dir.mkdir 'cfn' unless File.directory?("cfn")
55
75
  end
56
76
 
77
+ def create_all_templates
78
+ if @options[:dupe]
79
+ puts "Duplicating cluster"
80
+ orgin_stack_name = @options[:dupe]
81
+ origin_env = @options[:dupe].match(/^[a-zA-Z]*\-([a-zA-Z]*)\-[a-zA-Z]*\-([a-zA-Z]*\d*)/)[1] + "-" + env_from_dupe = @options[:dupe].match(/^([a-zA-Z]*)\-([a-zA-Z]*)\-[a-zA-Z]*\-([a-zA-Z]*\d*)/)[1] + '-' + env_from_dupe = @options[:dupe].match(/^([a-zA-Z]*)\-([a-zA-Z]*)\-[a-zA-Z]*\-([a-zA-Z]*\d*)/)[3]
82
+ templates = ['master','resources','beanstalk']
83
+ templates.each do |template|
84
+ FileUtils.cp("cfn/#{origin_env}-#{template}.cfn.json", "cfn/#{@env}-#{template}.cfn.json")
85
+ file = IO.read("cfn/#{@env}-#{template}.cfn.json")
86
+ file.gsub!(/#{escape_characters_in_string(orgin_stack_name)}/, @options[:stack_name])
87
+ file.gsub!(/#{escape_characters_in_string(origin_env)}/, @options[:env])
88
+ IO.write("cfn/#{@env}-#{template}.cfn.json",file)
89
+ end
90
+ else
91
+ puts "Generating templates from gantree"
92
+ generate("master", MasterTemplate.new(@options).create)
93
+ generate("beanstalk", BeanstalkTemplate.new(@options).create)
94
+ generate("resources", ResourcesTemplate.new(@options).create)
95
+ end
96
+ end
97
+
98
+ def escape_characters_in_string(string)
99
+ pattern = /(\'|\"|\.|\*|\/|\-|\\)/
100
+ string.gsub(pattern){|match|"\\" + match} # <-- Trying to take the currently found match and add a \ before it I have no idea how to do that).
101
+ end
102
+
57
103
  def generate(template_name, template)
58
104
  IO.write("cfn/#{template_name}.rb", template)
59
105
  json = `ruby cfn/#{template_name}.rb expand`
@@ -62,20 +108,26 @@ module Gantree
62
108
  IO.write("cfn/#{template_file_name}", json)
63
109
  puts "Created #{template_file_name} in the cfn directory"
64
110
  FileUtils.rm("cfn/#{template_name}.rb")
65
- upload_template_to_s3("cfn/#{template_file_name}")
66
111
  end
67
112
 
68
- def upload_template_to_s3(filename)
69
- begin
70
- puts "uploading cfn template to #{@options[:cfn_bucket]}/#{@env}"
113
+ def upload_templates
114
+ check_template_bucket
115
+ templates = ['master','resources','beanstalk']
116
+ templates.each do |template|
117
+ filename = "cfn/#{@env}-#{template}.cfn.json"
71
118
  key = File.basename(filename)
72
119
  @s3.buckets["#{@options[:cfn_bucket]}/#{@env}"].objects[key].write(:file => filename)
73
- rescue AWS::S3::Errors::NoSuchBucket
74
- puts "bucket didn't exist...creating"
75
- bucket = @s3.buckets.create("#{@options[:cfn_bucket]}/#{@env}")
76
- retry
77
- rescue AWS::S3::Errors::AccessDenied
78
- puts "Your key is not configured for s3 access, please let your operations team know"
120
+ end
121
+ puts "templates uploaded"
122
+ end
123
+
124
+ def check_template_bucket
125
+ bucket_name = "#{@options[:cfn_bucket]}/#{@env}"
126
+ if @s3.buckets[bucket_name].exists?
127
+ puts "uploading cfn templates to #{@options[:cfn_bucket]}/#{@env}"
128
+ else
129
+ puts "creating bucket #{@options[:cfn_bucket]}/#{@env} to upload templates"
130
+ @s3.buckets.create(bucket_name)
79
131
  end
80
132
  end
81
133
 
data/lib/gantree/cli.rb CHANGED
@@ -11,6 +11,7 @@ module Gantree
11
11
  method_option :env, :aliases => "-e", :desc => "elastic beanstalk environment"
12
12
  method_option :ext, :aliases => "-x", :desc => "ebextensions folder/repo"
13
13
  option :dry_run, :aliases => "-d", :desc => "do not actually deploy the app"
14
+ option :silent, :aliases => "-s", :desc => "mute notifications"
14
15
  def deploy app
15
16
  Gantree::Deploy.new(app, merge_defaults(options)).run
16
17
  end
@@ -22,16 +23,30 @@ module Gantree
22
23
  Gantree::Init.new(image,options).run
23
24
  end
24
25
 
25
- desc "create APP", "create or update a cfn stack"
26
+ desc "create APP", "create a cfn stack"
26
27
  method_option :env, :aliases => "-e", :desc => "(optional) environment name"
27
28
  method_option :instance_size, :aliases => "-i", :desc => "(optional) set instance size"
28
29
  method_option :rds, :aliases => "-r", :desc => "(optional) set database type [pg,mysql]"
29
30
  option :dry_run, :aliases => "-d", :desc => "do not actually create the stack"
30
31
  option :docker_version, :desc => "set the version of docker to use as solution stack"
32
+ option :dupe, :desc => "use a local cfn folder"
31
33
  def create app
32
34
  Gantree::Stack.new(app, merge_defaults(options)).create
33
35
  end
34
36
 
37
+ desc "update APP", "update a cfn stack"
38
+ option :dry_run, :aliases => "-d", :desc => "do not actually create the stack"
39
+ def update app
40
+ Gantree::Stack.new(app, merge_defaults(options)).update
41
+ end
42
+
43
+ desc "delete APP", "delete a cfn stack"
44
+ option :force, :desc => "do not prompt"
45
+ option :dry_run, :aliases => "-d", :desc => "do not actually create the stack"
46
+ def delete app
47
+ Gantree::Stack.new(app, merge_defaults(options)).delete
48
+ end
49
+
35
50
  protected
36
51
 
37
52
  def merge_defaults(options={})
@@ -1,5 +1,6 @@
1
1
  require 'json'
2
2
  require 'archive/zip'
3
+ require_relative 'notification'
3
4
 
4
5
  module Gantree
5
6
  class Deploy
@@ -23,6 +24,9 @@ module Gantree
23
24
  clean_up
24
25
  create_eb_version if @options[:dry_run].nil?
25
26
  update_application if @options[:dry_run].nil?
27
+ if @options[:slack]
28
+ Notification.new(@options[:slack]).say("hello") unless @options[:silent]
29
+ end
26
30
  end
27
31
 
28
32
  private
@@ -145,7 +149,7 @@ module Gantree
145
149
  end
146
150
 
147
151
  def clean_up
148
- FileUtils.rm(@packeged_version)
152
+ FileUtils.rm_rf(@packeged_version)
149
153
  `git checkout Dockerrun.aws.json` # reverts back to original Dockerrun.aws.json
150
154
  `rm -rf .ebextensions/` if ext?
151
155
  end
@@ -0,0 +1,16 @@
1
+ require 'slackr'
2
+ class Notification
3
+
4
+ def initialize(options={})
5
+ @slack = Slackr.connect(options["team"], options["token"], {
6
+ "channel" => options["channel"],
7
+ "username" => options["username"],
8
+ "icon_url" => options["icon_url"]
9
+ })
10
+ end
11
+
12
+ def say(msg)
13
+ @slack.say(msg)
14
+ end
15
+
16
+ end
@@ -1,3 +1,3 @@
1
1
  module Gantree
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
data/spec/lib/cli_spec.rb CHANGED
@@ -32,15 +32,19 @@ describe Gantree::CLI do
32
32
 
33
33
  describe "deploy" do
34
34
  it "should deploy images" do
35
- out = execute("bin/gantree deploy #{@env} --dry-run")
35
+ out = execute("bin/gantree deploy #{@env} --dry-run --silent")
36
36
  expect(out).to include("Deploying")
37
37
  end
38
38
  it "should deploy images with remote extensions" do
39
- out = execute("bin/gantree deploy #{@env} -x 'git@github.com:br/.ebextensions' --dry-run")
39
+ out = execute("bin/gantree deploy #{@env} -x 'git@github.com:br/.ebextensions' --dry-run --silent")
40
40
  expect(out).to include("Deploying")
41
41
  end
42
42
  it "should deploy images with remote extensions on a branch" do
43
- out = execute("bin/gantree deploy #{@env} -x 'git@github.com:br/.ebextensions:basic' --dry-run")
43
+ out = execute("bin/gantree deploy #{@env} -x 'git@github.com:br/.ebextensions:basic' --dry-run --silent")
44
+ expect(out).to include("Deploying")
45
+ end
46
+ it "should notify slack of deploys" do
47
+ out = execute("bin/gantree deploy #{@env} --dry-run")
44
48
  expect(out).to include("Deploying")
45
49
  end
46
50
  end
@@ -50,20 +54,45 @@ describe Gantree::CLI do
50
54
  out = execute("bin/gantree create #{@env} --dry-run")
51
55
  beanstalk = JSON.parse(IO.read("cfn/#{@app}-beanstalk.cfn.json"))["Resources"]["ConfigurationTemplate"]["Properties"]["SolutionStackName"]
52
56
  expect(beanstalk).to include "Docker 1.2.0"
53
- expect(out).to include "All templates created"
54
- expect(out).to include "RDS is not enabled, no DB created"
57
+ expect(out).to include "Generating"
58
+ expect_all_templates_created(out)
55
59
  end
56
60
 
57
61
  it "should create clusters with any docker version" do
58
62
  out = execute("bin/gantree create #{@env} --dry-run --docker-version '64bit Amazon Linux 2014.03 v1.0.1 running Docker 1.0.0'")
59
63
  beanstalk = JSON.parse(IO.read("cfn/#{@app}-beanstalk.cfn.json"))["Resources"]["ConfigurationTemplate"]["Properties"]["SolutionStackName"]
60
64
  expect(beanstalk).to include "Docker 1.0.0"
61
- expect(out).to include "All templates created"
65
+ expect_all_templates_created(out)
62
66
  end
63
67
 
64
68
  it "should create clusters with databases" do
65
- out = execute("bin/gantree create stag-knarr-app-s7 --dry-run --rds pg")
69
+ out = execute("bin/gantree create #{@env} --dry-run --rds pg")
66
70
  expect(out).to_not include "RDS is not enabled, no DB created"
67
71
  end
72
+
73
+ it "should create dupliacte clusters from local cfn" do
74
+ out = execute("bin/gantree create stag-knarr-app-s2 --dupe #{@env} --dry-run")
75
+ expect(out).to include "Duplicating"
76
+ end
77
+ end
78
+
79
+ describe "update" do
80
+ it "should update existing clusters" do
81
+ out = execute("bin/gantree update #{@env} --dry-run")
82
+ expect(out).to include "Updating"
83
+ end
68
84
  end
85
+
86
+ describe "delete" do
87
+ it "should update existing clusters" do
88
+ out = execute("bin/gantree delete #{@env} --dry-run --force")
89
+ expect(out).to include "Deleting"
90
+ end
91
+ end
92
+
93
+ def expect_all_templates_created(out)
94
+ expect(out).to include "#{@app}-master.cfn.json"
95
+ expect(out).to include "#{@app}-beanstalk.cfn.json"
96
+ expect(out).to include "#{@app}-resources.cfn.json"
97
+ end
69
98
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gantree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix
@@ -122,6 +122,34 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: slackr
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: highline
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
125
153
  - !ruby/object:Gem::Dependency
126
154
  name: bundler
127
155
  requirement: !ruby/object:Gem::Requirement
@@ -220,6 +248,7 @@ files:
220
248
  - lib/gantree/cli/help.rb
221
249
  - lib/gantree/deploy.rb
222
250
  - lib/gantree/init.rb
251
+ - lib/gantree/notification.rb
223
252
  - lib/gantree/version.rb
224
253
  - spec/lib/cli_spec.rb
225
254
  - spec/lib/deploy_spec.rb