simple_deploy 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
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