simple_deploy 0.7.2 → 0.7.3

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.
Files changed (89) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG.md +6 -0
  3. data/lib/simple_deploy/aws/cloud_formation/error.rb +32 -0
  4. data/lib/simple_deploy/aws/cloud_formation.rb +76 -0
  5. data/lib/simple_deploy/aws/instance_reader.rb +59 -0
  6. data/lib/simple_deploy/aws/simpledb.rb +52 -0
  7. data/lib/simple_deploy/aws.rb +4 -0
  8. data/lib/simple_deploy/cli/attributes.rb +7 -18
  9. data/lib/simple_deploy/cli/clone.rb +9 -19
  10. data/lib/simple_deploy/cli/create.rb +5 -14
  11. data/lib/simple_deploy/cli/deploy.rb +8 -11
  12. data/lib/simple_deploy/cli/destroy.rb +4 -10
  13. data/lib/simple_deploy/cli/environments.rb +1 -1
  14. data/lib/simple_deploy/cli/events.rb +5 -11
  15. data/lib/simple_deploy/cli/execute.rb +6 -9
  16. data/lib/simple_deploy/cli/instances.rb +4 -9
  17. data/lib/simple_deploy/cli/list.rb +5 -10
  18. data/lib/simple_deploy/cli/outputs.rb +5 -11
  19. data/lib/simple_deploy/cli/parameters.rb +5 -11
  20. data/lib/simple_deploy/cli/protect.rb +5 -10
  21. data/lib/simple_deploy/cli/resources.rb +5 -11
  22. data/lib/simple_deploy/cli/shared.rb +6 -6
  23. data/lib/simple_deploy/cli/status.rb +5 -11
  24. data/lib/simple_deploy/cli/template.rb +8 -13
  25. data/lib/simple_deploy/cli/update.rb +6 -10
  26. data/lib/simple_deploy/configuration.rb +102 -0
  27. data/lib/simple_deploy/entry.rb +71 -0
  28. data/lib/simple_deploy/entry_lister.rb +30 -0
  29. data/lib/simple_deploy/exceptions.rb +8 -0
  30. data/lib/simple_deploy/misc/attribute_merger.rb +2 -5
  31. data/lib/simple_deploy/notifier/campfire.rb +15 -12
  32. data/lib/simple_deploy/notifier.rb +6 -11
  33. data/lib/simple_deploy/stack/deployment/status.rb +5 -3
  34. data/lib/simple_deploy/stack/deployment.rb +8 -10
  35. data/lib/simple_deploy/stack/execute.rb +2 -3
  36. data/lib/simple_deploy/stack/output_mapper.rb +1 -4
  37. data/lib/simple_deploy/stack/ssh.rb +4 -4
  38. data/lib/simple_deploy/stack/{stack_attribute_formater.rb → stack_attribute_formatter.rb} +4 -6
  39. data/lib/simple_deploy/stack/stack_creator.rb +46 -0
  40. data/lib/simple_deploy/stack/stack_destroyer.rb +19 -0
  41. data/lib/simple_deploy/stack/stack_formatter.rb +25 -0
  42. data/lib/simple_deploy/stack/stack_lister.rb +18 -0
  43. data/lib/simple_deploy/stack/stack_reader.rb +56 -0
  44. data/lib/simple_deploy/stack/stack_updater.rb +67 -0
  45. data/lib/simple_deploy/stack/status.rb +53 -0
  46. data/lib/simple_deploy/stack.rb +89 -37
  47. data/lib/simple_deploy/version.rb +1 -1
  48. data/lib/simple_deploy.rb +31 -1
  49. data/simple_deploy.gemspec +6 -3
  50. data/spec/aws/cloud_formation/error_spec.rb +50 -0
  51. data/spec/aws/cloud_formation_spec.rb +207 -0
  52. data/spec/aws/instance_reader_spec.rb +96 -0
  53. data/spec/aws/simpledb_spec.rb +89 -0
  54. data/spec/cli/attributes_spec.rb +5 -15
  55. data/spec/cli/clone_spec.rb +14 -27
  56. data/spec/cli/create_spec.rb +11 -18
  57. data/spec/cli/deploy_spec.rb +24 -63
  58. data/spec/cli/destroy_spec.rb +7 -25
  59. data/spec/cli/outputs_spec.rb +12 -17
  60. data/spec/cli/protect_spec.rb +68 -106
  61. data/spec/cli/shared_spec.rb +12 -15
  62. data/spec/cli/update_spec.rb +9 -27
  63. data/spec/config_spec.rb +47 -14
  64. data/spec/contexts/config_contexts.rb +28 -0
  65. data/spec/contexts/logger_contexts.rb +9 -0
  66. data/spec/contexts/stack_contexts.rb +40 -0
  67. data/spec/entry_lister_spec.rb +31 -0
  68. data/spec/entry_spec.rb +86 -0
  69. data/spec/misc/attribute_merger_spec.rb +3 -8
  70. data/spec/notifier/campfire_spec.rb +21 -61
  71. data/spec/notifier_spec.rb +18 -40
  72. data/spec/spec_helper.rb +10 -0
  73. data/spec/stack/deployment/status_spec.rb +13 -13
  74. data/spec/stack/deployment_spec.rb +26 -21
  75. data/spec/stack/execute_spec.rb +7 -3
  76. data/spec/stack/output_mapper_spec.rb +3 -15
  77. data/spec/stack/ssh_spec.rb +14 -13
  78. data/spec/stack/{stack_attribute_formater_spec.rb → stack_attribute_formatter_spec.rb} +19 -16
  79. data/spec/stack/stack_creator_spec.rb +46 -0
  80. data/spec/stack/stack_destroyer_spec.rb +18 -0
  81. data/spec/stack/stack_formatter_spec.rb +37 -0
  82. data/spec/stack/stack_lister_spec.rb +17 -0
  83. data/spec/stack/stack_reader_spec.rb +81 -0
  84. data/spec/stack/stack_updater_spec.rb +79 -0
  85. data/spec/stack/status_spec.rb +106 -0
  86. data/spec/stack_spec.rb +160 -133
  87. metadata +112 -19
  88. data/.rvmrc +0 -1
  89. data/lib/simple_deploy/config.rb +0 -87
