server_maint 0.0.3 → 0.0.4
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/.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.
|