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.
- 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
|