@@ -0,0 +1,71 @@
1
+
2
+ module SimpleDeploy
3
+ class Entry
4
+ attr_accessor :name
5
+
6
+ def initialize(args)
7
+ @domain = 'stacks'
8
+ @config = SimpleDeploy.config
9
+ @logger = SimpleDeploy.logger
10
+ @custom_attributes = {}
11
+ @name = region_specific_name args[:name]
12
+ create_domain
13
+ end
14
+
15
+ def self.find(args)
16
+ Entry.new :name => args[:name]
17
+ end
18
+
19
+ def attributes
20
+ u = {}
21
+
22
+ attrs = sdb_connect.select "select * from stacks where itemName() = '#{name}'"
23
+ if attrs.has_key? name
24
+ u.merge! Hash[attrs[name].map { |k,v| [k, v.first] }]
25
+ end
26
+
27
+ u.merge @custom_attributes
28
+ end
29
+
30
+ def set_attributes(a)
31
+ a.each { |attribute| @custom_attributes.merge! attribute }
32
+ end
33
+
34
+ def save
35
+ @custom_attributes.merge! 'Name' => name,
36
+ 'CreatedAt' => Time.now.utc.to_s
37
+
38
+ current_attributes = attributes
39
+ current_attributes.each_pair do |key,value|
40
+ @logger.debug "Setting attribute #{key}=#{value}"
41
+ end
42
+
43
+ sdb_connect.put_attributes('stacks',
44
+ name,
45
+ current_attributes,
46
+ :replace => current_attributes.keys )
47
+
48
+ @logger.debug "Save to SimpleDB successful."
49
+ end
50
+
51
+ def delete_attributes
52
+ sdb_connect.delete('stacks', name)
53
+ @logger.info "Delete from SimpleDB successful."
54
+ end
55
+
56
+ private
57
+
58
+ def region_specific_name(name)
59
+ "#{name}-#{@config.region}"
60
+ end
61
+
62
+ def create_domain
63
+ sdb_connect.create_domain @domain
64
+ end
65
+
66
+ def sdb_connect
67
+ @sdb_connect ||= AWS::SimpleDB.new
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,30 @@
1
+ module SimpleDeploy
2
+ class EntryLister
3
+
4
+ def initialize
5
+ @domain = 'stacks'
6
+ @config = SimpleDeploy.config
7
+ end
8
+
9
+ def all
10
+ if sdb_connect.domain_exists? @domain
11
+ e = sdb_connect.select "select * from #{@domain}"
12
+ entries = e.keys.map do |name|
13
+ remove_region_from_entry(name)
14
+ end
15
+ end
16
+ entries ? entries : []
17
+ end
18
+
19
+ private
20
+
21
+ def sdb_connect
22
+ @sdb_connect ||= AWS::SimpleDB.new
23
+ end
24
+
25
+ def remove_region_from_entry(name)
26
+ name.gsub(/-[a-z]{2}-[a-z]*-[0-9]{1,2}$/, '')
27
+ end
28
+
29
+ end
30
+ end
@@ -15,5 +15,13 @@ module SimpleDeploy
15
15
  class Exceptions::NoInstances < Base
