chef-provisioning-aws 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +70 -69
  3. data/Rakefile +22 -2
  4. data/lib/chef/provider/aws_auto_scaling_group.rb +3 -2
  5. data/lib/chef/provider/aws_cache_cluster.rb +3 -2
  6. data/lib/chef/provider/aws_cache_replication_group.rb +5 -4
  7. data/lib/chef/provider/aws_cache_subnet_group.rb +5 -4
  8. data/lib/chef/provider/aws_cloudsearch_domain.rb +163 -0
  9. data/lib/chef/provider/aws_dhcp_options.rb +9 -6
  10. data/lib/chef/provider/aws_ebs_volume.rb +7 -3
  11. data/lib/chef/provider/aws_eip_address.rb +8 -7
  12. data/lib/chef/provider/aws_image.rb +8 -3
  13. data/lib/chef/provider/aws_instance.rb +14 -2
  14. data/lib/chef/provider/aws_key_pair.rb +2 -1
  15. data/lib/chef/provider/aws_launch_configuration.rb +4 -2
  16. data/lib/chef/provider/aws_load_balancer.rb +18 -0
  17. data/lib/chef/provider/aws_network_acl.rb +6 -2
  18. data/lib/chef/provider/aws_network_interface.rb +11 -24
  19. data/lib/chef/provider/aws_rds_instance.rb +66 -0
  20. data/lib/chef/provider/aws_rds_subnet_group.rb +89 -0
  21. data/lib/chef/provider/aws_route_table.rb +42 -23
  22. data/lib/chef/provider/aws_s3_bucket.rb +32 -8
  23. data/lib/chef/provider/aws_security_group.rb +11 -4
  24. data/lib/chef/provider/aws_server_certificate.rb +23 -0
  25. data/lib/chef/provider/aws_sns_topic.rb +4 -3
  26. data/lib/chef/provider/aws_sqs_queue.rb +3 -2
  27. data/lib/chef/provider/aws_subnet.rb +10 -7
  28. data/lib/chef/provider/aws_vpc.rb +54 -21
  29. data/lib/chef/provider/aws_vpc_peering_connection.rb +88 -0
  30. data/lib/chef/provisioning/aws_driver.rb +8 -0
  31. data/lib/chef/provisioning/aws_driver/aws_provider.rb +45 -76
  32. data/lib/chef/provisioning/aws_driver/aws_rds_resource.rb +11 -0
  33. data/lib/chef/provisioning/aws_driver/aws_resource.rb +14 -2
  34. data/lib/chef/provisioning/aws_driver/aws_resource_with_entry.rb +2 -8
  35. data/lib/chef/provisioning/aws_driver/aws_taggable.rb +18 -0
  36. data/lib/chef/provisioning/aws_driver/aws_tagger.rb +61 -0
  37. data/lib/chef/provisioning/aws_driver/credentials2.rb +51 -0
  38. data/lib/chef/provisioning/aws_driver/driver.rb +214 -162
  39. data/lib/chef/provisioning/aws_driver/tagging_strategy/ec2.rb +64 -0
  40. data/lib/chef/provisioning/aws_driver/tagging_strategy/elb.rb +39 -0
  41. data/lib/chef/provisioning/aws_driver/tagging_strategy/rds.rb +92 -0
  42. data/lib/chef/provisioning/aws_driver/tagging_strategy/s3.rb +41 -0
  43. data/lib/chef/provisioning/aws_driver/version.rb +1 -1
  44. data/lib/chef/resource/aws_cache_cluster.rb +1 -2
  45. data/lib/chef/resource/aws_cloudsearch_domain.rb +46 -0
  46. data/lib/chef/resource/aws_dhcp_options.rb +2 -0
  47. data/lib/chef/resource/aws_ebs_volume.rb +3 -1
  48. data/lib/chef/resource/aws_eip_address.rb +0 -3
  49. data/lib/chef/resource/aws_image.rb +3 -0
  50. data/lib/chef/resource/aws_instance.rb +7 -2
  51. data/lib/chef/resource/aws_internet_gateway.rb +2 -0
  52. data/lib/chef/resource/aws_load_balancer.rb +3 -0
  53. data/lib/chef/resource/aws_network_acl.rb +2 -0
  54. data/lib/chef/resource/aws_network_interface.rb +3 -1
  55. data/lib/chef/resource/aws_rds_instance.rb +42 -0
  56. data/lib/chef/resource/aws_rds_subnet_group.rb +29 -0
  57. data/lib/chef/resource/aws_route_table.rb +7 -5
  58. data/lib/chef/resource/aws_s3_bucket.rb +3 -0
  59. data/lib/chef/resource/aws_security_group.rb +2 -7
  60. data/lib/chef/resource/aws_server_certificate.rb +21 -0
  61. data/lib/chef/resource/aws_subnet.rb +2 -0
  62. data/lib/chef/resource/aws_vpc.rb +4 -1
  63. data/lib/chef/resource/aws_vpc_peering_connection.rb +73 -0
  64. data/spec/acceptance/aws_ebs_volume/nodes/ettores-mbp.lan.json +3 -0
  65. data/spec/aws_support.rb +25 -8
  66. data/spec/aws_support/aws_resource_run_wrapper.rb +5 -1
  67. data/spec/aws_support/deep_matcher/match_values_failure_messages.rb +19 -0
  68. data/spec/aws_support/matchers/create_an_aws_object.rb +1 -1
  69. data/spec/aws_support/matchers/destroy_an_aws_object.rb +1 -1
  70. data/spec/aws_support/matchers/have_aws_object_tags.rb +9 -15
  71. data/spec/aws_support/matchers/match_an_aws_object.rb +1 -1
  72. data/spec/aws_support/matchers/update_an_aws_object.rb +1 -1
  73. data/spec/integration/aws_cloudsearch_domain_spec.rb +31 -0
  74. data/spec/integration/aws_dhcp_options_spec.rb +73 -0
  75. data/spec/integration/aws_ebs_volume_spec.rb +97 -0
  76. data/spec/integration/aws_network_acl_spec.rb +51 -0
  77. data/spec/integration/aws_network_interface_spec.rb +89 -0
  78. data/spec/integration/aws_rds_instance_spec.rb +150 -0
  79. data/spec/integration/aws_rds_subnet_group_spec.rb +105 -0
  80. data/spec/integration/aws_route_table_spec.rb +94 -7
  81. data/spec/integration/aws_s3_bucket_spec.rb +88 -0
  82. data/spec/integration/aws_security_group_spec.rb +47 -0
  83. data/spec/integration/aws_server_certificate_spec.rb +24 -0
  84. data/spec/integration/aws_subnet_spec.rb +51 -2
  85. data/spec/integration/aws_vpc_peering_connection_spec.rb +99 -0
  86. data/spec/integration/aws_vpc_spec.rb +73 -0
  87. data/spec/integration/load_balancer_spec.rb +101 -0
  88. data/spec/integration/machine_image_spec.rb +61 -6
  89. data/spec/integration/machine_spec.rb +26 -0
  90. data/spec/spec_helper.rb +3 -0
  91. data/spec/unit/{aws_driver → chef/provisioning/aws_driver}/credentials_spec.rb +0 -0
  92. data/spec/unit/chef/provisioning/aws_driver/driver_spec.rb +88 -0
  93. metadata +63 -20
  94. data/spec/integration/aws_tagged_items_spec.rb +0 -166
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 152994be990de9eda227b6a5be1179acea932c78
4
- data.tar.gz: 1c58f8b2be7da9e3a779dae16ba2ff445de4370d
3
+ metadata.gz: 19f4ffce05e2b12c1256593ed8132affc94376f8
4
+ data.tar.gz: e606311b2689000c0e5098087d5debaff8c2997d
5
5
  SHA512:
