chef-provisioning-aws 1.3.1 → 1.4.0

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.
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
@@ -0,0 +1,29 @@
1
+ require 'chef/provisioning/aws_driver/aws_rds_resource'
2
+ require 'chef/provisioning/aws_driver/aws_taggable'
3
+ require 'chef/resource/aws_subnet'
4
+
5
+ class Chef::Resource::AwsRdsSubnetGroup < Chef::Provisioning::AWSDriver::AWSRDSResource
6
+ include Chef::Provisioning::AWSDriver::AWSTaggable
7
+
8
+ aws_sdk_type AWS::RDS
9
+
10
+ attribute :name, kind_of: String, name_attribute: true
11
+ attribute :description, kind_of: String, required: true
12
+ attribute :subnets,
13
+ kind_of: [ String, Array, AwsSubnet, AWS::EC2::Subnet ],
14
+ required: true,
15
+ coerce: proc { |v| [v].flatten }
16
+
17
+ def aws_object
18
+ driver.rds.client
19
+ .describe_db_subnet_groups(db_subnet_group_name: name)[:db_subnet_groups].first
20
+ rescue AWS::RDS::Errors::DBSubnetGroupNotFoundFault
21
+ # triggered by describe_db_subnet_groups when the group can't
22
+ # be found
23
+ nil
24
+ end
25
+
26
+ def rds_tagging_type
27
+ "subgrp"
28
+ end
29
+ end
@@ -13,7 +13,8 @@ require 'chef/provisioning/aws_driver/aws_resource_with_entry'
13
13
  # - http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/RouteTable.html
14
14
  #
15
15
  class Chef::Resource::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSResourceWithEntry
16
- aws_sdk_type AWS::EC2::RouteTable
16
+ include Chef::Provisioning::AWSDriver::AWSTaggable
17
+ aws_sdk_type ::Aws::EC2::RouteTable
17
18
 
18
19
  require 'chef/resource/aws_vpc'
19
20
 
@@ -63,7 +64,8 @@ class Chef::Resource::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSResource
63
64
  # - { internet_gateway: <AWS Internet Gateway ID or object> }
64
65
  # - { instance: <Chef machine name or resource, AWS Instance ID or object> }
65
66
  # - { network_interface: <AWS Network Interface ID or object> }
66
- # - <AWS Internet Gateway, Instance or Network Interface <ID or object)>
67
+ # - { vpc_peering_connection: <AWS VPC Peering Connection ID or object> }
68
+ # - <AWS Internet Gateway, Instance, Network Interface or a VPC Peering Connection <ID or object)>
67
69
  # - Chef machine name
68
70
  # - Chef machine resource
69
71
  #
@@ -95,11 +97,11 @@ class Chef::Resource::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSResource
95
97
 
96
98
  def aws_object
97
99
  driver, id = get_driver_and_id
98
- result = driver.ec2.route_tables[id] if id
100
+ result = driver.ec2_resource.route_table(id) if id
99
101
  begin
100
102
  # try accessing it to find out if it exists
101
- result.vpc if result
102
- rescue AWS::EC2::Errors::InvalidRouteTableID::NotFound
103
+ result.vpc_id if result
104
+ rescue ::Aws::EC2::Errors::InvalidRouteTableIDNotFound
103
105
  result = nil
104
106
  end
105
107
  result
@@ -1,12 +1,15 @@
1
1
  require 'chef/provisioning/aws_driver/aws_resource'
2
2
 
3
3
  class Chef::Resource::AwsS3Bucket < Chef::Provisioning::AWSDriver::AWSResource
4
+ include Chef::Provisioning::AWSDriver::AWSTaggable
5
+
4
6
  aws_sdk_type AWS::S3::Bucket, id: :name
5
7
 
6
8
  attribute :name, :kind_of => String, :name_attribute => true
7
9
  attribute :options, :kind_of => Hash, :default => {}
8
10
  attribute :enable_website_hosting, :kind_of => [TrueClass, FalseClass], :default => false
9
11
  attribute :website_options, :kind_of => Hash, :default => {}
