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
data/.gitignore CHANGED
@@ -2,4 +2,7 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ coverage
6
+ .ruby-version
7
+ .rvmrc
5
8
  *.swp
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## head:
2
2
 
3
+ ## v0.7.3 (05/17/2013):
4
+
5
+ * Merged the simple_deploy and stackster gems
6
+ * Replaced the tinder gem with the esbit gem for campfire communications
7
+ * Refactored the combined source code to make it easier to maintain
8
+
3
9
  ## v0.7.2 (03/20/2013):
4
10
 
5
11
  * Fix issue when trying to use ssh command (fixes #172)
@@ -0,0 +1,32 @@
1
+ require 'xmlsimple'
2
+
3
+ module SimpleDeploy
4
+ class AWS
5
+ class CloudFormation
6
+ class Error
7
+
8
+ def initialize(args)
9
+ @logger = SimpleDeploy.logger
10
+ @exception = args[:exception]
11
+ end
12
+
13
+ def process
14
+ message = XmlSimple.xml_in @exception.response.body
15
+ message['Error'].first['Message'].each do |msg|
16
+ case msg
17
+ when 'No updates are to be performed.'
18
+ @logger.info msg
19
+ when /^Stack:(.*) does not exist$/
20
+ @logger.error msg
21
+ raise Exceptions::UnknownStack.new msg
22
+ else
23
+ @logger.error msg
24
+ raise Exceptions::CloudFormationError.new msg
25
+ end
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,76 @@
1
+ require 'fog'
2
+
3
+ module SimpleDeploy
4
+ class AWS
5
+ class CloudFormation
6
+
7
+ def initialize
8
+ @config = SimpleDeploy.config
9
+ @logger = SimpleDeploy.logger
10
+ @connect = Fog::AWS::CloudFormation.new :aws_access_key_id => @config.access_key,
11
+ :aws_secret_access_key => @config.secret_key,
12
+ :region => @config.region
13
+ end
14
+
15
+ def create(args)
16
+ parameters = { 'Parameters' => args[:parameters] }
17
+ data = { 'Capabilities' => ['CAPABILITY_IAM'],
18
+ 'TemplateBody' => args[:template] }.merge parameters
19
+ @connect.create_stack(args[:name], data)
20
+ @logger.info "Cloud Formation stack creation completed."
21
+ rescue Exception => e
22
+ Error.new(:exception => e).process
23
+ end
24
+
25
+ def update(args)
26
+ parameters = { 'Parameters' => args[:parameters] }
27
+ data = { 'Capabilities' => ['CAPABILITY_IAM'],
28
+ 'TemplateBody' => args[:template] }.merge parameters
29
+ @connect.update_stack(args[:name], data)
30
+ @logger.info "Cloud Formation stack update completed."
31
+ rescue Exception => e
32
+ Error.new(:exception => e).process
33
+ end
34
+
35
+ def destroy(name)
36
+ @connect.delete_stack name
37
+ @logger.info "Cloud Formation stack destroy completed."
38
+ rescue Exception => e
39
+ Error.new(:exception => e).process
40
+ end
41
+
42
+ def describe_stack(name)
43
+ @connect.describe_stacks('StackName' => name).body['Stacks']
44
+ rescue Exception => e
45
+ Error.new(:exception => e).process
46
+ end
47
+
48
+ def stack_resources(name)
49
+ @connect.describe_stack_resources('StackName' => name).body['StackResources']
50
+ rescue Exception => e
51
+ Error.new(:exception => e).process
52
+ end
53
+
54
+ def stack_events(name, limit)
55
+ @connect.describe_stack_events(name).body['StackEvents'] [0..limit-1]
56
+ rescue Exception => e
57
+ Error.new(:exception => e).process
58
+ end
59
+
60
+ def stack_status(name)
61
+ describe_stack(name).first['StackStatus']
62
+ end
63
+
64
+ def stack_outputs(name)
65
+ describe_stack(name).last['Outputs']
66
+ end
67
+
68
+ def template(name)
69
+ @connect.get_template(name).body['TemplateBody']
70
+ rescue Exception => e
71
+ Error.new(:exception => e).process
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,59 @@
1
+ module SimpleDeploy
2
+ class AWS
3
+ class InstanceReader
4
+ def initialize
5
+ @config = SimpleDeploy.config
6
+ end
7
+
8
+ def list_stack_instances(stack_name)
9
+ asg_id = auto_scaling_group_id(stack_name)
10
+ return [] unless asg_id
11
+
12
+ asg_instances = list_instances asg_id
13
+ return [] unless asg_instances.any?
14
+
15
+ describe_instances asg_instances
16
+ end
17
+
18
+ private
19
+
20
+ def list_instances(asg_id)
21
+ @asg ||= Fog::AWS::AutoScaling.new :aws_access_key_id => @config.access_key,
22
+ :aws_secret_access_key => @config.secret_key,
23
+ :region => @config.region
24
+
25
+ body = @asg.describe_auto_scaling_groups('AutoScalingGroupNames' => [asg_id]).body
26
+ result = body['DescribeAutoScalingGroupsResult']['AutoScalingGroups'].last
27
+ return [] unless result
28
+
29
+ result['Instances'].map { |info| info['InstanceId'] }
30
+ end
31
+
32
+ def describe_instances(instances)
33
+ @ec2 ||= Fog::Compute::AWS.new :aws_access_key_id => @config.access_key,
34
+ :aws_secret_access_key => @config.secret_key,
35
+ :region => @config.region
36
+
37
+ @ec2.describe_instances('instance-state-name' => 'running',
38
+ 'instance-id' => instances).body['reservationSet']
39
+ end
40
+
41
+ def cloud_formation
42
+ @cloud_formation ||= AWS::CloudFormation.new
43
+ end
44
+
45
+ def auto_scaling_group_id(stack_name)
46
+ cf_stack_resources = cloud_formation.stack_resources stack_name
47
+ parse_cf_stack_resources cf_stack_resources
48
+ end
49
+
50
+ def parse_cf_stack_resources(cf_stack_resources)
51
+ asgs = cf_stack_resources.select do |r|
52
+ r['ResourceType'] == 'AWS::AutoScaling::AutoScalingGroup'
53
+ end
54
+ asgs.any? ? asgs.first['PhysicalResourceId'] : false
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,52 @@
1
+ require 'fog'
2
+
3
+ module SimpleDeploy
4
+ class AWS
5
+ class SimpleDB
6
+
7
+ def initialize
8
+ c = SimpleDeploy.config
9
+ @connect = Fog::AWS::SimpleDB.new :aws_access_key_id => c.access_key,
10
+ :aws_secret_access_key => c.secret_key,
11
+ :region => c.region
12
+ end
13
+
14
+ def domains
15
+ @connect.list_domains.body['Domains']
16
+ end
17
+
18
+ def domain_exists?(domain)
19
+ domains.include? domain
20
+ end
21
+
22
+ def create_domain(domain)
23
+ @connect.create_domain(domain) unless domain_exists?(domain)
24
+ end
25
+
26
+ def put_attributes(domain, key, attributes, options)
27
+ @connect.put_attributes domain, key, attributes, options
28
+ end
29
+
30
+ def select(query)
31
+ options = { 'ConsistentRead' => true }
32
+ data = {}
33
+ next_token = nil
34
+
35
+ while true
36
+ options.merge! 'NextToken' => next_token
37
+ chunk = @connect.select(query, options).body
38
+ data.merge! chunk['Items']
39
+ next_token = chunk['NextToken']
40
+ break unless next_token
41
+ end
42
+
43
+ data
44
+ end
45
+
46
+ def delete(domain, key)
47
+ @connect.delete_attributes domain, key
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,4 @@
1
+ require "simple_deploy/aws/cloud_formation"
2
+ require "simple_deploy/aws/cloud_formation/error"
3
+ require "simple_deploy/aws/instance_reader"
4
+ require "simple_deploy/aws/simpledb"
@@ -28,6 +28,11 @@ EOS
28
28
  valid_options? :provided => @opts,
29
29
  :required => [:environment, :name]
30
30
 
31
+ SimpleDeploy.create_config @opts[:environment]
32
+ SimpleDeploy.logger @opts[:log_level]
33
+ @stack = Stack.new :name => @opts[:name],
34
+ :environment => @opts[:environment]
35
+
31
36
  @opts[:as_command_args] ? command_args_output : default_output
32
37
  end
33
38
 
@@ -38,8 +43,8 @@ EOS
38
43
  private
39
44
 
40
45
  def attribute_data
41
- rescue_stackster_exceptions_and_exit do
42
- Hash[stack.attributes.sort]
46
+ rescue_exceptions_and_exit do
47
+ Hash[@stack.attributes.sort]
43
48
  end
44
49
  end
45
50
 
@@ -47,25 +52,9 @@ EOS
47
52
  puts attribute_data.map { |k, v| "-a #{k}=#{v}" }.join(' ')
48
53
  end
49
54
 
50
- def config
51
- @config ||= Config.new.environment @opts[:environment]
52
- end
53
-
54
55
  def default_output
55
56
  attribute_data.each_pair { |k, v| puts "#{k}: #{v}" }
56
57
  end
57
-
58
- def logger
59
- @logger ||= SimpleDeployLogger.new :log_level => @opts[:log_level]
60
- end
61
-
62
- def stack
63
- @stack = Stack.new :environment => @opts[:environment],
64
- :name => @opts[:name],
65
- :config => config,
66
- :logger => logger
67
- end
68
-
69
58
  end
70
59
 
71
60
  end
@@ -31,6 +31,9 @@ EOS
31
31
  valid_options? :provided => @opts,
32
32
  :required => [:environment, :source_name, :new_name]
33
33
 
34
+ SimpleDeploy.create_config @opts[:environment]
35
+ SimpleDeploy.logger @opts[:log_level]
36
+
34
37
  override_attributes = parse_attributes :attributes => @opts[:attributes]
35
38
 
36
39
  cloned_attributes = filter_attributes source_stack.attributes
@@ -43,10 +46,10 @@ EOS
43
46
  if @opts[:template]
44
47
  template_file_path = @opts[:template]
45
48
  else
46
- template_file.write source_stack.template.to_json
49
+ template_file.write source_stack.template
47
50
  end
48
51
 
49
- rescue_stackster_exceptions_and_exit do
52
+ rescue_exceptions_and_exit do
50
53
  new_stack.create :attributes => new_attributes,
51
54
  :template => template_file_path
52
55
  end
@@ -80,28 +83,15 @@ EOS
80
83
  end.compact
81
84
  end
82
85
 
83
- def config
84
- @config ||= Config.new.environment @opts[:environment]
85
- end
86
-
87
- def logger
88
- @logger ||= SimpleDeployLogger.new :log_level => @opts[:log_level]
89
- end
90
-
91
86
  def source_stack
92
- @source_stack ||= Stack.new :environment => @opts[:environment],
93
- :name => @opts[:source_name],
94
- :config => config,
95
- :logger => logger
87
+ @source_stack = Stack.new :name => @opts[:source_name],
88
+ :environment => @opts[:environment]
96
89
  end
97
90
 
98
91
  def new_stack
99
- @new_stack ||= Stack.new :environment => @opts[:environment],
100
- :name => @opts[:new_name],
101
- :config => config,
102
- :logger => logger
92
+ @new_stack = Stack.new :name => @opts[:new_name],
93
+ :environment => @opts[:environment]
103
94
  end
104
-
105
95
  end
106
96
 
107
97
  end
@@ -34,14 +34,12 @@ matching or pluralized names. Can be specified multiple times.", :type => :stri
34
34
  valid_options? :provided => @opts,
35
35
  :required => [:environment, :name, :template]
36
36
 
37
- @config = Config.new.environment @opts[:environment]
37
+ SimpleDeploy.create_config @opts[:environment]
38
+ SimpleDeploy.logger @opts[:log_level]
39
+ stack = Stack.new :name => @opts[:name],
40
+ :environment => @opts[:environment]
38
41
 
39
- stack = Stack.new :environment => @opts[:environment],
40
- :name => @opts[:name],
41
- :config => @config,
42
- :logger => logger
43
-
44
- rescue_stackster_exceptions_and_exit do
42
+ rescue_exceptions_and_exit do
45
43
  stack.create :attributes => merged_attributes,
46
44
  :template => @opts[:template]
47
45
  end
@@ -57,8 +55,6 @@ matching or pluralized names. Can be specified multiple times.", :type => :stri
57
55
  provided_attributes = parse_attributes :attributes => @opts[:attributes]
58
56
 
59
57
  attribute_merger.merge :attributes => provided_attributes,
60
- :config => @config,
61
- :logger => @logger,
62
58
  :environment => @opts[:environment],
63
59
  :input_stacks => @opts[:input_stack],
64
60
  :template => @opts[:template]
@@ -67,11 +63,6 @@ matching or pluralized names. Can be specified multiple times.", :type => :stri
67
63
  def attribute_merger
68
64
  SimpleDeploy::Misc::AttributeMerger.new
69
65
  end
70
-
71
- def logger
72
- @logger ||= SimpleDeployLogger.new :log_level => @opts[:log_level]
73
- end
74
-
75
66
  end
76
67
 
77
68
  end
@@ -54,22 +54,23 @@ EOS
54
54
  valid_options? :provided => @opts,
55
55
  :required => [:environment, :name]
56
56
 
57
+ SimpleDeploy.create_config @opts[:environment]
58
+ logger = SimpleDeploy.logger @opts[:log_level]
59
+
57
60
  new_attributes = parse_attributes :attributes => @opts[:attributes]
58
61
 
59
62
  @opts[:name].each do |name|
60
63
  notifier = Notifier.new :stack_name => name,
61
- :environment => @opts[:environment],
62
- :logger => logger
64
+ :environment => @opts[:environment]
63
65
 
64
- stack = Stack.new :environment => @opts[:environment],
65
- :name => name,
66
- :logger => logger,
67
- :internal => @opts[:internal]
66
+ stack = Stack.new :name => name,
67
+ :environment => @opts[:environment],
68
+ :internal => @opts[:internal]
68
69
 
69
70
  proceed = true
70
71
 
71
72
  if new_attributes.any?
72
- rescue_stackster_exceptions_and_exit do
73
+ rescue_exceptions_and_exit do
73
74
  proceed = stack.update :force => @opts[:force],
74
75
  :attributes => new_attributes
75
76
  end
@@ -96,10 +97,6 @@ EOS
96
97
  end
97
98
  end
98
99
 
99
- def logger
100
- @logger ||= SimpleDeployLogger.new :log_level => @opts[:log_level]
101
- end
102
-
103
100
  def command_summary
104
101
  'Execute deployment on given stack(s)'
105
102
  end
@@ -26,20 +26,14 @@ EOS
26
26
  valid_options? :provided => @opts,
27
27
  :required => [:environment, :name]
28
28
 
29
- config = Config.new.environment @opts[:environment]
30
-
31
- stack = Stack.new :environment => @opts[:environment],
32
- :name => @opts[:name],
33
- :config => config,
34
- :logger => logger
29
+ SimpleDeploy.create_config @opts[:environment]
30
+ SimpleDeploy.logger @opts[:log_level]
31
+ stack = Stack.new :name => @opts[:name],
32
+ :environment => @opts[:environment]
35
33
 
36
34
  exit 1 unless stack.destroy
37
35
  end
38
36
 
39
- def logger
40
- @logger ||= SimpleDeployLogger.new :log_level => @opts[:log_level]
41
- end
42
-
43
37
  def command_summary
44
38
  'Destroy a stack'
45
39
  end