server_maint 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitmodules +21 -0
- data/lib/cookbooks/aws/CHANGELOG.md +11 -0
- data/lib/cookbooks/aws/CONTRIBUTING +29 -0
- data/lib/cookbooks/aws/LICENSE +201 -0
- data/lib/cookbooks/aws/README.md +271 -0
- data/lib/cookbooks/aws/attributes/default.rb +20 -0
- data/lib/cookbooks/aws/libraries/ec2.rb +58 -0
- data/lib/cookbooks/aws/metadata.rb +7 -0
- data/lib/cookbooks/aws/providers/ebs_volume.rb +236 -0
- data/lib/cookbooks/aws/providers/elastic_ip.rb +90 -0
- data/lib/cookbooks/aws/providers/elastic_lb.rb +24 -0
- data/lib/cookbooks/aws/providers/resource_tag.rb +93 -0
- data/lib/cookbooks/aws/recipes/default.rb +25 -0
- data/lib/cookbooks/aws/resources/ebs_volume.rb +17 -0
- data/lib/cookbooks/aws/resources/elastic_ip.rb +11 -0
- data/lib/cookbooks/aws/resources/elastic_lb.rb +10 -0
- data/lib/cookbooks/aws/resources/resource_tag.rb +11 -0
- data/lib/cookbooks/database/.gitignore +1 -0
- data/lib/cookbooks/database/CHANGELOG.md +51 -0
- data/lib/cookbooks/database/CONTRIBUTING +29 -0
- data/lib/cookbooks/database/LICENSE +201 -0
- data/lib/cookbooks/database/README.md +468 -0
- data/lib/cookbooks/database/libraries/provider_database_mysql.rb +103 -0
- data/lib/cookbooks/database/libraries/provider_database_mysql_user.rb +76 -0
- data/lib/cookbooks/database/libraries/provider_database_postgresql.rb +131 -0
- data/lib/cookbooks/database/libraries/provider_database_postgresql_user.rb +83 -0
- data/lib/cookbooks/database/libraries/provider_database_sql_server.rb +109 -0
- data/lib/cookbooks/database/libraries/provider_database_sql_server_user.rb +106 -0
- data/lib/cookbooks/database/libraries/resource_database.rb +119 -0
- data/lib/cookbooks/database/libraries/resource_database_user.rb +90 -0
- data/lib/cookbooks/database/libraries/resource_mysql_database.rb +34 -0
- data/lib/cookbooks/database/libraries/resource_mysql_database_user.rb +34 -0
- data/lib/cookbooks/database/libraries/resource_postgresql_database.rb +35 -0
- data/lib/cookbooks/database/libraries/resource_postgresql_database_user.rb +35 -0
- data/lib/cookbooks/database/libraries/resource_sql_server_database.rb +34 -0
- data/lib/cookbooks/database/libraries/resource_sql_server_database_user.rb +34 -0
- data/lib/cookbooks/database/metadata.rb +22 -0
- data/lib/cookbooks/database/recipes/default.rb +20 -0
- data/lib/cookbooks/database/recipes/ebs_backup.rb +89 -0
- data/lib/cookbooks/database/recipes/ebs_volume.rb +204 -0
- data/lib/cookbooks/database/recipes/master.rb +78 -0
- data/lib/cookbooks/database/recipes/mysql.rb +20 -0
- data/lib/cookbooks/database/recipes/postgresql.rb +20 -0
- data/lib/cookbooks/database/recipes/snapshot.rb +62 -0
- data/lib/cookbooks/database/templates/default/app_grants.sql.erb +8 -0
- data/lib/cookbooks/database/templates/default/aws_config.erb +3 -0
- data/lib/cookbooks/database/templates/default/chef-solo-database-snapshot.cron.erb +6 -0
- data/lib/cookbooks/database/templates/default/chef-solo-database-snapshot.json.erb +1 -0
- data/lib/cookbooks/database/templates/default/chef-solo-database-snapshot.rb.erb +6 -0
- data/lib/cookbooks/database/templates/default/ebs-backup-cron.erb +2 -0
- data/lib/cookbooks/database/templates/default/ebs-db-backup.sh.erb +8 -0
- data/lib/cookbooks/database/templates/default/ebs-db-restore.sh.erb +10 -0
- data/lib/cookbooks/database/templates/default/s3cfg.erb +27 -0
- data/lib/cookbooks/mysql/.gitignore +5 -0
- data/lib/cookbooks/mysql/CHANGELOG.md +86 -0
- data/lib/cookbooks/mysql/CONTRIBUTING +29 -0
- data/lib/cookbooks/mysql/Gemfile +8 -0
- data/lib/cookbooks/mysql/LICENSE +201 -0
- data/lib/cookbooks/mysql/README.md +227 -0
- data/lib/cookbooks/mysql/attributes/client.rb +50 -0
- data/lib/cookbooks/mysql/attributes/server.rb +153 -0
- data/lib/cookbooks/mysql/files/default/tests/minitest/server_test.rb +36 -0
- data/lib/cookbooks/mysql/files/default/tests/minitest/support/helpers.rb +11 -0
- data/lib/cookbooks/mysql/libraries/helpers.rb +33 -0
- data/lib/cookbooks/mysql/metadata.rb +140 -0
- data/lib/cookbooks/mysql/recipes/client.rb +59 -0
- data/lib/cookbooks/mysql/recipes/default.rb +20 -0
- data/lib/cookbooks/mysql/recipes/ruby.rb +36 -0
- data/lib/cookbooks/mysql/recipes/server.rb +216 -0
- data/lib/cookbooks/mysql/recipes/server_ec2.rb +51 -0
- data/lib/cookbooks/mysql/templates/default/debian.cnf.erb +12 -0
- data/lib/cookbooks/mysql/templates/default/grants.sql.erb +15 -0
- data/lib/cookbooks/mysql/templates/default/my.cnf.erb +211 -0
- data/lib/cookbooks/mysql/templates/default/mysql-server.seed.erb +10 -0
- data/lib/cookbooks/mysql/templates/default/port_mysql.erb +3 -0
- data/lib/cookbooks/mysql/templates/windows/my.cnf.erb +61 -0
- data/lib/cookbooks/mysql/test/features/query_database.feature +26 -0
- data/lib/cookbooks/mysql/test/features/step_definitions/mysql_steps.rb +47 -0
- data/lib/cookbooks/mysql/test/features/support/env.rb +3 -0
- data/lib/cookbooks/mysql/test/features/support/mysql_helpers.rb +51 -0
- data/lib/cookbooks/mysql/test/kitchen/Kitchenfile +5 -0
- data/lib/cookbooks/mysql/test/kitchen/cookbooks/mysql_test/.gitignore +1 -0
- data/lib/cookbooks/mysql/test/kitchen/cookbooks/mysql_test/README.md +63 -0
- data/lib/cookbooks/mysql/test/kitchen/cookbooks/mysql_test/attributes/default.rb +27 -0
- data/lib/cookbooks/mysql/test/kitchen/cookbooks/mysql_test/metadata.rb +10 -0
- data/lib/cookbooks/mysql/test/kitchen/cookbooks/mysql_test/recipes/client.rb +20 -0
- data/lib/cookbooks/mysql/test/kitchen/cookbooks/mysql_test/recipes/server.rb +72 -0
- data/lib/cookbooks/openssl/CHANGELOG.md +0 -0
- data/lib/cookbooks/openssl/CONTRIBUTING +29 -0
- data/lib/cookbooks/openssl/LICENSE +201 -0
- data/lib/cookbooks/openssl/README.md +37 -0
- data/lib/cookbooks/openssl/libraries/secure_password.rb +37 -0
- data/lib/cookbooks/openssl/metadata.rb +8 -0
- data/lib/cookbooks/openssl/recipes/default.rb +19 -0
- data/lib/cookbooks/postgresql/CHANGELOG.md +35 -0
- data/lib/cookbooks/postgresql/CONTRIBUTING +29 -0
- data/lib/cookbooks/postgresql/LICENSE +201 -0
- data/lib/cookbooks/postgresql/README.md +148 -0
- data/lib/cookbooks/postgresql/attributes/default.rb +103 -0
- data/lib/cookbooks/postgresql/metadata.rb +21 -0
- data/lib/cookbooks/postgresql/recipes/client.rb +26 -0
- data/lib/cookbooks/postgresql/recipes/default.rb +20 -0
- data/lib/cookbooks/postgresql/recipes/ruby.rb +40 -0
- data/lib/cookbooks/postgresql/recipes/server.rb +64 -0
- data/lib/cookbooks/postgresql/recipes/server_debian.rb +64 -0
- data/lib/cookbooks/postgresql/recipes/server_redhat.rb +77 -0
- data/lib/cookbooks/postgresql/templates/default/debian.postgresql.conf.erb +499 -0
- data/lib/cookbooks/postgresql/templates/default/pg_hba.conf.erb +83 -0
- data/lib/cookbooks/postgresql/templates/default/redhat.postgresql.conf.erb +501 -0
- data/lib/cookbooks/sqlite/.gitignore +4 -0
- data/lib/cookbooks/sqlite/CHANGELOG.md +3 -0
- data/lib/cookbooks/sqlite/CONTRIBUTING +29 -0
- data/lib/cookbooks/sqlite/Gemfile +2 -0
- data/lib/cookbooks/sqlite/LICENSE +201 -0
- data/lib/cookbooks/sqlite/README.md +36 -0
- data/lib/cookbooks/sqlite/metadata.rb +12 -0
- data/lib/cookbooks/sqlite/recipes/default.rb +30 -0
- data/lib/cookbooks/sqlite/test/kitchen/Kitchenfile +1 -0
- data/lib/cookbooks/xfs/CHANGELOG.md +0 -0
- data/lib/cookbooks/xfs/CONTRIBUTING +29 -0
- data/lib/cookbooks/xfs/LICENSE +201 -0
- data/lib/cookbooks/xfs/README.md +30 -0
- data/lib/cookbooks/xfs/metadata.rb +12 -0
- data/lib/cookbooks/xfs/recipes/default.rb +26 -0
- data/lib/server_maint/version.rb +1 -1
- metadata +127 -4
@@ -0,0 +1,236 @@
|
|
1
|
+
include Opscode::Aws::Ec2
|
2
|
+
|
3
|
+
# Support whyrun
|
4
|
+
def whyrun_supported?
|
5
|
+
true
|
6
|
+
end
|
7
|
+
|
8
|
+
action :create do
|
9
|
+
raise "Cannot create a volume with a specific id (EC2 chooses volume ids)" if new_resource.volume_id
|
10
|
+
if new_resource.snapshot_id =~ /vol/
|
11
|
+
new_resource.snapshot_id(find_snapshot_id(new_resource.snapshot_id))
|
12
|
+
end
|
13
|
+
|
14
|
+
nvid = volume_id_in_node_data
|
15
|
+
if nvid
|
16
|
+
# volume id is registered in the node data, so check that the volume in fact exists in EC2
|
17
|
+
vol = volume_by_id(nvid)
|
18
|
+
exists = vol && vol[:aws_status] != "deleting"
|
19
|
+
# TODO: determine whether this should be an error or just cause a new volume to be created. Currently erring on the side of failing loudly
|
20
|
+
raise "Volume with id #{nvid} is registered with the node but does not exist in EC2. To clear this error, remove the ['aws']['ebs_volume']['#{new_resource.name}']['volume_id'] entry from this node's data." unless exists
|
21
|
+
else
|
22
|
+
# Determine if there is a volume that meets the resource's specifications and is attached to the current
|
23
|
+
# instance in case a previous [:create, :attach] run created and attached a volume but for some reason was
|
24
|
+
# not registered in the node data (e.g. an exception is thrown after the attach_volume request was accepted
|
25
|
+
# by EC2, causing the node data to not be stored on the server)
|
26
|
+
if new_resource.device && (attached_volume = currently_attached_volume(instance_id, new_resource.device))
|
27
|
+
Chef::Log.debug("There is already a volume attached at device #{new_resource.device}")
|
28
|
+
compatible = volume_compatible_with_resource_definition?(attached_volume)
|
29
|
+
raise "Volume #{attached_volume[:aws_id]} attached at #{attached_volume[:aws_device]} but does not conform to this resource's specifications" unless compatible
|
30
|
+
Chef::Log.debug("The volume matches the resource's definition, so the volume is assumed to be already created")
|
31
|
+
converge_by("update the node data with volume id: #{attached_volume[:aws_id]}") do
|
32
|
+
node.set['aws']['ebs_volume'][new_resource.name]['volume_id'] = attached_volume[:aws_id]
|
33
|
+
node.save unless Chef::Config[:solo]
|
34
|
+
end
|
35
|
+
else
|
36
|
+
# If not, create volume and register its id in the node data
|
37
|
+
converge_by("create a volume with id=#{new_resource.snapshot_id} size=#{new_resource.size} availability_zone=#{new_resource.availability_zone} and update the node data with created volume's id") do
|
38
|
+
nvid = create_volume(new_resource.snapshot_id, new_resource.size, new_resource.availability_zone, new_resource.timeout)
|
39
|
+
node.set['aws']['ebs_volume'][new_resource.name]['volume_id'] = nvid
|
40
|
+
node.save unless Chef::Config[:solo]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
action :attach do
|
47
|
+
vol = determine_volume
|
48
|
+
|
49
|
+
if vol[:aws_status] == "in-use"
|
50
|
+
if vol[:aws_instance_id] != instance_id
|
51
|
+
raise "Volume with id #{vol[:aws_id]} exists but is attached to instance #{vol[:aws_instance_id]}"
|
52
|
+
else
|
53
|
+
Chef::Log.debug("Volume is already attached")
|
54
|
+
end
|
55
|
+
else
|
56
|
+
converge_by("attach the volume with aws_id=#{vol[:aws_id]} id=#{instance_id} device=#{new_resource.device} and update the node data with created volume's id") do
|
57
|
+
# attach the volume and register its id in the node data
|
58
|
+
attach_volume(vol[:aws_id], instance_id, new_resource.device, new_resource.timeout)
|
59
|
+
node.set['aws']['ebs_volume'][new_resource.name]['volume_id'] = vol['aws_id']
|
60
|
+
node.save unless Chef::Config[:solo]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
action :detach do
|
66
|
+
vol = determine_volume
|
67
|
+
return if vol[:aws_instance_id] != instance_id
|
68
|
+
converge_by("detach volume with id: #{vol[:aws_id]}") do
|
69
|
+
detach_volume(vol[:aws_id], new_resource.timeout)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
action :snapshot do
|
74
|
+
vol = determine_volume
|
75
|
+
converge_by("would create a snapshot for volume: #{vol[:aws_id]}") do
|
76
|
+
snapshot = ec2.create_snapshot(vol[:aws_id],new_resource.description)
|
77
|
+
Chef::Log.info("Created snapshot of #{vol[:aws_id]} as #{snapshot[:aws_id]}")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
action :prune do
|
82
|
+
vol = determine_volume
|
83
|
+
old_snapshots = Array.new
|
84
|
+
Chef::Log.info "Checking for old snapshots"
|
85
|
+
ec2.describe_snapshots.sort { |a,b| b[:aws_started_at] <=> a[:aws_started_at] }.each do |snapshot|
|
86
|
+
if snapshot[:aws_volume_id] == vol[:aws_id]
|
87
|
+
Chef::Log.info "Found old snapshot #{snapshot[:aws_id]} (#{snapshot[:aws_volume_id]}) #{snapshot[:aws_started_at]}"
|
88
|
+
old_snapshots << snapshot
|
89
|
+
end
|
90
|
+
end
|
91
|
+
if old_snapshots.length > new_resource.snapshots_to_keep
|
92
|
+
old_snapshots[new_resource.snapshots_to_keep, old_snapshots.length].each do |die|
|
93
|
+
converge_by("delete snapshot with id: #{die[:aws_id]}") do
|
94
|
+
Chef::Log.info "Deleting old snapshot #{die[:aws_id]}"
|
95
|
+
ec2.delete_snapshot(die[:aws_id])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def volume_id_in_node_data
|
104
|
+
begin
|
105
|
+
node['aws']['ebs_volume'][new_resource.name]['volume_id']
|
106
|
+
rescue NoMethodError => e
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Pulls the volume id from the volume_id attribute or the node data and verifies that the volume actually exists
|
112
|
+
def determine_volume
|
113
|
+
vol = currently_attached_volume(instance_id, new_resource.device)
|
114
|
+
vol_id = new_resource.volume_id || volume_id_in_node_data || ( vol ? vol[:aws_id] : nil )
|
115
|
+
raise "volume_id attribute not set and no volume id is set in the node data for this resource (which is populated by action :create) and no volume is attached at the device" unless vol_id
|
116
|
+
|
117
|
+
# check that volume exists
|
118
|
+
vol = volume_by_id(vol_id)
|
119
|
+
raise "No volume with id #{vol_id} exists" unless vol
|
120
|
+
|
121
|
+
vol
|
122
|
+
end
|
123
|
+
|
124
|
+
# Retrieves information for a volume
|
125
|
+
def volume_by_id(volume_id)
|
126
|
+
ec2.describe_volumes.find{|v| v[:aws_id] == volume_id}
|
127
|
+
end
|
128
|
+
|
129
|
+
# Returns the volume that's attached to the instance at the given device or nil if none matches
|
130
|
+
def currently_attached_volume(instance_id, device)
|
131
|
+
ec2.describe_volumes.find{|v| v[:aws_instance_id] == instance_id && v[:aws_device] == device}
|
132
|
+
end
|
133
|
+
|
134
|
+
# Returns true if the given volume meets the resource's attributes
|
135
|
+
def volume_compatible_with_resource_definition?(volume)
|
136
|
+
if new_resource.snapshot_id =~ /vol/
|
137
|
+
new_resource.snapshot_id(find_snapshot_id(new_resource.snapshot_id))
|
138
|
+
end
|
139
|
+
(new_resource.size.nil? || new_resource.size == volume[:aws_size]) &&
|
140
|
+
(new_resource.availability_zone.nil? || new_resource.availability_zone == volume[:zone]) &&
|
141
|
+
(new_resource.snapshot_id == volume[:snapshot_id])
|
142
|
+
end
|
143
|
+
|
144
|
+
# Creates a volume according to specifications and blocks until done (or times out)
|
145
|
+
def create_volume(snapshot_id, size, availability_zone, timeout)
|
146
|
+
availability_zone ||= instance_availability_zone
|
147
|
+
nv = ec2.create_volume(snapshot_id, size, availability_zone)
|
148
|
+
Chef::Log.debug("Created new volume #{nv[:aws_id]}#{snapshot_id ? " based on #{snapshot_id}" : ""}")
|
149
|
+
|
150
|
+
# block until created
|
151
|
+
begin
|
152
|
+
Timeout::timeout(timeout) do
|
153
|
+
while true
|
154
|
+
vol = volume_by_id(nv[:aws_id])
|
155
|
+
if vol && vol[:aws_status] != "deleting"
|
156
|
+
if ["in-use", "available"].include?(vol[:aws_status])
|
157
|
+
Chef::Log.info("Volume #{nv[:aws_id]} is available")
|
158
|
+
break
|
159
|
+
else
|
160
|
+
Chef::Log.debug("Volume is #{vol[:aws_status]}")
|
161
|
+
end
|
162
|
+
sleep 3
|
163
|
+
else
|
164
|
+
raise "Volume #{nv[:aws_id]} no longer exists"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
rescue Timeout::Error
|
169
|
+
raise "Timed out waiting for volume creation after #{timeout} seconds"
|
170
|
+
end
|
171
|
+
|
172
|
+
nv[:aws_id]
|
173
|
+
end
|
174
|
+
|
175
|
+
# Attaches the volume and blocks until done (or times out)
|
176
|
+
def attach_volume(volume_id, instance_id, device, timeout)
|
177
|
+
Chef::Log.debug("Attaching #{volume_id} as #{device}")
|
178
|
+
ec2.attach_volume(volume_id, instance_id, device)
|
179
|
+
|
180
|
+
# block until attached
|
181
|
+
begin
|
182
|
+
Timeout::timeout(timeout) do
|
183
|
+
while true
|
184
|
+
vol = volume_by_id(volume_id)
|
185
|
+
if vol && vol[:aws_status] != "deleting"
|
186
|
+
if vol[:aws_attachment_status] == "attached"
|
187
|
+
if vol[:aws_instance_id] == instance_id
|
188
|
+
Chef::Log.info("Volume #{volume_id} is attached to #{instance_id}")
|
189
|
+
break
|
190
|
+
else
|
191
|
+
raise "Volume is attached to instance #{vol[:aws_instance_id]} instead of #{instance_id}"
|
192
|
+
end
|
193
|
+
else
|
194
|
+
Chef::Log.debug("Volume is #{vol[:aws_status]}")
|
195
|
+
end
|
196
|
+
sleep 3
|
197
|
+
else
|
198
|
+
raise "Volume #{volume_id} no longer exists"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
rescue Timeout::Error
|
203
|
+
raise "Timed out waiting for volume attachment after #{timeout} seconds"
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# Detaches the volume and blocks until done (or times out)
|
208
|
+
def detach_volume(volume_id, timeout)
|
209
|
+
Chef::Log.debug("Detaching #{volume_id}")
|
210
|
+
vol = volume_by_id(volume_id)
|
211
|
+
orig_instance_id = vol[:aws_instance_id]
|
212
|
+
ec2.detach_volume(volume_id)
|
213
|
+
|
214
|
+
# block until detached
|
215
|
+
begin
|
216
|
+
Timeout::timeout(timeout) do
|
217
|
+
while true
|
218
|
+
vol = volume_by_id(volume_id)
|
219
|
+
if vol && vol[:aws_status] != "deleting"
|
220
|
+
if vol[:aws_instance_id] != orig_instance_id
|
221
|
+
Chef::Log.info("Volume detached from #{orig_instance_id}")
|
222
|
+
break
|
223
|
+
else
|
224
|
+
Chef::Log.debug("Volume: #{vol.inspect}")
|
225
|
+
end
|
226
|
+
else
|
227
|
+
Chef::Log.debug("Volume #{volume_id} no longer exists")
|
228
|
+
break
|
229
|
+
end
|
230
|
+
sleep 3
|
231
|
+
end
|
232
|
+
end
|
233
|
+
rescue Timeout::Error
|
234
|
+
raise "Timed out waiting for volume detachment after #{timeout} seconds"
|
235
|
+
end
|
236
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
include Opscode::Aws::Ec2
|
2
|
+
|
3
|
+
# Support whyrun
|
4
|
+
def whyrun_supported?
|
5
|
+
true
|
6
|
+
end
|
7
|
+
|
8
|
+
action :associate do
|
9
|
+
addr = address(new_resource.ip)
|
10
|
+
|
11
|
+
if addr.nil?
|
12
|
+
raise "Elastic IP #{new_resource.ip} does not exist"
|
13
|
+
elsif addr[:instance_id] == instance_id
|
14
|
+
Chef::Log.debug("Elastic IP #{new_resource.ip} is already attached to the instance")
|
15
|
+
else
|
16
|
+
converge_by("attach Elastic IP #{new_resource.ip} to the instance") do
|
17
|
+
Chef::Log.info("Attaching Elastic IP #{new_resource.ip} to the instance")
|
18
|
+
attach(new_resource.ip, new_resource.timeout)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
action :disassociate do
|
24
|
+
addr = address(new_resource.ip)
|
25
|
+
|
26
|
+
if addr.nil?
|
27
|
+
Chef::Log.debug("Elastic IP #{new_resource.ip} does not exist, so there is nothing to detach")
|
28
|
+
elsif addr[:instance_id] != instance_id
|
29
|
+
Chef::Log.debug("Elastic IP #{new_resource.ip} is already detached from the instance")
|
30
|
+
else
|
31
|
+
converge_by("detach Elastic IP #{new_resource.ip} from the instance") do
|
32
|
+
Chef::Log.info("Detaching Elastic IP #{new_resource.ip} from the instance")
|
33
|
+
detach(new_resource.ip, new_resource.timeout)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def address(ip)
|
41
|
+
ec2.describe_addresses.find{|a| a[:public_ip] == ip}
|
42
|
+
end
|
43
|
+
|
44
|
+
def attach(ip, timeout)
|
45
|
+
ec2.associate_address(instance_id, ip)
|
46
|
+
|
47
|
+
# block until attached
|
48
|
+
begin
|
49
|
+
Timeout::timeout(timeout) do
|
50
|
+
while true
|
51
|
+
addr = address(ip)
|
52
|
+
if addr.nil?
|
53
|
+
raise "Elastic IP has been deleted while waiting for attachment"
|
54
|
+
elsif addr[:instance_id] == instance_id
|
55
|
+
Chef::Log.debug("Elastic IP is attached to this instance")
|
56
|
+
break
|
57
|
+
else
|
58
|
+
Chef::Log.debug("Elastic IP is currently attached to #{addr[:instance_id]}")
|
59
|
+
end
|
60
|
+
sleep 3
|
61
|
+
end
|
62
|
+
end
|
63
|
+
rescue Timeout::Error
|
64
|
+
raise "Timed out waiting for attachment after #{timeout} seconds"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def detach(ip, timeout)
|
69
|
+
ec2.disassociate_address(ip)
|
70
|
+
|
71
|
+
# block until detached
|
72
|
+
begin
|
73
|
+
Timeout::timeout(timeout) do
|
74
|
+
while true
|
75
|
+
addr = address(ip)
|
76
|
+
if addr.nil?
|
77
|
+
Chef::Log.debug("Elastic IP has been deleted while waiting for detachment")
|
78
|
+
elsif addr[:instance_id] != instance_id
|
79
|
+
Chef::Log.debug("Elastic IP is detached from this instance")
|
80
|
+
break
|
81
|
+
else
|
82
|
+
Chef::Log.debug("Elastic IP is still attached")
|
83
|
+
end
|
84
|
+
sleep 3
|
85
|
+
end
|
86
|
+
end
|
87
|
+
rescue Timeout::Error
|
88
|
+
raise "Timed out waiting for detachment after #{timeout} seconds"
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
include Opscode::Aws::Ec2
|
2
|
+
|
3
|
+
action :register do
|
4
|
+
converge_by("add the node #{new_resource.name} to ELB") do
|
5
|
+
Chef::Log.info("Adding node to ELB #{new_resource.name}")
|
6
|
+
elb.register_instances_with_load_balancer(new_resource.name, instance_id)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
action :deregister do
|
11
|
+
converge_by("remove the node #{new_resource.name} from ELB") do
|
12
|
+
Chef::Log.info("Removing node from ELB #{new_resource.name}")
|
13
|
+
elb.deregister_instances_with_load_balancer(new_resource.name, instance_id)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def elb
|
20
|
+
region = instance_availability_zone
|
21
|
+
region = region[0, region.length-1]
|
22
|
+
@@elb ||= RightAws::ElbInterface.new(new_resource.aws_access_key, new_resource.aws_secret_access_key, { :logger => Chef::Log, :region => region })
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,93 @@
|
|
1
|
+
include Opscode::Aws::Ec2
|
2
|
+
|
3
|
+
action :add do
|
4
|
+
|
5
|
+
unless @new_resource.resource_id
|
6
|
+
resource_id = @new_resource.name
|
7
|
+
else
|
8
|
+
resource_id = @new_resource.resource_id
|
9
|
+
end
|
10
|
+
|
11
|
+
@new_resource.tags.each do |k,v|
|
12
|
+
unless @current_resource.tags.keys.include?(k)
|
13
|
+
converge_by("add tag '#{k}' with value '#{v}' on resource #{resource_id}") do
|
14
|
+
ec2.create_tags(resource_id, { k => v })
|
15
|
+
Chef::Log.info("AWS: Added tag '#{k}' with value '#{v}' on resource #{resource_id}")
|
16
|
+
end
|
17
|
+
else
|
18
|
+
Chef::Log.debug("AWS: Resource #{resource_id} already has a tag with key '#{k}', will not add tag '#{k}' => '#{v}'")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
action :update do
|
24
|
+
unless @new_resource.resource_id
|
25
|
+
resource_id = @new_resource.name
|
26
|
+
else
|
27
|
+
resource_id = @new_resource.resource_id
|
28
|
+
end
|
29
|
+
|
30
|
+
updated_tags = @current_resource.tags.merge(@new_resource.tags)
|
31
|
+
unless updated_tags.eql?(@current_resource.tags)
|
32
|
+
converge_by("Updating the following tags for resource #{resource_id}: " + updated_tags.inspect) do
|
33
|
+
Chef::Log.info("AWS: Updating the following tags for resource #{resource_id}: " + updated_tags.inspect)
|
34
|
+
ec2.create_tags(resource_id, updated_tags)
|
35
|
+
end
|
36
|
+
else
|
37
|
+
Chef::Log.debug("AWS: Tags for resource #{resource_id} are unchanged")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
action :remove do
|
42
|
+
unless @new_resource.resource_id
|
43
|
+
resource_id = @new_resource.name
|
44
|
+
else
|
45
|
+
resource_id = @new_resource.resource_id
|
46
|
+
end
|
47
|
+
|
48
|
+
tags_to_delete = @new_resource.tags.keys
|
49
|
+
|
50
|
+
tags_to_delete.each do |key|
|
51
|
+
if @current_resource.tags.keys.include?(key) and @current_resource.tags[key] == @new_resource.tags[key]
|
52
|
+
converge_by("delete tag '#{key}' on resource #{resource_id} with value '#{@current_resource.tags[key]}'") do
|
53
|
+
ec2.delete_tags(resource_id, {key => @new_resource.tags[key]})
|
54
|
+
Chef::Log.info("AWS: Deleted tag '#{key}' on resource #{resource_id} with value '#{@current_resource.tags[key]}'")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
action :force_remove do
|
61
|
+
unless @new_resource.resource_id
|
62
|
+
resource_id = @new_resource.name
|
63
|
+
else
|
64
|
+
resource_id = @new_resource.resource_id
|
65
|
+
end
|
66
|
+
|
67
|
+
@new_resource.tags.keys do |key|
|
68
|
+
if @current_resource.tags.keys.include?(key)
|
69
|
+
converge_by("AWS: Deleted tag '#{key}' on resource #{resource_id} with value '#{@current_resource.tags[key]}'") do
|
70
|
+
ec2.delete_tags(resource_id, key)
|
71
|
+
Chef::Log.info("AWS: Deleted tag '#{key}' on resource #{resource_id} with value '#{@current_resource.tags[key]}'")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def load_current_resource
|
78
|
+
@current_resource = Chef::Resource::AwsResourceTag.new(@new_resource.name)
|
79
|
+
@current_resource.name(@new_resource.name)
|
80
|
+
unless @new_resource.resource_id
|
81
|
+
@current_resource.resource_id(@new_resource.name)
|
82
|
+
else
|
83
|
+
@current_resource.resource_id(@new_resource.resource_id)
|
84
|
+
end
|
85
|
+
|
86
|
+
@current_resource.tags(Hash.new)
|
87
|
+
|
88
|
+
ec2.describe_tags(:filters => { 'resource-id' => @current_resource.resource_id }).map {
|
89
|
+
|tag| @current_resource.tags[tag[:key]] = tag[:value]
|
90
|
+
}
|
91
|
+
|
92
|
+
@current_resource
|
93
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#
|
2
|
+
# Cookbook Name:: aws
|
3
|
+
# Recipe:: default
|
4
|
+
#
|
5
|
+
# Copyright 2008-2009, Opscode, Inc.
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
chef_gem "right_aws" do
|
21
|
+
version node['aws']['right_aws_version']
|
22
|
+
action :install
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'right_aws'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
actions :create, :attach, :detach, :snapshot, :prune
|
2
|
+
|
3
|
+
attribute :aws_access_key, :kind_of => String
|
4
|
+
attribute :aws_secret_access_key, :kind_of => String
|
5
|
+
attribute :size, :kind_of => Integer
|
6
|
+
attribute :snapshot_id, :kind_of => String
|
7
|
+
attribute :availability_zone, :kind_of => String
|
8
|
+
attribute :device, :kind_of => String
|
9
|
+
attribute :volume_id, :kind_of => String
|
10
|
+
attribute :description, :kind_of => String
|
11
|
+
attribute :timeout, :default => 3*60 # 3 mins, nil or 0 for no timeout
|
12
|
+
attribute :snapshots_to_keep, :default => 2
|
13
|
+
|
14
|
+
def initialize(*args)
|
15
|
+
super
|
16
|
+
@action = :create
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
actions :associate, :disassociate
|
2
|
+
|
3
|
+
attribute :aws_access_key, :kind_of => String
|
4
|
+
attribute :aws_secret_access_key, :kind_of => String
|
5
|
+
attribute :ip, :kind_of => String
|
6
|
+
attribute :timeout, :default => 3*60 # 3 mins, nil or 0 for no timeout
|
7
|
+
|
8
|
+
def initialize(*args)
|
9
|
+
super
|
10
|
+
@action = :associate
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
def initialize(*args)
|
2
|
+
super
|
3
|
+
@action = :update
|
4
|
+
end
|
5
|
+
|
6
|
+
actions :add, :update, :remove, :force_remove
|
7
|
+
|
8
|
+
attribute :aws_access_key, :kind_of => String, :required => true
|
9
|
+
attribute :aws_secret_access_key, :kind_of => String, :required => true
|
10
|
+
attribute :resource_id, :kind_of => [ String, Array ], :regex => /(i|snap|vol)-[a-zA-Z0-9]+/
|
11
|
+
attribute :tags, :kind_of => Hash, :required => true
|
@@ -0,0 +1 @@
|
|
1
|
+
*.sw[op]
|
@@ -0,0 +1,51 @@
|
|
1
|
+
## v1.3.6:
|
2
|
+
|
3
|
+
* [COOK-1688] - fix typo in readme and add amazon linux to supported
|
4
|
+
platforms
|
5
|
+
|
6
|
+
## v1.3.4:
|
7
|
+
|
8
|
+
* [COOK-1561] - depend on mysql 1.3.0+ explicitly
|
9
|
+
* depend on postgresql 1.0.0 explicitly
|
10
|
+
|
11
|
+
## v1.3.2:
|
12
|
+
|
13
|
+
* Update the version for release (oops)
|
14
|
+
|
15
|
+
## v1.3.0:
|
16
|
+
|
17
|
+
* [COOK-932] - Add mysql recipe to conveniently include mysql::ruby
|
18
|
+
* [COOK-1228] - database resource should be able to execute scripts on disk
|
19
|
+
* [COOK-1291] - make the snapshot retention policy less confusing
|
20
|
+
* [COOK-1401] - Allow to specify the collation of new databases
|
21
|
+
* [COOK-1534] - Add postgresql recipe to conveniently include postgresql::ruby
|
22
|
+
|
23
|
+
## v1.2.0:
|
24
|
+
|
25
|
+
* [COOK-970] - workaround for disk [re]naming on ubuntu 11.04+
|
26
|
+
* [COOK-1085] - check RUBY_VERSION and act accordingly for role
|
27
|
+
* [COOK-749] - localhost should be a string in snapshot recipe
|
28
|
+
|
29
|
+
## v1.1.4:
|
30
|
+
|
31
|
+
* [COOK-1062] - Databases: Postgres exists should close connection
|
32
|
+
|
33
|
+
## v1.1.2:
|
34
|
+
|
35
|
+
* [COOK-975] - Change arg='DEFAULT' to arg=nil, :default => 'DEFAULT'
|
36
|
+
* [COOK-964] - Add parentheses around connection hash in example
|
37
|
+
|
38
|
+
## v1.1.0
|
39
|
+
|
40
|
+
* [COOK-716] - providers for PostgreSQL
|
41
|
+
|
42
|
+
## v1.0.0
|
43
|
+
|
44
|
+
* [COOK-683] - added `database` and `database_user` resources
|
45
|
+
* [COOK-684] - MySQL providers
|
46
|
+
* [COOK-685] - SQL Server providers
|
47
|
+
* refactored - `database::master` and `database::snapshot` recipes to leverage new resources
|
48
|
+
|
49
|
+
## v0.99.1
|
50
|
+
|
51
|
+
* Use Chef 0.10's `node.chef_environment` instead of `node['app_environment']`.
|
@@ -0,0 +1,29 @@
|
|
1
|
+
If you would like to contribute, please open a ticket in JIRA:
|
2
|
+
|
3
|
+
* http://tickets.opscode.com
|
4
|
+
|
5
|
+
Create the ticket in the COOK project and use the cookbook name as the
|
6
|
+
component.
|
7
|
+
|
8
|
+
For all code contributions, we ask that contributors sign a
|
9
|
+
contributor license agreement (CLA). Instructions may be found here:
|
10
|
+
|
11
|
+
* http://wiki.opscode.com/display/chef/How+to+Contribute
|
12
|
+
|
13
|
+
When contributing changes to individual cookbooks, please do not
|
14
|
+
modify the version number in the metadata.rb. Also please do not
|
15
|
+
update the CHANGELOG.md for a new version. Not all changes to a
|
16
|
+
cookbook may be merged and released in the same versions. Opscode will
|
17
|
+
handle the version updates during the release process. You are welcome
|
18
|
+
to correct typos or otherwise make updates to documentation in the
|
19
|
+
README.
|
20
|
+
|
21
|
+
If a contribution adds new platforms or platform versions, indicate
|
22
|
+
such in the body of the commit message(s), and update the relevant
|
23
|
+
COOK ticket. When writing commit messages, it is helpful for others if
|
24
|
+
you indicate the COOK ticket. For example:
|
25
|
+
|
26
|
+
git commit -m '[COOK-1041] Updated pool resource to correctly delete.'
|
27
|
+
|
28
|
+
In the ticket itself, it is also helpful if you include log output of
|
29
|
+
a successful Chef run, but this is not absolutely required.
|