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.
- data/.gitignore +3 -0
- data/CHANGELOG.md +6 -0
- data/lib/simple_deploy/aws/cloud_formation/error.rb +32 -0
- data/lib/simple_deploy/aws/cloud_formation.rb +76 -0
- data/lib/simple_deploy/aws/instance_reader.rb +59 -0
- data/lib/simple_deploy/aws/simpledb.rb +52 -0
- data/lib/simple_deploy/aws.rb +4 -0
- data/lib/simple_deploy/cli/attributes.rb +7 -18
- data/lib/simple_deploy/cli/clone.rb +9 -19
- data/lib/simple_deploy/cli/create.rb +5 -14
- data/lib/simple_deploy/cli/deploy.rb +8 -11
- data/lib/simple_deploy/cli/destroy.rb +4 -10
- data/lib/simple_deploy/cli/environments.rb +1 -1
- data/lib/simple_deploy/cli/events.rb +5 -11
- data/lib/simple_deploy/cli/execute.rb +6 -9
- data/lib/simple_deploy/cli/instances.rb +4 -9
- data/lib/simple_deploy/cli/list.rb +5 -10
- data/lib/simple_deploy/cli/outputs.rb +5 -11
- data/lib/simple_deploy/cli/parameters.rb +5 -11
- data/lib/simple_deploy/cli/protect.rb +5 -10
- data/lib/simple_deploy/cli/resources.rb +5 -11
- data/lib/simple_deploy/cli/shared.rb +6 -6
- data/lib/simple_deploy/cli/status.rb +5 -11
- data/lib/simple_deploy/cli/template.rb +8 -13
- data/lib/simple_deploy/cli/update.rb +6 -10
- data/lib/simple_deploy/configuration.rb +102 -0
- data/lib/simple_deploy/entry.rb +71 -0
- data/lib/simple_deploy/entry_lister.rb +30 -0
- data/lib/simple_deploy/exceptions.rb +8 -0
- data/lib/simple_deploy/misc/attribute_merger.rb +2 -5
- data/lib/simple_deploy/notifier/campfire.rb +15 -12
- data/lib/simple_deploy/notifier.rb +6 -11
- data/lib/simple_deploy/stack/deployment/status.rb +5 -3
- data/lib/simple_deploy/stack/deployment.rb +8 -10
- data/lib/simple_deploy/stack/execute.rb +2 -3
- data/lib/simple_deploy/stack/output_mapper.rb +1 -4
- data/lib/simple_deploy/stack/ssh.rb +4 -4
- data/lib/simple_deploy/stack/{stack_attribute_formater.rb → stack_attribute_formatter.rb} +4 -6
- data/lib/simple_deploy/stack/stack_creator.rb +46 -0
- data/lib/simple_deploy/stack/stack_destroyer.rb +19 -0
- data/lib/simple_deploy/stack/stack_formatter.rb +25 -0
- data/lib/simple_deploy/stack/stack_lister.rb +18 -0
- data/lib/simple_deploy/stack/stack_reader.rb +56 -0
- data/lib/simple_deploy/stack/stack_updater.rb +67 -0
- data/lib/simple_deploy/stack/status.rb +53 -0
- data/lib/simple_deploy/stack.rb +89 -37
- data/lib/simple_deploy/version.rb +1 -1
- data/lib/simple_deploy.rb +31 -1
- data/simple_deploy.gemspec +6 -3
- data/spec/aws/cloud_formation/error_spec.rb +50 -0
- data/spec/aws/cloud_formation_spec.rb +207 -0
- data/spec/aws/instance_reader_spec.rb +96 -0
- data/spec/aws/simpledb_spec.rb +89 -0
- data/spec/cli/attributes_spec.rb +5 -15
- data/spec/cli/clone_spec.rb +14 -27
- data/spec/cli/create_spec.rb +11 -18
- data/spec/cli/deploy_spec.rb +24 -63
- data/spec/cli/destroy_spec.rb +7 -25
- data/spec/cli/outputs_spec.rb +12 -17
- data/spec/cli/protect_spec.rb +68 -106
- data/spec/cli/shared_spec.rb +12 -15
- data/spec/cli/update_spec.rb +9 -27
- data/spec/config_spec.rb +47 -14
- data/spec/contexts/config_contexts.rb +28 -0
- data/spec/contexts/logger_contexts.rb +9 -0
- data/spec/contexts/stack_contexts.rb +40 -0
- data/spec/entry_lister_spec.rb +31 -0
- data/spec/entry_spec.rb +86 -0
- data/spec/misc/attribute_merger_spec.rb +3 -8
- data/spec/notifier/campfire_spec.rb +21 -61
- data/spec/notifier_spec.rb +18 -40
- data/spec/spec_helper.rb +10 -0
- data/spec/stack/deployment/status_spec.rb +13 -13
- data/spec/stack/deployment_spec.rb +26 -21
- data/spec/stack/execute_spec.rb +7 -3
- data/spec/stack/output_mapper_spec.rb +3 -15
- data/spec/stack/ssh_spec.rb +14 -13
- data/spec/stack/{stack_attribute_formater_spec.rb → stack_attribute_formatter_spec.rb} +19 -16
- data/spec/stack/stack_creator_spec.rb +46 -0
- data/spec/stack/stack_destroyer_spec.rb +18 -0
- data/spec/stack/stack_formatter_spec.rb +37 -0
- data/spec/stack/stack_lister_spec.rb +17 -0
- data/spec/stack/stack_reader_spec.rb +81 -0
- data/spec/stack/stack_updater_spec.rb +79 -0
- data/spec/stack/status_spec.rb +106 -0
- data/spec/stack_spec.rb +160 -133
- metadata +112 -19
- data/.rvmrc +0 -1
- data/lib/simple_deploy/config.rb +0 -87
data/.gitignore
CHANGED
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
|
@@ -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
|
-
|
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
|
49
|
+
template_file.write source_stack.template
|
47
50
|
end
|
48
51
|
|
49
|
-
|
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
|
93
|
-
|
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
|
100
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
65
|
-
|
66
|
-
|
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
|
-
|
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
|
-
|
30
|
-
|
31
|
-
stack = Stack.new :
|
32
|
-
:
|
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
|