16
16
  end
17
17
 
18
+ class CloudFormationError < Base
19
+ end
20
+
21
+ class UnknownStack < Base
22
+ end
23
+
24
+ class IllegalStateException < Base
25
+ end
18
26
  end
19
27
  end
@@ -4,9 +4,8 @@ module SimpleDeploy
4
4
 
5
5
  def merge(args)
6
6
  @attributes = args[:attributes]
7
- @config = args[:config]
7
+ @config = SimpleDeploy.config
8
8
  @environment = args[:environment]
9
- @logger = args[:logger]
10
9
  @input_stacks = args[:input_stacks]
11
10
  @template = args[:template]
12
11
 
@@ -35,9 +34,7 @@ module SimpleDeploy
35
34
  end
36
35
 
37
36
  def mapper
38
- @om ||= Stack::OutputMapper.new :environment => @environment,
39
- :config => @config,
40
- :logger => @logger
37
+ @om ||= Stack::OutputMapper.new :environment => @environment
41
38
  end
42
39
 
43
40
  end
@@ -1,4 +1,4 @@
1
- require 'tinder'
1
+ require 'esbit'
2
2
 
3
3
  module SimpleDeploy
4
4
  class Notifier
@@ -7,8 +7,8 @@ module SimpleDeploy
7
7
  def initialize(args)
8
8
  @stack_name = args[:stack_name]
9
9
  @environment = args[:environment]
10
- @config = args[:config]
11
- @logger = @config.logger
10
+ @config = SimpleDeploy.config
11
+ @logger = SimpleDeploy.logger
12
12
 
13
13
  attributes = stack.attributes
14
14
  @subdomain = attributes['campfire_subdomain']
@@ -18,17 +18,21 @@ module SimpleDeploy
18
18
 
19
19
  if @subdomain
20
20
  @token = @config.notifications['campfire']['token']
21
- @campfire = Tinder::Campfire.new @subdomain, :token => @token,
22
- :ssl_options => { :verify => false }
21
+ @campfire = Esbit::Campfire.new @subdomain, @token
22
+ @rooms = @campfire.rooms
23
23
  end
24
24
  end
25
25
 
26
26
  def send(message)
27
27
  @logger.info "Sending Campfire notifications."
28
28
  @room_ids.split(',').each do |room_id|
29
- @logger.debug "Sending notification to Campfire room #{room_id}."
30
- room = @campfire.find_room_by_id room_id.to_i
31
- room.speak message
29
+ room = @rooms.find { |r| r.id == room_id.to_i }
30
+ if room
31
+ @logger.debug "Sending notification to Campfire room #{room.name}."
32
+ room.say message
33
+ else
34
+ @logger.warn "Could not find a room for id #{room_id}"
35
+ end
32
36
  end
33
37
  @logger.info "Campfire notifications complete."
34
38
  end
@@ -36,11 +40,10 @@ module SimpleDeploy
36
40
  private
37
41
 
38
42
  def stack
39
- @stack ||= Stackster::Stack.new :environment => @environment,
40
- :name => @stack_name,
41
- :config => @config.environment(@environment),
42
- :logger => @logger
43
+ @stack ||= Stack.new :name => @stack_name,
44
+ :environment => @environment
43
45
  end
44
46
  end
47
+
45
48
  end
46
49
  end
@@ -3,20 +3,19 @@ require 'simple_deploy/notifier/campfire'
3
3
  module SimpleDeploy
4
4
  class Notifier
5
5
  def initialize(args)
6
+ @config = SimpleDeploy.config
6
7
  @stack_name = args[:stack_name]
7
8
  @environment = args[:environment]
8
- @config = Config.new :logger => args[:logger]
9
- @logger = @config.logger
10
9
  @notifications = @config.notifications || {}
11
10
  end
12
11
 