12
+ attribute :recursive_delete, :kind_of => [TrueClass, FalseClass], :default => false
10
13
 
11
14
  def aws_object
12
15
  result = driver.s3.buckets[name]
@@ -3,6 +3,8 @@ require 'chef/resource/aws_vpc'
3
3
  require 'chef/provisioning/aws_driver/exceptions'
4
4
 
5
5
  class Chef::Resource::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSResource
6
+ include Chef::Provisioning::AWSDriver::AWSTaggable
7
+
6
8
  aws_sdk_type AWS::EC2::SecurityGroup,
7
9
  id: :id,
8
10
  option_names: [:security_group, :security_group_id, :security_group_name]
@@ -11,13 +13,6 @@ class Chef::Resource::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSResou
11
13
  attribute :vpc, kind_of: [ String, AwsVpc, AWS::EC2::VPC ]
12
14
  attribute :description, kind_of: String
13
15
 
14
- # This should be a hash of tags to apply to the AWS object
15
- # TODO this is duplicated from AWSResourceWithEntry
16
- #
17
- # @param aws_tags [Hash] Should be a hash of keys & values to add. Keys and values
18
- # can be provided as symbols or strings, but will be stored in AWS as strings.
19
- attribute :aws_tags, kind_of: Hash
20
-
21
16
  #
22
17
  # Accepts rules in the format:
23
18
  # [
@@ -0,0 +1,21 @@
1
+ require 'chef/provisioning/aws_driver/aws_resource'
2
+
3
+ class Chef::Resource::AwsServerCertificate < Chef::Provisioning::AWSDriver::AWSResource
4
+ aws_sdk_type AWS::IAM::ServerCertificate
5
+
6
+ attribute :name, kind_of: String, name_attribute: true
7
+
8
+ attribute :certificate_body, kind_of: String
9
+ attribute :private_key, kind_of: String
10
+
11
+ def aws_object
12
+ begin
13
+ cert = driver.iam.server_certificates[name]
14
+ # this will trigger a AWS::IAM::Errors::NoSuchEntity if the cert does not exist
15
+ cert.arn
16
+ cert
17
+ rescue AWS::IAM::Errors::NoSuchEntity
18
+ nil
19
+ end
20
+ end
21
+ end
@@ -14,6 +14,8 @@ require 'chef/provisioning/aws_driver/aws_resource_with_entry'
14
14
  # - http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/Subnet.html
15
15
  #
16
16
  class Chef::Resource::AwsSubnet < Chef::Provisioning::AWSDriver::AWSResourceWithEntry
17
+ include Chef::Provisioning::AWSDriver::AWSTaggable
18
+
17
19
  aws_sdk_type AWS::EC2::Subnet
18
20
 
19
21
  require 'chef/resource/aws_vpc'
@@ -26,7 +26,10 @@ require 'chef/provisioning/aws_driver/aws_resource_with_entry'
26
26
  # - http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/VPC.html
27
27
  #
28
28
  class Chef::Resource::AwsVpc < Chef::Provisioning::AWSDriver::AWSResourceWithEntry
29
- aws_sdk_type AWS::EC2::VPC
29
+ include Chef::Provisioning::AWSDriver::AWSTaggable
30
+ aws_sdk_type AWS::EC2::VPC,
31
+ id: :id,
32
+ option_names: [:vpc, :vpc_id, :peer_vpc_id]
30
33
 
31
34
  require 'chef/resource/aws_dhcp_options'
32
35
  require 'chef/resource/aws_route_table'