6
- metadata.gz: aba82b6a79304d5786b8b686aad781c18add3fac6b1d52c52b300dffd38ec93b2262cda6be721de582f5382cea04a08435f3a3001bd4857415743713a0ca4e66
7
- data.tar.gz: 2e70c7a272b3902b7b8a96a70f4a70a99f9a6ee3d38e1ef3c329efef09f055129d2a97202d00dcc08f6ec0e3d32e171f908dea6eef093de97c853cb37ac9e9f3
6
+ metadata.gz: a37d0a594d564b0a6da4f84b8a4d9d6222654e7bc2ddedb68d22d830cdfea1321cfb4b3d024264e14c81a7462b1f47b3c311ebff79972deb8bba2b4558847f57
7
+ data.tar.gz: 8dd82f47ac3c83b52b124d75a316c1c54a348d755c2e892213cd245fdf5f5cfeabebfb67bc81eed26c9362d62ba6c4dbfa3f07a7ecf40dfcc7d00668d00aa800
data/README.md CHANGED
@@ -10,6 +10,16 @@ AWS credentials should be specified in your `~/.aws/credentials` file as documen
10
10
 
11
11
  You can specify a profile as the middle section of the semi-colon seperated driver url. For example, a driver url of `aws:staging:us-east-1` would use the profile `staging`.
