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
@@ -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
|
@@ -4,9 +4,8 @@ module SimpleDeploy
|
|
4
4
|
|
5
5
|
def merge(args)
|
6
6
|
@attributes = args[:attributes]
|
7
|
-
@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 '
|
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 =
|
11
|
-
@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 =
|
22
|
-
|
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
|
-
@
|
30
|
-
room
|
31
|
-
|
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 ||=
|
40
|
-
|
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
|
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
|
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 ||=
|
49
|
-
|
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 =
|
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.
|
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 =
|
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.
|
94
|
-
@stack.
|
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 = { :
|
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
|
-
:
|
117
|
-
:
|
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 =
|
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 = { :
|
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 =
|
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 =
|
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
|
-
@
|
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
|
2
|
+
class StackAttributeFormatter
|
3
3
|
|
4
4
|
def initialize(args)
|
5
|
-
@config =
|
6
|
-
@
|
5
|
+
@config = SimpleDeploy.config
|
6
|
+
@logger = SimpleDeploy.logger
|
7
7
|
@main_attributes = args[:main_attributes]
|
8
|
-
@region = @config.region
|
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
|