@@ -0,0 +1,73 @@
1
+ require 'chef/provisioning/aws_driver/aws_resource_with_entry'
2
+
3
+ #
4
+ # An AWS peering connection, specifying which VPC to peer.
5
+ #
6
+ # `name` is not guaranteed unique for an AWS account; therefore, Chef will
7
+ # store the vpc peering connection ID associated with this name in your Chef server in the
8
+ # data bag `data/aws_vpc_peering_connection/<name>`.
9
+ #
10
+ # API documentation for the AWS Ruby SDK for VPC Peering Connections can be found here:
11
+ #
12
+ # - http://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Types/VpcPeeringConnectionVpcInfo.html
13
+ #
14
+ class Chef::Resource::AwsVpcPeeringConnection < Chef::Provisioning::AWSDriver::AWSResourceWithEntry
15
+ aws_sdk_type ::Aws::EC2::VpcPeeringConnection
16
+ actions :accept, :create, :destroy, :purge, :nothing
17
+
18
+ require 'chef/resource/aws_vpc'
19
+
20
+ #
21
+ # The name of this peering connection.
22
+ #
23
+ attribute :name, kind_of: String, name_attribute: true
24
+
25
+ #
26
+ # The Local VPC to peer
27
+ #
28
+ # May be one of:
29
+ # - The name of an `aws_vpc` Chef resource.
30
+ # - An actual `aws_vpc` resource.
31
+ # - An AWS `VPC` object.
32
+ #
33
+ # This is required for new peering connections.
34
+ #
35
+ attribute :vpc, kind_of: [ String, AwsVpc, AWS::EC2::VPC ]
36
+
37
+ #
38
+ # The VPC to peer
39
+ #
40
+ # May be one of:
41
+ # - The name of an `aws_vpc` Chef resource.
42
+ # - An actual `aws_vpc` resource.
43
+ # - An AWS `VPC` object.
44
+ # - The id of an AWS `VPC`.
45
+ #
46
+ # This is required for new peering connections.
47
+ #
48
+ attribute :peer_vpc, kind_of: [ String, AwsVpc, AWS::EC2::VPC ]
49
+
50
+ #
51
+ # The target VPC account id to peer
52
+ #
53
+ # If not specified, will be assumed that the target VPC belongs to the current account.
54
+ #
55
+ attribute :peer_owner_id, kind_of: String
56
+
57
+ attribute :vpc_peering_connection_id, kind_of: String, aws_id_attribute: true, lazy_default: proc {
58
+ name =~ /^pcx-[a-f0-9]{8}$/ ? name : nil
59
+ }
60
+
61
+ def aws_object
62
+ driver, id = get_driver_and_id
63
+ result = driver.ec2_resource.vpc_peering_connection(id) if id
64
+
65
+ begin
66
+ # try accessing it to find out if it exists
67
+ result.requester_vpc if result
68
+ rescue ::Aws::EC2::Errors::InvalidVpcPeeringConnectionIDNotFound
69
+ result = nil
70
+ end
71
+ result
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ {
2
+ "name": "ettores-mbp.lan"
3
+ }
data/spec/aws_support.rb CHANGED
@@ -23,7 +23,7 @@ module AWSSupport
23
23
  require 'aws'
24
24
  require 'aws_support/deep_matcher/matchable_object'
25
25
  require 'aws_support/deep_matcher/matchable_array'
26
- DeepMatcher::MatchableObject.matchable_classes << proc { |o| o.class.name =~ /^AWS::(EC2|ELB)($|::)/ }
26
+ DeepMatcher::MatchableObject.matchable_classes << proc { |o| o.class.name =~ /^(AWS|Aws)::(EC2|ELB|IAM|S3|RDS|CloudSearch)($|::)/ }
27
27
  DeepMatcher::MatchableArray.matchable_classes << AWS::Core::Data::List
28
28
 
29
29
  def purge_all
@@ -66,6 +66,12 @@ module AWSSupport
66
66
  end.converge
67
67
  end
68
68
 
69
+ aws_security_group 'test_security_group' do
70
+ vpc 'test_vpc'
71
+ inbound_rules '0.0.0.0/0' => [ 22, 80 ]
72
+ outbound_rules [ 22, 80 ] => '0.0.0.0/0'
73
+ end
74
+
69
75
  aws_subnet 'test_public_subnet' do
70
76
  vpc 'test_vpc'
71
77
  map_public_ip_on_launch true
@@ -118,8 +124,11 @@ module AWSSupport
118
124
  # Destroys it after the last example in the context runs. Objects created
119
125
  # in the order declared, and destroyed in reverse order.
120
126
  #