13
12
  def send_deployment_start_message
14
- message = "Deployment to #{@stack_name} in #{@config.region @environment} started."
13
+ message = "Deployment to #{@stack_name} in #{@config.region} started."
15
14
  send message
16
15
  end
17
16
 
18
17
  def send_deployment_complete_message
19
- message = "Deployment to #{@stack_name} in #{@config.region @environment} complete."
18
+ message = "Deployment to #{@stack_name} in #{@config.region} complete."
20
19
  attributes = stack.attributes
21
20
 
22
21
  if attributes['app_github_url']
@@ -35,8 +34,7 @@ module SimpleDeploy
35
34
  case notification
36
35
  when 'campfire'
37
36
  campfire = Notifier::Campfire.new :stack_name => @stack_name,
38
- :environment => @environment,
39
- :config => @config
37
+ :environment => @environment
40
38
  campfire.send message
41
39
  end
42
40
  end
@@ -45,11 +43,8 @@ module SimpleDeploy
45
43
  private
46
44
 
47
45
  def stack
48
- @stack ||= Stackster::Stack.new :environment => @environment,
49
- :name => @stack_name,
50
- :config => @config.environment(@environment),
51
- :logger => @logger
46
+ @stack ||= Stack.new :name => @stack_name,
47
+ :environment => @environment
52
48
  end
53
-
54
49
  end
55
50
  end
@@ -4,11 +4,11 @@ module SimpleDeploy
4
4
  class Status
5
5
 
6
6
  def initialize(args)
7
- @config = args[:config]
7
+ @config = SimpleDeploy.config
8
+ @logger = SimpleDeploy.logger
8
9
  @stack = args[:stack]
9
10
  @ssh_user = args[:ssh_user]
10
11
  @name = args[:name]
11
- @logger = @config.logger
12
12
  end
13
13
 
14
14
  def clear_for_deployment?
@@ -43,7 +43,9 @@ module SimpleDeploy
43
43
 
44
44
  def unset_deployment_in_progress
45
45
  @logger.debug "Clearing deployment in progress for #{@name}."
46
- @stack.update :attributes => [ { 'deployment_in_progress' => 'false' } ]
46
+ @stack.in_progress_update :attributes => [
47
+ { 'deployment_in_progress' => 'false' } ],
48
+ :caller => self
47
49
  end
48
50
 
49
51
  private
@@ -10,15 +10,15 @@ module SimpleDeploy
10
10
  class Deployment
11
11
 
12
12
  def initialize(args)
13
- @config = args[:config]
13
+ @config = SimpleDeploy.config
14
+ @logger = SimpleDeploy.logger
15
+ @region = @config.region
14
16
  @instances = args[:instances]
15
17
  @environment = args[:environment]
16
18
  @ssh_user = args[:ssh_user]
17
19
  @ssh_key = args[:ssh_key]
18
20
  @stack = args[:stack]
19
21
  @name = args[:name]
20
- @logger = @config.logger
21
- @region = @config.region @environment
22
22
  end
23
23
 
24
24
  def execute(force=false)
@@ -90,8 +90,8 @@ module SimpleDeploy
90
90
  end
91
91
 
92
92
  def primary_instance
93
- if @stack.instances.any?
94
- @stack.instances.first['instancesSet'].first['privateIpAddress']
93
+ if @stack.raw_instances.any?
94
+ @stack.raw_instances.first['instancesSet'].first['privateIpAddress']
95
95
  end
96
96
  end
97
97
 
@@ -100,8 +100,7 @@ module SimpleDeploy
100
100
  end
101
101
 
102
102
  def executer