12
12
 
13
+ ## Configurable Options
14
+
15
+ When using `machine_batch` with a large number of machines it is possible to overwhelm the AWS SDK until it starts returning `AWS::EC2::Errors::RequestLimitExceeded`. You can configure the AWS SDK to retry these errors automatically by specifying
16
+
17
+ ```ruby
18
+ chef_provisioning({:aws_retry_limit => 10})
19
+ ```
20
+
21
+ in your client.rb for the provisioning workstation. The default `:aws_retry_limit` is 5.
22
+
13
23
  # Resources
14
24
 
15
25
  TODO: List out weird/unique things about resources here. We don't need to document every resource
@@ -26,7 +36,7 @@ You can specify an existing key pair to upload by specifying the following:
26
36
  aws_key_pair 'my-aws-key' do
27
37
  private_key_path "~boiardi/.ssh/my-aws-key.pem"
28
38
  public_key_path "~boiardi/.ssh/my-aws-key.pub"
29
- overwrite false # Set to true if you want to regenerate this each chef run
39
+ allow_overwrite false # Set to true if you want to regenerate this each chef run
30
40
  end
31
41
  ```
32
42
 
@@ -108,6 +118,7 @@ configure the machine. These are all the available options:
108
118
 
109
119
  ```ruby
110
120
  with_machine_options({
121
+ # See https://github.com/chef/chef-provisioning#machine-options for options shared between drivers
111
122
  bootstrap_options: {
112
123
  # http://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Resource.html#create_instances-instance_method
113
124
  # lists the available options. The below options are the default
@@ -117,45 +128,8 @@ with_machine_options({
117
128
  key_path: "~/.chef/keys/chef_default", # only necessary if storing keys some other location
118
129
  user_data: "...", # Only defaulted on Windows instances to start winrm
119
130
  },
120
- convergence_options: {
121
- chef_version: "12.4.1",
122
- prerelease: "false",
123
- chef_client_timeout: 120*60, # Default: 2 hours
124
- chef_config: "log_level :debug\\n", # String containing additional text to inject into client.rb
125
- chef_server: "http://my.chef.server/", # TODO could conflict with https://github.com/chef/chef-provisioning#pointing-boxes-at-chef-servers
126
- bootstrap_proxy: "http://localhost:1234",
127
- ssl_verify_mode: :verify_peer,
128
- client_rb_path: "/etc/chef/client.rb", # <- DEFAULT, overwrite if necessary
129
- client_pem_path: "/etc/chef/client.pem", # <- DEFAULT, overwrite if necessary
130
- allow_overwrite_keys: false, # If there is an existing client.pem this needs to be true to overwrite it
131
- private_key_options: {}, # TODO ????? Something to do with creating node object
132
- source_key: "", # ?????
133
- source_key_pass_phrase: "", # ?????
134
- source_key_path: "", # ?????
135
- public_key_path: "", # ?????
136
- public_key_format: "", # ?????
137
- admin: "", # ?????
138
- validator: "", # ?????
139
- ohai_hints: { :ec2 => { :key => :value } }, # Map from hint file name to file contents, this would create /etc/chef/ohai/hints/ec2.json
140
- # The following are only available for Linux machines
141
- install_sh_url: "https://www.chef.io/chef/install.sh", # <- DEFAULT, overwrite if necessary
142
- install_sh_path: "/tmp/chef-install.sh", # <- DEFAULT, overwrite if necessary
143
- install_sh_arguments: "-P chef-dk", # Additional commands to pass to install.sh
144
- # The following are only available for Windows machines
145
- install_msi_url: "foo://bar.com"
146
- },
147
- ssh_options: {
148
- ...
149
- },
150
- cached_installer: false, # ???
151
- aws_tags: { :key1 => "value", "key2" => "value"},
152
- source_dest_check: false, # Specifies whether to enable an instance launched in a VPC to perform NAT
153
- is_windows: false, # set to true if using a Windows AMI
154
- ssh_username: "ubuntu",
155
- ssh_gateway: "localhost"
156
- sudo: true,
157
- use_private_ip_for_ssh: false, # If set to true, we will access the instance with its private_ip (usually requires VPN access)
158
- ...
131
+ use_private_ip_for_ssh: false, # DEPRECATED, use `transport_address_location`
132
+ transport_address_location: :public_ip, # `:public_ip` (default), `:private_ip` or `:dns`. Defines how SSH or WinRM should find an address to communicate with the instance.
159
133
  })
160
134
  ```
161
135
 
@@ -192,24 +166,59 @@ load_balancer "my_elb" do
192
166
  })
193
167
  ```
194
168
 
195
- The available parameters for `load_balancer_options` can be viewed at http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/ELB/Client.html#create_load_balancer-instance_method .
169
+ The available parameters for `load_balancer_options` can be viewed in the [aws docs](http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/ELB/Client.html#create_load_balancer-instance_method).
196
170
 
197
171
  NOTES:
198
172
 
199
173
  1. You can specify either `ssl_certificate_id` or `server_certificate` in a listener but the value to both parameters should be the ARN of an existing IAM::ServerCertificate object.
200
174
  2. Instead of specifying `tags` in the `load_balancer_options`, you should specify `aws_tags`. See the note on [tagging base resources](https://github.com/chef/chef-provisioning-aws#base-resources).
201
175
 
176
+ # RDS Instance Options
177
+
178
+ ### Additional Options
179
+
180
+ RDS instances have many options. Some of them live as first class attributes. Any valid RDS option that is not a first class attribute can still be set via a hash in `additional_options`.
181
+ *If you set an attribute and also specify it in `additional_options`, the resource will chose the attribute and not what is specified in `additional_options`.*
182
+
183
+ To illustrate, note that the following example defines `multi_az` as both an attribute and in the `additional_options` hash:
184
+
185
+ ```
186
+ aws_rds_instance "test-rds-instance2" do
187
+ engine "postgres"
188
+ publicly_accessible false
189
+ db_instance_class "db.t1.micro"
190
+ master_username "thechief"
191
+ master_user_password "securesecure"
192
+ multi_az false
193
+ additional_options(multi_az: true)
194
+ end
195
+ ```
196
+
197
+ The above would result in a new `aws_rds_instance` with `multi_az` being `false`.
198
+
199
+ Additional values for `additional_options` can view viewed in the [aws docs](http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/RDS/Client.html#create_db_instance-instance_method).
200
+
201
+ ### Specifying a DB Subnet Group for your RDS Instance
202
+
203
+ See [this example](docs/examples/aws_rds_subnet_group.rb) for how to set up a DB Subnet Group and pass it to your RDS Instance.
204
+
202
205
  # Specifying a Chef Server
203
206
 
204
207
  See [Pointing Boxes at Chef Servers](https://github.com/chef/chef-provisioning/blob/master/README.md#pointing-boxes-at-chef-servers)
205
208
 
206
209
  # Tagging Resources
207
210
 
208
- ## Aws Resources
211
+ ## For Recipe authors
212
+
213
+ All resources (incuding base resources like `machine`) that are taggable support an `aws_tags` attribute which accepts a single layer hash. To set just the key of an AWS tag specify the value as nil. EG, `aws_tags {my_tag_key: nil}`. Some AWS objects cannot accept nil values and will automatically convert it to an empty string.
214
+
215
+ Some AWS objects (may EC2) view the `Name` tag as unique - it shows up in a `Name` column in the AWS console. By default we specify the `Name` tag as the resource name. This can be overridden by specifying `aws_tags {Name: 'some other name'}`.
216
+
217
+ You can remove all the tags _except_ the `Name` tag by specifying `aws_tags {}`.
209
218
 
210
- All resources which extend Chef::Provisioning::AWSDriver::AWSResourceWithEntry support the ability
211
- to add tags, except AwsEipAddress. AWS does not support tagging on AwsEipAddress. To add a tag
212
- to any aws resource, us the `aws_tags` attribute and provide it a hash:
219
+ Tag keys and values can be specified as symbols or strings but will be converted to strings before sending to AWS.
220
+
221
+ Examples:
213
222
 
214
223
  ```ruby
215
224
  aws_ebs_volume 'ref-volume' do
@@ -221,39 +230,31 @@ aws_vpc 'ref-vpc' do
221
230
  end
222
231
  ```
223
232
 
224
- The hash of tags can use symbols or strings for both keys and values. The tags will be converged
225
- idempotently, meaning no write will occur if no tags are changing.
226
-
227
- We will not touch the `'Name'` tag UNLESS you specifically pass it. If you do not pass it, we
228
- leave it alone.
233
+ ## For Resource Authors
229
234
 
230
- ## Base Resources
235
+ To enable tagging support you must make specific changes to the Resource and Attribute. For the Resource it needs to include the `attribute aws_tags`. This should be done by `include Chef::Provisioning::AWSDriver::AWSTaggable` on the Resource.
231
236
 
232
- Because base resources from chef-provisioning do not have the `aws_tag` attribute, they must be
233
- tagged in their options:
237
+ The `AWSProvider` class will automatically try to call `converge_tags` when running the `action_create` method. You should instantiate an instance of the `AWSTagger` and provide it a strategy depending on the client used to perform the tagging. For example, an RDS Provider should define
234
238
 
235
239
  ```ruby
236
- machine 'ref-machine-1' do
237
- machine_options :aws_tags => {:marco => 'polo', :happyhappy => 'joyjoy'}
238
- end
239
-
240
- machine_batch "ref-batch" do
241
- machine 'ref-machine-2' do
242
- machine_options :aws_tags => {:marco => 'polo', :happyhappy => 'joyjoy'}
243
- converge false
244
- end
245
- machine 'ref-machine-3' do
246
- machine_options :aws_tags => {:othercustomtags => 'byebye'}
247
- converge false
240
+ def aws_tagger
241
+ @aws_tagger ||= begin
242
+ rds_strategy = Chef::Provisioning::AWSDriver::TaggingStrategy::RDS.new(
243
+ new_resource.driver.rds.client,
244
+ construct_arn(new_resource),
245
+ new_resource.aws_tags
246
+ )
247
+ Chef::Provisioning::AWSDriver::AWSTagger.new(rds_strategy, action_handler)
248
248
  end
249
249
  end
250
-
251
- load_balancer 'ref-elb' do
252
- load_balancer_options :aws_tags => {:marco => 'polo', :happyhappy => 'joyjoy'}
250
+ def converge_tags
251
+ aws_tagger.converge_tags
253
252
  end
254
253
  ```
255
254
 
256
- See `docs/examples/aws_tags.rb` for further examples.
255
+ The `aws_tagger` method is used by the tests to assert that the object tags are correct. These methods can be encapsulated in an module for DRY purposes, as the EC2 strategy shows.
256
+
257
+ Finally, you should add 3 standard tests for taggable objects - 1) Tags can be created on a new object, 2) Tags can be updated on an existing object with tags and 3) Tags can be cleared by setting `aws_tags {}`. Copy the tests from an existing spec file and modify them to support your resource. TODO make a module that copies these tests for us. Right now it is complicated by the fact that some resources have required attributes that others don't.
257
258
 
258
259
  # Looking up AWS objects
259
260
 
data/Rakefile CHANGED
@@ -4,14 +4,34 @@ require 'rspec/core/rake_task'
4
4
 
5
5
  task :default => :spec
6
6
 
7
- desc "Run specs"
7
+ ENV['AWS_TEST_DRIVER'] ||= "aws"
8
+
9
+ desc "run all non-integration specs"
8
10
  RSpec::Core::RakeTask.new(:spec) do |spec|
9
11
  spec.pattern = 'spec/**/*_spec.rb'
10
12
  # TODO add back integration tests whenever we have strategy for keys
11
13
  spec.exclude_pattern = 'spec/integration/**/*_spec.rb'
12
14
  end
13
15
 
14
- desc "Run Integration Specs"
16
+ desc "run integration specs"
15
17
  RSpec::Core::RakeTask.new(:integration) do |spec|
16
18
  spec.pattern = 'spec/integration/**/*_spec.rb'
17
19
  end
20
+
21
+ desc "run :super_slow specs (machine/machine_image)"
22
+ RSpec::Core::RakeTask.new(:slow) do |spec|
23
+ spec.pattern = 'spec/**/*_spec.rb'
24
+ spec.rspec_opts = "-t super_slow"
25
+ end
26
+
27
+ desc "run all specs, except :super_slow"
28
+ RSpec::Core::RakeTask.new(:all) do |spec|
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ end
31
+
32
+ desc "run all specs, including :super_slow"
33
+ task :all_slow do
34
+ %w(all slow).each do |t|
35
+ Rake::Task[t].invoke
36
+ end
37
+ end
@@ -2,11 +2,12 @@ require 'chef/provisioning/aws_driver/aws_provider'
2
2
  require 'set'
3
3
 
4
4
  class Chef::Provider::AwsAutoScalingGroup < Chef::Provisioning::AWSDriver::AWSProvider
5
+ provides :aws_auto_scaling_group
5
6
 
6
7
  protected
7
8
 
8
9
  def create_aws_object
9
- converge_by "create new Auto Scaling Group #{new_resource.name} in #{region}" do
10
+ converge_by "create Auto Scaling group #{new_resource.name} in #{region}" do
10
11
  options = desired_options.dup
11
12
  options[:min_size] ||= 1
12
13
  options[:max_size] ||= 1
@@ -20,7 +21,7 @@ class Chef::Provider::AwsAutoScalingGroup < Chef::Provisioning::AWSDriver::AWSPr
20
21
  end
21
22
 
22
23
  def destroy_aws_object(group)
23
- converge_by "delete Auto Scaling Group #{new_resource.name} in #{region}" do
24
+ converge_by "delete Auto Scaling group #{new_resource.name} in #{region}" do
24
25
  group.delete!
25
26
  end
26
27
  end
@@ -1,11 +1,12 @@
1
1
  require 'chef/provisioning/aws_driver/aws_provider'
2
2
 
3
3
  class Chef::Provider::AwsCacheCluster < Chef::Provisioning::AWSDriver::AWSProvider
4
+ provides :aws_cache_cluster
4
5
 
5
6
  protected
6
7
 
7
8
  def create_aws_object
8
- converge_by "create new Elasticache Cluster #{new_resource.name} in #{region}" do
9
+ converge_by "create ElastiCache cluster #{new_resource.name} in #{region}" do
9
10
  driver.create_cache_cluster(desired_options)
10
11
  end
11
12
  end
@@ -23,7 +24,7 @@ class Chef::Provider::AwsCacheCluster < Chef::Provisioning::AWSDriver::AWSProvid
23
24
  end
24
25
 
25
26
  def destroy_aws_object(cache_cluster)
26
- converge_by "delete Elasticache Cluster #{new_resource.name} in #{region}" do
27
+ converge_by "delete ElastiCache cluster #{new_resource.name} in #{region}" do
27
28
  driver.delete_cache_cluster(
28
29
  cache_cluster_id: cache_cluster[:cache_cluster_id]
29
30
  )
@@ -1,21 +1,22 @@
1
1
  require 'chef/provisioning/aws_driver/aws_provider'
2
2
 
3
3
  class Chef::Provider::AwsCacheReplicationGroup < Chef::Provisioning::AWSDriver::AWSProvider
4
-
4
+ provides :aws_cache_replication_group
5
+
5
6
  protected
6
7
 
7
8
  def create_aws_object
8
- converge_by "create new Elasticache Replication Group #{new_resource.name} in #{region}" do
9
+ converge_by "create ElastiCache replication group #{new_resource.name} in #{region}" do
9
10
  driver.create_replication_group(desired_options)
10
11
  end
11
12
  end
12
13
 
13
14
  def update_aws_object(cache_replication_group)
14
- Chef::Log.warn('Updating Elasticache Replication Groups is currently unsupported')
15
+ Chef::Log.warn('Updating ElastiCache replication groups is currently unsupported')
15
16
  end
16
17
 
17
18
  def destroy_aws_object(cache_replication_group)
18
- converge_by "delete Elasticache Replication group #{new_resource.name} in #{region}" do
19
+ converge_by "delete ElastiCache replication group #{new_resource.name} in #{region}" do
19
20
  driver.delete_replication_group(
20
21
  replication_group_id: cache_replication_group[:replication_group_id]
21
22
  )
@@ -1,25 +1,26 @@
1
1
  require 'chef/provisioning/aws_driver/aws_provider'
2
2
 
3
3
  class Chef::Provider::AwsCacheSubnetGroup < Chef::Provisioning::AWSDriver::AWSProvider
4
-
4
+ provides :aws_cache_subnet_group
5
+
5
6
  protected
6
7
 
7
8
  def create_aws_object
8
- converge_by "create new Elasticache Subnet Group #{new_resource.name} in #{region}" do
9
+ converge_by "create ElastiCache subnet group #{new_resource.name} in #{region}" do
9
10
  driver.create_cache_subnet_group(desired_options)
10
11
  end
11
12
  end
12
13
 
13
14
  def update_aws_object(cache_subnet_group)
14
15
  if update_required?(cache_subnet_group)
15
- converge_by "update Elasticache Subnet Group #{new_resource.name} in #{region}" do
16
+ converge_by "update ElastiCache subnet group #{new_resource.name} in #{region}" do
16
17
  driver.modify_cache_subnet_group(desired_options)
17
18
  end
18
19
  end
19
20
  end
20
21
 
21
22
  def destroy_aws_object(cache_subnet_group)
22
- converge_by "delete Elasticache Subnet Group #{new_resource.name} in #{region}" do
23
+ converge_by "delete ElastiCache subnet group #{new_resource.name} in #{region}" do
23
24
  driver.delete_cache_subnet_group(
24
25
  cache_subnet_group_name: cache_subnet_group[:cache_subnet_group_name]
25
26
  )
@@ -0,0 +1,163 @@
1
+ require 'chef/provisioning/aws_driver/aws_provider'
2
+
3
+ class Chef::Provider::AwsCloudsearchDomain < Chef::Provisioning::AWSDriver::AWSProvider
4
+ provides :aws_cloudsearch_domain
5
+
6
+ def create_aws_object
7
+ domain = nil # define here to ensure it is available outside of the coverge_by scope
8
+ converge_by "create CloudSearch domain #{new_resource.name}" do
9
+ domain = create_domain
10
+ end
11
+
12
+ update_aws_object(domain)
13
+ end
14
+
15
+ def destroy_aws_object(domain)
16
+ converge_by "delete CloudSearch domain #{new_resource.name}" do
17
+ cs_client.delete_domain(domain_name: new_resource.name)
18
+ end
19
+ # CloudSearch can take over 30 minutes to delete so im not adding a waiter
20
+ # for now
21
+ end
22
+
23
+ def update_aws_object(domain)
24
+ if update_availability_options?(domain)
25
+ converge_by "update availability options for CloudSearch domain #{new_resource}" do
26
+ update_availability_options
27
+ end
28
+ end
29
+
30
+ if update_scaling_params?(domain)
31
+ converge_by "update scaling parameters for CloudSearch domain #{new_resource.name}" do
32
+ update_scaling_parameters
33
+ end
34
+ end
35
+
36
+ if update_policy?(domain)
37
+ converge_by "update access policy for CloudSearch domain #{new_resource.name}" do
38
+ update_service_access_policy
39
+ end
40
+ end
41
+
42
+ if update_index_fields?(domain)
43
+ Chef::Log.warn("Updating existing index_fields not currently supported")
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def update_availability_options?(_domain)
50
+ # new_resource.multi_az defaults to false so we don't need an existence check
51
+ new_resource.multi_az != availability_options
52
+ end
53
+
54
+ def update_scaling_params?(domain)
55
+ if new_resource.partition_count || new_resource.replication_count || new_resource.instance_type
56
+ # We don't want to change scaling parameters that the user
57
+ # didn't specify. Thus, we compare on a key-by-key basis. Only
58
+ # user-specified keys show up in desired_scaling_parameters
59
+ actual_scaling_parameters = scaling_parameters(domain)
60
+ desired_scaling_parameters.each do |key, value|
61
+ return true if value != actual_scaling_parameters[key]
62
+ end
63
+ false
64
+ else
65
+ false
66
+ end
67
+ end
68
+
69
+ def update_policy?(_domain)
70
+ if !new_resource.access_policies.nil?
71
+ new_resource.access_policies != access_policies
72
+ else
73
+ false
74
+ end
75
+ end
76
+
77
+ def update_index_fields?(domain)
78
+ if ! new_resource.index_fields.nil?
79
+ new_resource.index_fields != index_fields
80
+ else
81
+ false
82
+ end
83
+ end
84
+
85
+ def desired_scaling_parameters
86
+ ret = {}
87
+ ret[:desired_partition_count] = new_resource.partition_count if new_resource.partition_count
88
+ ret[:desired_replication_count] = new_resource.replication_count if new_resource.replication_count
89
+ ret[:desired_instance_type] = new_resource.instance_type if new_resource.instance_type
90
+ ret
91
+ end
92
+
93
+ #
94
+ # API Update Functions
95
+ #
96
+ # The following functions all make changes to our domain. Unlike
97
+ # other AWS APIs we don't have a single modify function for this
98
+ # domain. Rather, updates our split up over a number of different
99
+ # API requestsion.
100
+ #
101
+ def create_domain
102
+ cs_client.create_domain(domain_name: new_resource.name)[:domain_status]
103
+ end
104
+
105
+ def update_availability_options
106
+ cs_client.update_availability_options(domain_name: new_resource.name,
107
+ multi_az: new_resource.multi_az)
108
+ end
109
+
110
+ def update_scaling_parameters
111
+ cs_client.update_scaling_parameters(domain_name: new_resource.name,
112
+ scaling_parameters: desired_scaling_parameters)
113
+ end
114
+
115
+ def update_service_access_policy
116
+ cs_client.update_service_access_policies(domain_name: new_resource.name,
117
+ access_policies: new_resource.access_policies)
118
+ end
119
+
120
+ def create_index_field(field)
121
+ cs_client.define_index_field(domain_name: new_resource.name, index_field: field)
122
+ end
123
+
124
+ #
125
+ # API Query Functions
126
+ #
127
+ # The CloudSearch API doesn't provide all of the data about the
128
+ # domain's settings via the descrbe domain API. We have to call
129
+ # additional endpoints to determine the current values of:
130
+ # availability_options, scalability_parameters, index_fields, and
131
+ # access_policies
132
+ #
133
+ def availability_options
134
+ get_option(:availability_options)
135
+ end
136
+
137
+ def scaling_parameters(object)
138
+ o = get_option(:scaling_parameters)
139
+ o.merge(desired_instance_type: object[:search_instance_type])
140
+ end
141
+
142
+ def access_policies
143
+ get_option(:service_access_policies, :access_policies)
144
+ end
145
+
146
+ def index_fields
147
+ cs_client.describe_index_fields(domain_name: new_resource.name)[:index_fields]
148
+ end
149
+
150
+ def get_option(option_name, key=nil)
151
+ opt = cs_client.send("describe_#{option_name}".to_sym,
152
+ {domain_name: new_resource.name})[key || option_name]
153
+ if ! opt[:status][:pending_deletion]
154
+ opt[:options]
155
+ else
156
+ nil
157
+ end
158
+ end
159
+
160
+ def cs_client
161
+ @cs_client ||= new_resource.driver.cloudsearch(new_resource.cloudsearch_api_version)
162
+ end
163
+ end