121
- Chef::Provisioning::AWSDriver::Resources.constants.each do |resource_class|
122
- resource_class = Chef::Provisioning::AWSDriver::Resources.const_get(resource_class)
127
+ aws_resources = Chef::Provisioning::AWSDriver::Resources.constants
128
+ aws_resources.map! {|r| Chef::Provisioning::AWSDriver::Resources.const_get(r) }
129
+
130
+ aws_resources += [Chef::Resource::Machine, Chef::Resource::MachineImage, Chef::Resource::MachineBatch, Chef::Resource::LoadBalancer]
131
+ aws_resources.each do |resource_class|
123
132
  resource_name = resource_class.resource_name
124
133
  # def aws_vpc(name, &block)
125
134
  define_method(resource_name) do |name, &block|
@@ -168,11 +177,19 @@ module AWSSupport
168
177
 
169
178
  # Destroy any objects we know got created during the test
170
179
  created_during_test.reverse_each do |resource_name, name|
171
- (recipe do
172
- public_send(resource_name, name) do
173
- action :purge
174
- end
175
- end).converge
180
+ begin
181
+ (recipe do
182
+ public_send(resource_name, name) do
183
+ action :purge
184
+ end
185
+ end).converge
186
+ rescue ::Chef::Exceptions::ValidationFailed
187
+ (recipe do
188
+ public_send(resource_name, name) do
189
+ action :destroy
190
+ end
191
+ end).converge
192
+ end
176
193
  end
177
194
  end
178
195
  end
@@ -33,7 +33,11 @@ module AWSSupport
33
33
  name = self.name
34
34
  example.recipe do
35
35
  public_send(resource_type, name) do
36
- action :purge
36
+ if allowed_actions.include?(:purge)
37
+ action :purge
38
+ else
39
+ action :destroy
40
+ end
37
41
  end
38
42
  end.converge
39
43
  end
@@ -2,6 +2,7 @@ module AWSSupport
2
2
  module DeepMatcher
3
3
  module MatchValuesFailureMessages
4
4
 
5
+ require 'set'
5
6
  require 'rspec/matchers'
6
7
  require 'rspec/matchers/composable'
7
8
  require 'aws_support/deep_matcher'
@@ -19,6 +20,8 @@ module AWSSupport
19
20
  else
20
21
  return []
21
22
  end
23
+ elsif Set === expected
24
+ return match_sets_failure_messages(expected, actual, identifier)
22
25
  elsif Hash === expected
23
26
  return match_hashes_failure_messages(expected, actual, identifier) if Hash === actual
24
27
  return match_hash_and_object_failure_messages(expected, actual, identifier) if MatchableObject === actual
@@ -35,6 +38,19 @@ module AWSSupport
35
38
  end
36
39
  end
37
40
 
41
+ def match_sets_failure_messages(expected_set, actual_setlike, identifier)
42
+ result = []
43
+ if ! actual_setlike.respond_to?(:to_set)
44
+ result << "expected #{identifier || "setlike"} to be castable to a Set, but it isn't!"
45
+ else
46
+ if ! actual_setlike.to_set == expected_set
47
+
48
+ result << "expected #{identifier || "setlike"} to #{description_of(expected_value)}"
49
+ end
50
+ end
51
+ result
52
+ end
53
+
38
54
  def match_hashes_failure_messages(expected_hash, actual_hash, identifier)
39
55
  result = []
40
56
 
@@ -62,6 +78,9 @@ module AWSSupport
62
78
  different = false
63
79
 
64
80
  expected_list = expected_list.map { |v| ExpectedValue.new(v) }
81
+ unless actual_list.class <= Array
82
+ actual_list = actual_list.to_a
83
+ end
65
84
  Diff::LCS.sdiff(expected_list, actual_list) do |change|
66
85
  case change.action
67
86
  when '='
@@ -32,7 +32,7 @@ module AWSSupport
32
32
 
33
33
  # Converge
34
34
  begin
35
- recipe.converge
35
+ recipe.converge unless recipe.converged?
36
36
  rescue