103
- options = { :config => @config,
104
- :instances => @instances,
103
+ options = { :instances => @instances,
105
104
  :environment => @environment,
106
105
  :ssh_user => @ssh_user,
107
106
  :ssh_key => @ssh_key,
@@ -113,9 +112,8 @@ module SimpleDeploy
113
112
  def status
114
113
  options = { :name => @name,
115
114
  :environment => @environment,
116
- :ssh_user => @ssh_user,
117
- :config => @config,
118
- :stack => @stack }
115
+ :stack => @stack,
116
+ :ssh_user => @ssh_user }
119
117
  @status ||= SimpleDeploy::Stack::Deployment::Status.new options
120
118
  end
121
119
 
@@ -4,7 +4,7 @@ module SimpleDeploy
4
4
  class Stack
5
5
  class Execute
6
6
  def initialize(args)
7
- @config = args[:config]
7
+ @config = SimpleDeploy.config
8
8
  @instances = args[:instances]
9
9
  @environment = args[:environment]
10
10
  @ssh_user = args[:ssh_user]
@@ -20,8 +20,7 @@ module SimpleDeploy
20
20
  private
21
21
 
22
22
  def ssh
23
- options = { :config => @config,
24
- :instances => @instances,
23
+ options = { :instances => @instances,
25
24
  :environment => @environment,
26
25
  :ssh_user => @ssh_user,
27
26
  :ssh_key => @ssh_key,
@@ -3,9 +3,8 @@ module SimpleDeploy
3
3
  class OutputMapper
4
4
 
5
5
  def initialize(args)
6
- @config = args[:config]
7
6
  @environment = args[:environment]
8
- @logger = args[:logger]
7
+ @logger = SimpleDeploy.logger
9
8
  end
10
9
 
11
10
  def map_outputs_from_stacks(args)
@@ -35,8 +34,6 @@ module SimpleDeploy
35
34
  count += 1
36
35
  @logger.info "Reading outputs from stack '#{s}'."
37
36
  stack = Stack.new :environment => @environment,
38
- :config => @config,
39
- :logger => @logger,
40
37
  :name => s
41
38
  stack.wait_for_stable
42
39
  merge_outputs stack
@@ -6,15 +6,15 @@ module SimpleDeploy
6
6
  class SSH
7
7
 
8
8
  def initialize(args)
9
- @config = args[:config]
9
+ @config = SimpleDeploy.config
10
+ @logger = SimpleDeploy.logger
11
+ @stack = args[:stack]
10
12
  @instances = args[:instances]
11
13
  @environment = args[:environment]
12
14
  @ssh_user = args[:ssh_user]
13
15
  @ssh_key = args[:ssh_key]
14
- @stack = args[:stack]
15
16
  @name = args[:name]
16
- @logger = @config.logger
17
- @region = @config.region @environment
17
+ @region = @config.region
18
18
  end
19
19
 
20
20
  def execute(args)
@@ -1,12 +1,11 @@
1
1
  module SimpleDeploy
2
- class StackAttributeFormater
2
+ class StackAttributeFormatter
3
3
 
4
4
  def initialize(args)
5
- @config = args[:config]
6
- @environment = args[:environment]
5
+ @config = SimpleDeploy.config
6
+ @logger = SimpleDeploy.logger
7
7
  @main_attributes = args[:main_attributes]
8
- @region = @config.region @environment
9
- @logger = @config.logger
8
+ @region = @config.region
10
9
  end
11
10
 
12
11
  def updated_attributes(attributes)
@@ -39,7 +38,6 @@ module SimpleDeploy
39
38
  artifact = Artifact.new :name => name,
40
39
  :id => id,
41
40
  :region => @region,
42
- :config => @config,
43
41
  :domain => domain,
44
42
  :encrypted => artifact_encrypted?(name),
45
43
  :bucket_prefix => bucket_prefix
@@ -0,0 +1,46 @@
1
+ require 'json'
2
+
3
+ module SimpleDeploy
4
+ class StackCreator
5
+
6
+ def initialize(args)
7
+ @config = SimpleDeploy.config
8
+ @logger = SimpleDeploy.logger
9
+ @entry = args[:entry]
10
+ @name = args[:name]
11
+ @template = read_template_from_file args[:template_file]
12
+ end
13
+
14
+ def create
15
+ @logger.info "Creating Cloud Formation stack #{@name}."
16
+ cloud_formation.create :name => @name,
17
+ :parameters => read_parameters_from_entry,
18
+ :template => @template
19
+ end
20
+
21
+ private
22
+
23
+ def cloud_formation
24
+ @cf ||= AWS::CloudFormation.new
25
+ end
26
+
27
+ def read_template_from_file(template_file)
28
+ file = File.open template_file
29
+ file.read
30
+ end
31
+
32
+ def read_parameters_from_template
33
+ t = JSON.parse @template
34
+ t['Parameters'] ? t['Parameters'].keys : []
35
+ end
36
+
37
+ def read_parameters_from_entry
38
+ h = {}
39
+ attributes = @entry.attributes
40
+ read_parameters_from_template.each do |p|
41
+ h[p] = attributes[p] if attributes[p]
42
+ end
43
+ h
44
+ end
45
+ end
46
+ end