opendelivery 0.4.4 → 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/opendelivery/domain.rb +45 -80
- data/lib/opendelivery.rb +0 -5
- metadata +13 -18
- data/lib/opendelivery/machine_image.rb +0 -78
- data/lib/opendelivery/source_control.rb +0 -101
- data/lib/opendelivery/stack.rb +0 -177
- data/lib/opendelivery/storage.rb +0 -74
- data/lib/opsworks.rb +0 -320
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTgxZDRiNTAzYWFhNzE0ZDM1OGE3NGE1NDRjYjljYmE0OGUyYjZlYg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MTUxODE0YzQ4YjdjODgyZWNlNGE5Y2ZiNWFkNmVjMWEzY2YwYjUzNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NmM4ZTdhNmZhNTcyYThjOWRkZjAyNjNhM2RhZjVmOTIxOWE2OTQyM2RmMDJh
|
10
|
+
OTRmMWJhMTJkZTQ5Y2M0NjU2MTg0MDY4ODkwY2M0NDc3NWE4ZTcxNjUyYWY4
|
11
|
+
MTIyMzdmNzNjOWMzMjZmNDg5Mjg5YWEyNzZhZWY1NjViN2ViYTY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Y2VmNTU0NWFmMDE1ZThjODEzODdlMzU0NmZjNWJiY2IyNDkzZTk3NmI5NDY4
|
14
|
+
ZDU3NzA3NWJkZWE3Mzk5ZDEwOTA1N2NiZjc3ZDQzYzJhYzQ5MDllYzZhNzBh
|
15
|
+
MTAwZmE4ZjI3MDdkZjIzZTFiNzI1ODg0NDliMTM5MWJjOGFhMjI=
|
data/lib/opendelivery/domain.rb
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
21
|
#THE SOFTWARE.
|
22
22
|
|
23
|
-
require 'aws-sdk'
|
23
|
+
require 'aws-sdk-core'
|
24
24
|
require 'encrypto_signo'
|
25
25
|
|
26
26
|
module OpenDelivery
|
@@ -30,108 +30,67 @@ module OpenDelivery
|
|
30
30
|
@key_path = File.read(key_path) unless key_path.nil?
|
31
31
|
|
32
32
|
if region.nil?
|
33
|
-
@sdb =
|
33
|
+
@sdb = Aws::SimpleDB::Client.new
|
34
34
|
else
|
35
|
-
@sdb =
|
35
|
+
@sdb = Aws::SimpleDB::Client.new(:region => region)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
def create(domain)
|
40
|
-
|
41
|
-
@sdb.domains.create(domain)
|
42
|
-
end
|
40
|
+
@sdb.create_domain(domain_name: domain)
|
43
41
|
end
|
44
42
|
|
45
43
|
def destroy(domain)
|
46
|
-
|
47
|
-
@sdb.domains[domain].delete
|
48
|
-
end
|
44
|
+
@sdb.delete_domain(domain_name: domain)
|
49
45
|
end
|
50
46
|
|
51
47
|
def destroy_item(domain, item_name)
|
52
|
-
|
53
|
-
|
54
|
-
end
|
48
|
+
@sdb.delete_attributes(domain_name: domain,
|
49
|
+
item_name: item_name)
|
55
50
|
end
|
56
51
|
|
57
52
|
def load_stack_properties(domain, stack)
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
stack.resources.each do |resource|
|
54
|
+
set_property(domain,
|
55
|
+
stack.name,
|
56
|
+
resource.resource_type,
|
57
|
+
resource.physical_resource_id)
|
62
58
|
end
|
63
59
|
end
|
64
60
|
|
65
|
-
def get_encrypted_property(domain, item_name, key
|
66
|
-
value = get_property(domain, item_name, key
|
67
|
-
|
61
|
+
def get_encrypted_property(domain, item_name, key)
|
62
|
+
value = get_property(domain, item_name, key)
|
63
|
+
EncryptoSigno.decrypt(@key_path, value.chomp)
|
68
64
|
end
|
69
65
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
AWS::SimpleDB.consistent_reads do
|
77
|
-
item = @sdb.domains[domain].items[item_name]
|
78
|
-
if !item.nil?
|
79
|
-
item.attributes.each do |att|
|
80
|
-
col_name = nil
|
81
|
-
|
82
|
-
att_array = att.name.split('|')
|
83
|
-
col_title = att_array.first
|
84
|
-
|
85
|
-
if att_array.length > 1
|
86
|
-
col_name = att_array[1]
|
87
|
-
end
|
66
|
+
def get_property(domain, item_name, key)
|
67
|
+
get_attributes_response = @sdb.get_attributes(domain_name: domain,
|
68
|
+
item_name: item_name,
|
69
|
+
attribute_names: [key],
|
70
|
+
consistent_read: true)
|
88
71
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
if name.nil?
|
94
|
-
# Not given a name to search for, just return the first one
|
95
|
-
# we have found.
|
96
|
-
attribute = att
|
97
|
-
break
|
98
|
-
else
|
99
|
-
|
100
|
-
# Give a 'name' search criteria, so match it against this column
|
101
|
-
if name == col_name
|
102
|
-
# 'name' criteria matches "|name" value, found a match
|
103
|
-
attribute = att
|
104
|
-
break
|
105
|
-
else
|
106
|
-
# 'name' criteria did not match, keep searching
|
107
|
-
end
|
108
|
-
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
if !attribute.nil?
|
113
|
-
value = attribute.values[index]
|
114
|
-
if !value.nil?
|
115
|
-
property_value = value.chomp
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
72
|
+
if get_attributes_response.attributes.empty?
|
73
|
+
nil
|
74
|
+
else
|
75
|
+
get_attributes_response.attributes.first.value.chomp
|
119
76
|
end
|
120
|
-
return property_value
|
121
77
|
end
|
122
78
|
|
123
|
-
def set_encrypted_property(domain, item_name, key, value
|
79
|
+
def set_encrypted_property(domain, item_name, key, value)
|
124
80
|
encrypted_value = EncryptoSigno.encrypt(@key_path, value.chomp)
|
125
|
-
set_property(domain, item_name, key, encrypted_value
|
81
|
+
set_property(domain, item_name, key, encrypted_value)
|
126
82
|
end
|
127
83
|
|
128
|
-
def set_property(domain, item_name, key, value
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
84
|
+
def set_property(domain, item_name, key, value)
|
85
|
+
@sdb.put_attributes(domain_name: domain,
|
86
|
+
item_name: item_name,
|
87
|
+
attributes: [
|
88
|
+
{
|
89
|
+
name: key,
|
90
|
+
value: value,
|
91
|
+
replace: true,
|
92
|
+
}
|
93
|
+
])
|
135
94
|
end
|
136
95
|
|
137
96
|
def load_domain(domain, json_file)
|
@@ -140,9 +99,15 @@ module OpenDelivery
|
|
140
99
|
|
141
100
|
obj.each do |item, attributes|
|
142
101
|
attributes.each do |key,value|
|
143
|
-
|
144
|
-
|
145
|
-
|
102
|
+
@sdb.put_attributes(domain_name: domain,
|
103
|
+
item_name: item,
|
104
|
+
attributes: [
|
105
|
+
{
|
106
|
+
name: key,
|
107
|
+
value: value,
|
108
|
+
replace: true,
|
109
|
+
}
|
110
|
+
])
|
146
111
|
end
|
147
112
|
end
|
148
113
|
end
|
data/lib/opendelivery.rb
CHANGED
@@ -20,12 +20,7 @@
|
|
20
20
|
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
21
|
#THE SOFTWARE.
|
22
22
|
|
23
|
-
require 'opendelivery/source_control.rb'
|
24
23
|
require 'opendelivery/domain.rb'
|
25
|
-
require 'opendelivery/machine_image.rb'
|
26
|
-
require 'opendelivery/stack.rb'
|
27
|
-
require 'opendelivery/storage.rb'
|
28
|
-
|
29
24
|
|
30
25
|
module OpenDelivery
|
31
26
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opendelivery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Jakovich
|
@@ -83,33 +83,33 @@ dependencies:
|
|
83
83
|
- !ruby/object:Gem::Version
|
84
84
|
version: 2.9.0
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
|
-
name:
|
86
|
+
name: aws-sdk
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
|
-
- -
|
89
|
+
- - ~>
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
version: 1.0
|
92
|
-
type: :
|
91
|
+
version: '1.0'
|
92
|
+
type: :development
|
93
93
|
prerelease: false
|
94
94
|
version_requirements: !ruby/object:Gem::Requirement
|
95
95
|
requirements:
|
96
|
-
- -
|
96
|
+
- - ~>
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version: 1.0
|
98
|
+
version: '1.0'
|
99
99
|
- !ruby/object:Gem::Dependency
|
100
|
-
name:
|
100
|
+
name: encrypto_signo
|
101
101
|
requirement: !ruby/object:Gem::Requirement
|
102
102
|
requirements:
|
103
|
-
- -
|
103
|
+
- - '='
|
104
104
|
- !ruby/object:Gem::Version
|
105
|
-
version:
|
105
|
+
version: 1.0.0
|
106
106
|
type: :runtime
|
107
107
|
prerelease: false
|
108
108
|
version_requirements: !ruby/object:Gem::Requirement
|
109
109
|
requirements:
|
110
|
-
- -
|
110
|
+
- - '='
|
111
111
|
- !ruby/object:Gem::Version
|
112
|
-
version:
|
112
|
+
version: 1.0.0
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: aws-sdk-core
|
115
115
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,11 +146,6 @@ extra_rdoc_files: []
|
|
146
146
|
files:
|
147
147
|
- lib/opendelivery.rb
|
148
148
|
- lib/opendelivery/domain.rb
|
149
|
-
- lib/opendelivery/machine_image.rb
|
150
|
-
- lib/opendelivery/source_control.rb
|
151
|
-
- lib/opendelivery/stack.rb
|
152
|
-
- lib/opendelivery/storage.rb
|
153
|
-
- lib/opsworks.rb
|
154
149
|
homepage: http://stelligent.com
|
155
150
|
licenses:
|
156
151
|
- MIT
|
@@ -164,7 +159,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
159
|
requirements:
|
165
160
|
- - ! '>='
|
166
161
|
- !ruby/object:Gem::Version
|
167
|
-
version:
|
162
|
+
version: 2.0.0
|
168
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
164
|
requirements:
|
170
165
|
- - ! '>='
|
@@ -1,78 +0,0 @@
|
|
1
|
-
#Copyright (c) 2014 Stelligent Systems LLC
|
2
|
-
#
|
3
|
-
#MIT LICENSE
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in
|
13
|
-
#all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
#THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'aws-sdk'
|
24
|
-
|
25
|
-
module OpenDelivery
|
26
|
-
class MachineImage
|
27
|
-
|
28
|
-
def initialize(region=nil)
|
29
|
-
if region.nil?
|
30
|
-
@ec2 = AWS::EC2.new
|
31
|
-
@sdb = AWS::SimpleDB.new
|
32
|
-
@auto_scale = AWS::AutoScaling.new
|
33
|
-
@domain = OpenDelivery::Domain.new
|
34
|
-
else
|
35
|
-
@ec2 = AWS::EC2.new(:region => region)
|
36
|
-
@sdb = AWS::SimpleDB.new(:region => region)
|
37
|
-
@auto_scale = AWS::AutoScaling.new(:region => region)
|
38
|
-
@domain = OpenDelivery::Domain.new(:region => region)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def create(domain, stack_name)
|
43
|
-
instance_id = prep_instance(domain, stack_name)
|
44
|
-
image = @ec2.images.create(
|
45
|
-
instance_id: instance_id,
|
46
|
-
name: image_name)
|
47
|
-
|
48
|
-
wait_for_image(image)
|
49
|
-
end
|
50
|
-
|
51
|
-
protected
|
52
|
-
|
53
|
-
def wait_for_image(image)
|
54
|
-
# Waiting for AWS to realize the image is ready to start
|
55
|
-
sleep 10
|
56
|
-
|
57
|
-
while image.state != :available
|
58
|
-
sleep 10
|
59
|
-
case image.state
|
60
|
-
when :failed
|
61
|
-
image.delete
|
62
|
-
raise RuntimeError, 'Image Creation Failed'
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def prep_instance(domain, stack_name)
|
68
|
-
group_name = @domain.get_property(domain, stack_name, "AWS::AutoScaling::AutoScalingGroup")
|
69
|
-
instance = @auto_scale.groups[group_name].auto_scaling_instances.first.id
|
70
|
-
@ec2.instances[instance].stop
|
71
|
-
|
72
|
-
while @ec2.instances[instance].status != :stopped
|
73
|
-
sleep 10
|
74
|
-
end
|
75
|
-
return instance
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,101 +0,0 @@
|
|
1
|
-
#Copyright (c) 2014 Stelligent Systems LLC
|
2
|
-
#
|
3
|
-
#MIT LICENSE
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in
|
13
|
-
#all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
#THE SOFTWARE.
|
22
|
-
|
23
|
-
module OpenDelivery
|
24
|
-
class SourceControl
|
25
|
-
def initialize(dir)
|
26
|
-
@dir = dir
|
27
|
-
end
|
28
|
-
|
29
|
-
def log(lines=10)
|
30
|
-
Dir.chdir(@dir) do
|
31
|
-
`git log --stat -n #{lines}`
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def status
|
36
|
-
Dir.chdir(@dir) do
|
37
|
-
`git status -sb`
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def remove_missing_files(status)
|
42
|
-
removed_files = []
|
43
|
-
files = find_removed_files(status)
|
44
|
-
files.each do |file|
|
45
|
-
Dir.chdir(@dir) do
|
46
|
-
removed_files << `git rm -rf #{file}`
|
47
|
-
end
|
48
|
-
end
|
49
|
-
removed_files
|
50
|
-
end
|
51
|
-
|
52
|
-
def add(files)
|
53
|
-
Dir.chdir(@dir) do
|
54
|
-
`git add #{files} -v`
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def commit(message)
|
59
|
-
Dir.chdir(@dir) do
|
60
|
-
`git commit -m "#{message}"`
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def push
|
65
|
-
Dir.chdir(@dir) do
|
66
|
-
`git push`
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def pull
|
71
|
-
Dir.chdir(@dir) do
|
72
|
-
@result = `git pull`
|
73
|
-
end
|
74
|
-
if $?.to_i != 0
|
75
|
-
raise "Your pull failed. Probably because of a merge conflict!"
|
76
|
-
end
|
77
|
-
@result
|
78
|
-
end
|
79
|
-
|
80
|
-
def conflicted(status)
|
81
|
-
status.each_line do |stat|
|
82
|
-
if stat.match(/^UU /) || stat.match(/^U /) || stat.match(/^U /)
|
83
|
-
raise "You have file conflicts when trying to merge. Because this could end up horribly, we won't try to automatically fix these conflicts. Please go an manually merge the files!"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
protected
|
89
|
-
|
90
|
-
|
91
|
-
def find_removed_files(status)
|
92
|
-
statuses = []
|
93
|
-
status.each_line do |stat|
|
94
|
-
if stat.match(/^ D /)
|
95
|
-
statuses << stat.split[1]
|
96
|
-
end
|
97
|
-
end
|
98
|
-
statuses
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
data/lib/opendelivery/stack.rb
DELETED
@@ -1,177 +0,0 @@
|
|
1
|
-
#Copyright (c) 2014 Stelligent Systems LLC
|
2
|
-
#
|
3
|
-
#MIT LICENSE
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in
|
13
|
-
#all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
#THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'aws-sdk'
|
24
|
-
|
25
|
-
module OpenDelivery
|
26
|
-
class Stack
|
27
|
-
|
28
|
-
def initialize(region=nil)
|
29
|
-
if region.nil?
|
30
|
-
@cfn = AWS::CloudFormation.new
|
31
|
-
@autoscaling = AWS::AutoScaling.new
|
32
|
-
else
|
33
|
-
@autoscaling = AWS::AutoScaling.new(:region => region)
|
34
|
-
@cfn = AWS::CloudFormation.new(:region => region)
|
35
|
-
end
|
36
|
-
@domain = OpenDelivery::Domain.new(region)
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
SUCCESS_STATUSES = [ "CREATE_COMPLETE",
|
41
|
-
"UPDATE_COMPLETE" ]
|
42
|
-
|
43
|
-
FAILURE_STATUSES = [ "CREATE_FAILED",
|
44
|
-
"ROLLBACK_FAILED",
|
45
|
-
"ROLLBACK_COMPLETE",
|
46
|
-
"DELETE_FAILED",
|
47
|
-
"UPDATE_ROLLBACK_FAILED",
|
48
|
-
"UPDATE_ROLLBACK_COMPLETE",
|
49
|
-
"DELETE_COMPLETE" ]
|
50
|
-
|
51
|
-
PROGRESS_STATUSES = [ "CREATE_IN_PROGRESS",
|
52
|
-
"ROLLBACK_IN_PROGRESS",
|
53
|
-
"DELETE_IN_PROGRESS",
|
54
|
-
"UPDATE_IN_PROGRESS",
|
55
|
-
"UPDATE_COMPLETE_CLEANUP_IN_PROGRESS",
|
56
|
-
"UPDATE_ROLLBACK_IN_PROGRESS",
|
57
|
-
"UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS" ]
|
58
|
-
|
59
|
-
def watch(stack_name, sleep_time, silent=false)
|
60
|
-
success = false
|
61
|
-
begin
|
62
|
-
stack = @cfn.stacks[stack_name]
|
63
|
-
success = watch_loop(stack, sleep_time, silent)
|
64
|
-
rescue AWS::CloudFormation::Errors::ValidationError => msg
|
65
|
-
print_status "Exception raised: #{msg}"
|
66
|
-
success = false
|
67
|
-
end
|
68
|
-
return success
|
69
|
-
end
|
70
|
-
|
71
|
-
|
72
|
-
def create(stack_name, template, parameters = {}, wait=false, domain=nil, tags = {})
|
73
|
-
@cfn.stacks.create(stack_name,
|
74
|
-
File.open(template, "r").read,
|
75
|
-
:parameters => parameters,
|
76
|
-
:tags => tags,
|
77
|
-
:capabilities => ["CAPABILITY_IAM"],
|
78
|
-
:disable_rollback => true)
|
79
|
-
end
|
80
|
-
|
81
|
-
def destroy(stack_name, domain=nil, wait=false)
|
82
|
-
stack = @cfn.stacks[stack_name]
|
83
|
-
if stack.exists?
|
84
|
-
resume_scaling_activities(stack_name)
|
85
|
-
stack.delete
|
86
|
-
while wait and stack.exists?
|
87
|
-
sleep 20
|
88
|
-
end
|
89
|
-
@domain.destroy_item(domain, stack_name)
|
90
|
-
else
|
91
|
-
raise "Stack: #{stack_name} doesn't exist, therefore it cannot be destroyed"
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def list
|
96
|
-
@cfn.stacks.each do |stack|
|
97
|
-
puts "Stack Name: #{stack.name} | Status: #{stack.status}"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def resume_scaling_activities(stack_name)
|
102
|
-
stack = @cfn.stacks[stack_name]
|
103
|
-
stack.resources.each do |resource|
|
104
|
-
if resource.resource_type == "AWS::AutoScaling::AutoScalingGroup"
|
105
|
-
begin
|
106
|
-
@autoscaling.groups[resource.physical_resource_id].resume_all_processes
|
107
|
-
rescue Exception => e
|
108
|
-
puts "ASG operation failed with [#{e.message}]"
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
protected
|
115
|
-
|
116
|
-
def wait_for_stack(stack, wait)
|
117
|
-
if wait
|
118
|
-
while stack.status != "CREATE_COMPLETE"
|
119
|
-
sleep 20
|
120
|
-
|
121
|
-
if FAILURE_STATUSES.include? stack.status
|
122
|
-
stack.delete
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def print_status(status, silent=false)
|
129
|
-
timestamp = Time.now.strftime("%Y.%m.%d %H:%M:%S:%L")
|
130
|
-
unless silent
|
131
|
-
puts "#{timestamp}: #{status}"
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def watch_loop(stack, sleep_time, silent)
|
136
|
-
keep_watching = true
|
137
|
-
success = false
|
138
|
-
abort_count = 10
|
139
|
-
while(keep_watching) do
|
140
|
-
begin
|
141
|
-
stack_status = stack.status
|
142
|
-
if (SUCCESS_STATUSES.include? stack_status)
|
143
|
-
status = "Success: #{stack_status}"
|
144
|
-
print_status(status, silent)
|
145
|
-
success = true
|
146
|
-
keep_watching = false
|
147
|
-
elsif (PROGRESS_STATUSES.include? stack_status)
|
148
|
-
status = "In Progress: #{stack_status}"
|
149
|
-
print_status(status, silent)
|
150
|
-
success = false
|
151
|
-
keep_watching = true
|
152
|
-
elsif (FAILURE_STATUSES.include? stack_status)
|
153
|
-
status = "Failed: #{stack_status}"
|
154
|
-
print_status(status, silent)
|
155
|
-
success = false
|
156
|
-
keep_watching = false
|
157
|
-
else
|
158
|
-
status = "didn't find #{stack_status} in the list of expected statuses"
|
159
|
-
print_status(status, silent)
|
160
|
-
success = false
|
161
|
-
abort_count = abort_count - 1
|
162
|
-
# if we get too many unknown statuses, assume something has gone horribly wrong and quit.
|
163
|
-
keep_watching = (abort_count > 0)
|
164
|
-
end
|
165
|
-
rescue AWS::CloudFormation::Errors::Throttling
|
166
|
-
status = "Rate limit exceeded, retrying..."
|
167
|
-
print_status(status, silent)
|
168
|
-
sleep(sleep_time * 0.1)
|
169
|
-
end
|
170
|
-
if keep_watching
|
171
|
-
sleep(sleep_time)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
return success
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
data/lib/opendelivery/storage.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
#Copyright (c) 2014 Stelligent Systems LLC
|
2
|
-
#
|
3
|
-
#MIT LICENSE
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in
|
13
|
-
#all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
#THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'aws-sdk'
|
24
|
-
|
25
|
-
module OpenDelivery
|
26
|
-
class Storage
|
27
|
-
|
28
|
-
def initialize(region=nil)
|
29
|
-
if region.nil?
|
30
|
-
@s3 = AWS::S3.new
|
31
|
-
else
|
32
|
-
@s3 = AWS::S3.new(:region => region)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def copy(bucket, key, desired_key)
|
37
|
-
@s3.buckets[bucket].objects[key].copy_to(desired_key)
|
38
|
-
end
|
39
|
-
|
40
|
-
def upload(bucket, file, key)
|
41
|
-
@s3.buckets[bucket].objects[key].write(:file => file)
|
42
|
-
end
|
43
|
-
|
44
|
-
def download(bucket, key, output_directory)
|
45
|
-
# Puke if the bucket doesn't exist
|
46
|
-
raise "Bucket #{bucket} doesn't exist" unless @s3.buckets[bucket].exists?
|
47
|
-
|
48
|
-
# Puke if the key doesn't exist. This can cause problems with some bucket policies, so we catch and re-throw
|
49
|
-
begin
|
50
|
-
raise "File with key #{key} doesn't exist in bucket #{bucket}" unless @s3.buckets[bucket].objects[key].exists?
|
51
|
-
rescue Exception => e
|
52
|
-
raise "Exception [#{e.message}] occurred downloading key #{key} from bucket #{bucket}"
|
53
|
-
end
|
54
|
-
|
55
|
-
obj = @s3.buckets[bucket].objects[key]
|
56
|
-
|
57
|
-
base = Pathname.new("#{obj.key}").basename
|
58
|
-
|
59
|
-
Dir.mkdir(output_directory) unless File.exists?(output_directory)
|
60
|
-
|
61
|
-
File.open("#{output_directory}/#{base}", 'wb') do |file|
|
62
|
-
obj.read do |chunk|
|
63
|
-
file.write(chunk)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def add_timestamp(identifier, artifact)
|
69
|
-
timestamp = Time.now.strftime("%Y.%m.%d.%H.%M.%S.%L")
|
70
|
-
stamped_artifact = "#{artifact}-#{identifier}-#{timestamp}"
|
71
|
-
return stamped_artifact
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
data/lib/opsworks.rb
DELETED
@@ -1,320 +0,0 @@
|
|
1
|
-
#Copyright (c) 2014 Stelligent Systems LLC
|
2
|
-
#
|
3
|
-
#MIT LICENSE
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in
|
13
|
-
#all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
#THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'aws-sdk'
|
24
|
-
|
25
|
-
module OpsWorks
|
26
|
-
|
27
|
-
def create_and_launch_stack(stack_description)
|
28
|
-
stack_id = create_stack(stack_description)
|
29
|
-
launch_stack(stack_id)
|
30
|
-
deploy_apps(stack_id)
|
31
|
-
stack_id
|
32
|
-
end
|
33
|
-
|
34
|
-
def create_and_launch_stack_in_order(stack_description, layers_by_order)
|
35
|
-
stack_id = create_stack(stack_description)
|
36
|
-
launch_stack_in_order(stack_id, layers_by_order)
|
37
|
-
deploy_apps(stack_id)
|
38
|
-
stack_id
|
39
|
-
end
|
40
|
-
|
41
|
-
def create_stack(stack_description)
|
42
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
43
|
-
|
44
|
-
response = opsworks_client.create_stack(stack_description.stack_description)
|
45
|
-
stack_id = response[:stack_id]
|
46
|
-
|
47
|
-
wait_on_opsworks_sg_creation(stack_description.stack_description[:vpc_id]) if stack_description.stack_description[:vpc_id]
|
48
|
-
|
49
|
-
layer_descriptions = stack_description.layer_descriptions
|
50
|
-
layer_descriptions.each do |layer_description|
|
51
|
-
layer_description[:layer][:stack_id] = stack_id
|
52
|
-
|
53
|
-
response = opsworks_client.create_layer(layer_description[:layer])
|
54
|
-
layer_id = response[:layer_id]
|
55
|
-
layer_description[:layer][:layer_id] = layer_id
|
56
|
-
|
57
|
-
layer_description[:instances].each do |instance_description|
|
58
|
-
instance_description[:stack_id] = stack_id
|
59
|
-
instance_description[:layer_ids] = [layer_id]
|
60
|
-
|
61
|
-
save_off = instance_description[:extra_layers]
|
62
|
-
instance_description.delete :extra_layers
|
63
|
-
response = opsworks_client.create_instance(instance_description)
|
64
|
-
instance_description[:instance_id] = response[:instance_id]
|
65
|
-
instance_description[:extra_layers] = save_off
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
layer_descriptions.each do |layer_description|
|
70
|
-
layer_description[:instances].each do |instance_description|
|
71
|
-
if instance_description[:extra_layers]
|
72
|
-
instance_description[:extra_layers].each do |extra_layer_name|
|
73
|
-
found_extra_layer = layer_descriptions.find { |desc| desc[:layer][:name] == extra_layer_name }
|
74
|
-
|
75
|
-
raise "missing extra layer: #{extra_layer_name}" unless found_extra_layer
|
76
|
-
instance_description[:layer_ids] << found_extra_layer[:layer][:layer_id]
|
77
|
-
response = opsworks_client.update_instance(:instance_id => instance_description[:instance_id],
|
78
|
-
:layer_ids => instance_description[:layer_ids])
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
stack_description.app_descriptions.each do |app_description|
|
85
|
-
app_description[:stack_id] = stack_id
|
86
|
-
response = opsworks_client.create_app(app_description)
|
87
|
-
end
|
88
|
-
|
89
|
-
stack_id
|
90
|
-
end
|
91
|
-
|
92
|
-
def launch_stack(stack_id)
|
93
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
94
|
-
|
95
|
-
opsworks_client.start_stack(:stack_id => stack_id)
|
96
|
-
|
97
|
-
wait_on_setup(stack_id)
|
98
|
-
|
99
|
-
wait_on_all_configures(stack_id)
|
100
|
-
end
|
101
|
-
|
102
|
-
|
103
|
-
def launch_stack_in_order(stack_id, layers_by_order)
|
104
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
105
|
-
|
106
|
-
layers_by_order.each do |layer_names|
|
107
|
-
layer_names.each do |layer_name|
|
108
|
-
|
109
|
-
response = opsworks_client.describe_layers( :stack_id => stack_id)
|
110
|
-
layer = response[:layers].find { |layer| layer[:shortname] == layer_name }
|
111
|
-
raise "layer #{layer_name} not found in stack: #{stack_id}" if layer.nil?
|
112
|
-
|
113
|
-
response = opsworks_client.describe_instances( :layer_id => layer[:layer_id])
|
114
|
-
response[:instances].each do |instance|
|
115
|
-
opsworks_client.start_instance( :instance_id => instance[:instance_id])
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
layer_names.each do |layer_name|
|
120
|
-
response = opsworks_client.describe_layers( :stack_id => stack_id)
|
121
|
-
layer = response[:layers].find { |layer| layer[:shortname] == layer_name }
|
122
|
-
raise "layer #{layer_name} not found in stack: #{stack_id}" if layer.nil?
|
123
|
-
|
124
|
-
wait_on_layer_setup(layer[:layer_id])
|
125
|
-
wait_on_layer_configures(layer[:layer_id])
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def deploy_apps(stack_id)
|
131
|
-
deployment_ids = []
|
132
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
133
|
-
response = opsworks_client.describe_apps(:stack_id => stack_id)
|
134
|
-
response[:apps].each do |app|
|
135
|
-
|
136
|
-
puts "DEPLOYING THE APP: #{app}"
|
137
|
-
response = opsworks_client.create_deployment(:stack_id => stack_id,
|
138
|
-
:app_id => app[:app_id],
|
139
|
-
:command => {
|
140
|
-
:name => 'deploy',
|
141
|
-
:args => deployment_args_factory(app)
|
142
|
-
})
|
143
|
-
deployment_ids << response[:deployment_id]
|
144
|
-
end
|
145
|
-
|
146
|
-
max_attempts = 250
|
147
|
-
num_attempts = 0
|
148
|
-
|
149
|
-
deployments_complete = false
|
150
|
-
until deployments_complete
|
151
|
-
response = opsworks_client.describe_deployments(:deployment_ids => deployment_ids)
|
152
|
-
deployments_complete = response[:deployments].inject(true) do |status, deployment|
|
153
|
-
puts "Deployment status: #{deployment[:status]}"
|
154
|
-
|
155
|
-
if deployment[:status] == 'failed'
|
156
|
-
raise 'deployment failed'
|
157
|
-
end
|
158
|
-
|
159
|
-
status and (deployment[:status] == 'successful')
|
160
|
-
end
|
161
|
-
num_attempts += 1
|
162
|
-
if num_attempts >= max_attempts
|
163
|
-
raise 'stuck waiting on configure command max attempts'
|
164
|
-
end
|
165
|
-
sleep 10
|
166
|
-
end
|
167
|
-
deployment_ids
|
168
|
-
end
|
169
|
-
|
170
|
-
def discover_private_ips(stack_id, layer_name)
|
171
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
172
|
-
response = opsworks_client.describe_layers( :stack_id => stack_id)
|
173
|
-
layer = response[:layers].find { |layer| layer[:name] == layer_name }
|
174
|
-
raise "layer #{layer_name} not found in stack: #{stack_id}" if layer.nil?
|
175
|
-
|
176
|
-
response = opsworks_client.describe_instances( :layer_id => layer[:layer_id] )
|
177
|
-
response[:instances].collect { |instance| instance[:private_ip] }
|
178
|
-
end
|
179
|
-
|
180
|
-
def discover_public_ips(stack_id, layer_name)
|
181
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
182
|
-
response = opsworks_client.describe_layers( :stack_id => stack_id)
|
183
|
-
layer = response[:layers].find { |layer| layer[:name] == layer_name }
|
184
|
-
raise "layer #{layer_name} not found in stack: #{stack_id}" if layer.nil?
|
185
|
-
|
186
|
-
response = opsworks_client.describe_instances( :layer_id => layer[:layer_id] )
|
187
|
-
response[:instances].collect { |instance| instance[:public_ip] }
|
188
|
-
end
|
189
|
-
|
190
|
-
protected
|
191
|
-
|
192
|
-
def deployment_args_factory(app)
|
193
|
-
if app[:type] == 'rails'
|
194
|
-
{
|
195
|
-
'migrate' => %w{true}
|
196
|
-
}
|
197
|
-
else
|
198
|
-
{}
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
private
|
203
|
-
|
204
|
-
def wait_on_opsworks_sg_creation(vpc_id)
|
205
|
-
opsworks_security_group_names.each do |sg_name|
|
206
|
-
while AWS.ec2.security_groups.filter('vpc-id', vpc_id).filter('group-name', sg_name).count == 0
|
207
|
-
puts "Waiting on #{sg_name}, #{a = a ? a+1 : 1}"
|
208
|
-
sleep 1
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def opsworks_security_group_names
|
214
|
-
%w{AWS-OpsWorks-Default-Server AWS-OpsWorks-Blank-Server AWS-OpsWorks-Custom-Server AWS-OpsWorks-Rails-App-Server AWS-OpsWorks-PHP-App-Server}
|
215
|
-
end
|
216
|
-
|
217
|
-
|
218
|
-
def complete(status)
|
219
|
-
failure(status) or success(status)
|
220
|
-
end
|
221
|
-
|
222
|
-
def failure(status)
|
223
|
-
%w{setup_failed start_failed terminated connection_lost}.include? status
|
224
|
-
end
|
225
|
-
|
226
|
-
def success(status)
|
227
|
-
%w{online}.include? status
|
228
|
-
end
|
229
|
-
|
230
|
-
def wait_on_setup(stack_id)
|
231
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
232
|
-
|
233
|
-
setup_complete = false
|
234
|
-
until setup_complete
|
235
|
-
response = opsworks_client.describe_instances(:stack_id => stack_id)
|
236
|
-
setup_complete = response[:instances].inject(true) do |status, instance|
|
237
|
-
if failure(instance[:status])
|
238
|
-
raise 'setup failed'
|
239
|
-
end
|
240
|
-
|
241
|
-
instance_status(instance)
|
242
|
-
|
243
|
-
status and complete(instance[:status])
|
244
|
-
end
|
245
|
-
sleep 10
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
def wait_on_layer_setup(layer_id)
|
250
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
251
|
-
|
252
|
-
setup_complete = false
|
253
|
-
until setup_complete
|
254
|
-
response = opsworks_client.describe_instances(:layer_id => layer_id)
|
255
|
-
setup_complete = response[:instances].inject(true) do |status, instance|
|
256
|
-
if failure(instance[:status])
|
257
|
-
raise 'setup failed'
|
258
|
-
end
|
259
|
-
|
260
|
-
instance_status(instance)
|
261
|
-
|
262
|
-
status and complete(instance[:status])
|
263
|
-
end
|
264
|
-
sleep 10
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
def instance_status(instance)
|
269
|
-
puts "Instance: #{instance[:instance_id]} has status #{instance[:status]}"
|
270
|
-
end
|
271
|
-
|
272
|
-
def configure_status(configure_command)
|
273
|
-
puts "Configure command: #{configure_command}"
|
274
|
-
end
|
275
|
-
|
276
|
-
def wait_on_all_configures(stack_id)
|
277
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
278
|
-
response = opsworks_client.describe_instances(:stack_id => stack_id)
|
279
|
-
response[:instances].each do |instance|
|
280
|
-
wait_on_configure(instance[:instance_id])
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
def wait_on_layer_configures(layer_id)
|
285
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
286
|
-
response = opsworks_client.describe_instances(:layer_id => layer_id)
|
287
|
-
response[:instances].each do |instance|
|
288
|
-
wait_on_configure(instance[:instance_id])
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
def wait_on_configure(instance_id)
|
293
|
-
opsworks_client = AWS::OpsWorks::Client::V20130218.new
|
294
|
-
|
295
|
-
max_attempts = 250
|
296
|
-
num_attempts = 0
|
297
|
-
|
298
|
-
while true
|
299
|
-
response = opsworks_client.describe_commands(:instance_id => instance_id)
|
300
|
-
configure_command = response[:commands].find { |command| command[:type] == 'configure' }
|
301
|
-
|
302
|
-
configure_status(configure_command)
|
303
|
-
|
304
|
-
unless configure_command.nil?
|
305
|
-
#i guess just bail if superseded, waiting on configure events is somewhat dubious after seeing more complex stacks in action anyway!
|
306
|
-
if %w{successful superseded}.include? configure_command[:status]
|
307
|
-
return
|
308
|
-
elsif configure_command[:status] == 'failed'
|
309
|
-
raise 'configure failed'
|
310
|
-
end
|
311
|
-
end
|
312
|
-
num_attempts += 1
|
313
|
-
if num_attempts >= max_attempts
|
314
|
-
raise 'stuck waiting on configure command max attempts'
|
315
|
-
end
|
316
|
-
sleep 10
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
|
-
end
|