37
37
  differences += [ "error trying to create #{resource_name}[#{name}]!\n#{($!.backtrace.map { |line| "- #{line}\n" } + [ recipe.output_for_failure_message ]).join("")}" ]
38
38
  end
@@ -38,7 +38,7 @@ module AWSSupport
38
38
 
39
39
  # Converge
40
40
  begin
41
- recipe.converge
41
+ recipe.converge unless recipe.converged?
42
42
  rescue
43
43
  differences += [ "error trying to delete #{resource_name}[#{name}]!\n#{($!.backtrace.map { |line| "- #{line}\n" } + [ recipe.output_for_failure_message ]).join("")}" ]
44
44
  end
@@ -34,9 +34,9 @@ module AWSSupport
34
34
 
35
35
  # Check existence
36
36
  if @aws_object.nil?
37
- differences << "#{resource_name}[#{name}] did not exist!"
37
+ differences << "#{resource.to_s} did not exist!"
38
38
  else
39
- differences += match_hashes_failure_messages(expected_tags, aws_object_tags, "#{resource_name}[#{name}]")
39
+ differences += match_hashes_failure_messages(expected_tags, aws_object_tags(resource), resource.to_s)
40
40
  end
41
41
 
42
42
  differences
@@ -44,20 +44,14 @@ module AWSSupport
44
44
 
45
45
  private
46
46
 
47
- def aws_object_tags
48
- if @aws_object.is_a? AWS::ELB::LoadBalancer
49
- resp = @example.driver.elb.client.describe_tags load_balancer_names: [@aws_object.name]
50
- tags = {}
51
- resp.data[:tag_descriptions] && resp.data[:tag_descriptions].each do |td|
52
- td[:tags].each do |t|
53
- tags[t[:key]] = t[:value]
54
- end
55
- end
56
- tags
57
- else
58
- @aws_object.tags.to_h
59
- end
47
+ def aws_object_tags(resource)
48
+ # Okay, its annoying to have to lookup the provider for a resource and duplicate a bunch of code here.
49
+ # But I don't want to move the `converge_tags` method into the resource and until the resource & provider
50
+ # are combined, this is my best idea.
51
+ provider = resource.provider_for_action(:create)
52
+ provider.aws_tagger.current_tags
60
53
  end
54
+
61
55
  end
62
56
  end
63
57
  end
@@ -33,7 +33,7 @@ module AWSSupport
33
33
 
34
34
  # Converge
35
35
  begin
36
- recipe.converge
36
+ recipe.converge unless recipe.converged?
37
37
  rescue
38
38
  differences += [ "error trying to converge #{resource_name}[#{name}]!\n#{($!.backtrace.map { |line| "- #{line}\n" } + [ recipe.output_for_failure_message ]).join("")}" ]
39
39
  end
@@ -42,7 +42,7 @@ module AWSSupport
42
42
 
43
43
  # Converge
44
44
  begin
45
- recipe.converge
45
+ recipe.converge unless recipe.converged?
46
46
  rescue
47
47
  differences += [ "error trying to update #{resource_name}[#{name}]!\n#{($!.backtrace.map { |line| "- #{line}\n" } + [ recipe.output_for_failure_message ]).join("")}" ]
48
48
  end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chef::Resource::AwsCloudsearchDomain do
4
+ extend AWSSupport
5
+ when_the_chef_12_server "exists", organization: "foo", server_scope: :context do
6
+ with_aws "when connected to AWS" do
7
+
8
+ # Cloudsearch can take forevvvver to delete so we need to randomize our names
9
+ time = DateTime.now.strftime('%Q')
10
+
11
+ it "aws_cloudsearch_domain 'test-#{time}' creates a cloudsearch domain" do
12
+ expect_recipe {
13
+ aws_cloudsearch_domain "test-#{time}" do
14
+ multi_az false
15
+ end
16
+ }.to create_an_aws_cloudsearch_domain("test-#{time}", {}).and be_idempotent
17
+ end
18
+
19
+ it "returns nil when aws_object is called for something that does not exist" do
20
+ r = nil
21
+ converge {
22
+ r = aws_cloudsearch_domain "wont-exist" do
23
+ action :nothing
24
+ end
25
+ }
26
+ expect(r.aws_object).to eq(nil)
27
+ end
28
+
29
+ end
30
+ end
31
+ end