chef-provisioning-aws 2.2.2 → 3.0.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/chef-provisioning-aws.gemspec +0 -1
  4. data/lib/chef/provider/aws_auto_scaling_group.rb +9 -6
  5. data/lib/chef/provider/aws_dhcp_options.rb +21 -11
  6. data/lib/chef/provider/aws_ebs_volume.rb +26 -24
  7. data/lib/chef/provider/aws_eip_address.rb +11 -12
  8. data/lib/chef/provider/aws_image.rb +1 -1
  9. data/lib/chef/provider/aws_internet_gateway.rb +18 -10
  10. data/lib/chef/provider/aws_key_pair.rb +6 -6
  11. data/lib/chef/provider/aws_launch_configuration.rb +7 -9
  12. data/lib/chef/provider/aws_nat_gateway.rb +2 -2
  13. data/lib/chef/provider/aws_network_acl.rb +11 -8
  14. data/lib/chef/provider/aws_network_interface.rb +34 -29
  15. data/lib/chef/provider/aws_rds_parameter_group.rb +1 -1
  16. data/lib/chef/provider/aws_rds_subnet_group.rb +1 -1
  17. data/lib/chef/provider/aws_route_table.rb +7 -7
  18. data/lib/chef/provider/aws_s3_bucket.rb +24 -12
  19. data/lib/chef/provider/aws_security_group.rb +202 -25
  20. data/lib/chef/provider/aws_server_certificate.rb +3 -4
  21. data/lib/chef/provider/aws_sns_topic.rb +4 -3
  22. data/lib/chef/provider/aws_sqs_queue.rb +7 -3
  23. data/lib/chef/provider/aws_subnet.rb +45 -21
  24. data/lib/chef/provider/aws_vpc.rb +59 -30
  25. data/lib/chef/provisioning/aws_driver/aws_provider.rb +12 -3
  26. data/lib/chef/provisioning/aws_driver/aws_resource.rb +2 -2
  27. data/lib/chef/provisioning/aws_driver/aws_resource_with_entry.rb +1 -1
  28. data/lib/chef/provisioning/aws_driver/aws_tagger.rb +2 -2
  29. data/lib/chef/provisioning/aws_driver/credentials.rb +1 -1
  30. data/lib/chef/provisioning/aws_driver/credentials2.rb +5 -1
  31. data/lib/chef/provisioning/aws_driver/driver.rb +124 -34
  32. data/lib/chef/provisioning/aws_driver/tagging_strategy/rds.rb +4 -4
  33. data/lib/chef/provisioning/aws_driver/tagging_strategy/s3.rb +1 -1
  34. data/lib/chef/provisioning/aws_driver/version.rb +1 -1
  35. data/lib/chef/resource/aws_auto_scaling_group.rb +2 -2
  36. data/lib/chef/resource/aws_cache_cluster.rb +4 -4
  37. data/lib/chef/resource/aws_cache_replication_group.rb +3 -3
  38. data/lib/chef/resource/aws_cache_subnet_group.rb +4 -4
  39. data/lib/chef/resource/aws_cloudsearch_domain.rb +1 -1
  40. data/lib/chef/resource/aws_cloudwatch_alarm.rb +1 -1
  41. data/lib/chef/resource/aws_dhcp_options.rb +10 -3
  42. data/lib/chef/resource/aws_ebs_volume.rb +10 -4
  43. data/lib/chef/resource/aws_eip_address.rb +4 -4
  44. data/lib/chef/resource/aws_elasticsearch_domain.rb +1 -1
  45. data/lib/chef/resource/aws_iam_role.rb +1 -1
  46. data/lib/chef/resource/aws_internet_gateway.rb +11 -4
  47. data/lib/chef/resource/aws_key_pair.rb +4 -3
  48. data/lib/chef/resource/aws_launch_configuration.rb +5 -4
  49. data/lib/chef/resource/aws_load_balancer.rb +14 -3
  50. data/lib/chef/resource/aws_nat_gateway.rb +2 -2
  51. data/lib/chef/resource/aws_network_acl.rb +10 -10
  52. data/lib/chef/resource/aws_network_interface.rb +12 -6
  53. data/lib/chef/resource/aws_rds_parameter_group.rb +6 -6
  54. data/lib/chef/resource/aws_rds_subnet_group.rb +4 -5
  55. data/lib/chef/resource/aws_route53_record_set.rb +1 -1
  56. data/lib/chef/resource/aws_route_table.rb +1 -1
  57. data/lib/chef/resource/aws_s3_bucket.rb +3 -2
  58. data/lib/chef/resource/aws_security_group.rb +6 -6
  59. data/lib/chef/resource/aws_server_certificate.rb +4 -5
  60. data/lib/chef/resource/aws_sns_topic.rb +4 -4
  61. data/lib/chef/resource/aws_sqs_queue.rb +3 -3
  62. data/lib/chef/resource/aws_subnet.rb +5 -5
  63. data/lib/chef/resource/aws_vpc.rb +12 -6
  64. data/lib/chef/resource/aws_vpc_peering_connection.rb +2 -2
  65. data/spec/aws_support.rb +12 -9
  66. data/spec/aws_support/deep_matcher/match_values_failure_messages.rb +15 -5
  67. data/spec/integration/aws_dhcp_options_spec.rb +7 -7
  68. data/spec/integration/aws_ebs_volume_spec.rb +1 -1
  69. data/spec/integration/aws_internet_gateway_spec.rb +19 -18
  70. data/spec/integration/aws_key_pair_spec.rb +1 -1
  71. data/spec/integration/aws_nat_gateway_spec.rb +3 -6
  72. data/spec/integration/aws_network_acl_spec.rb +19 -11
  73. data/spec/integration/aws_network_interface_spec.rb +26 -20
  74. data/spec/integration/aws_rds_instance_spec.rb +6 -7
  75. data/spec/integration/aws_rds_subnet_group_spec.rb +6 -6
  76. data/spec/integration/aws_route53_hosted_zone_spec.rb +1 -1
  77. data/spec/integration/aws_s3_bucket_spec.rb +1 -2
  78. data/spec/integration/aws_security_group_spec.rb +272 -198
  79. data/spec/integration/aws_server_certificate_spec.rb +60 -78
  80. data/spec/integration/aws_subnet_spec.rb +8 -4
  81. data/spec/integration/aws_vpc_spec.rb +29 -23
  82. data/spec/integration/machine_spec.rb +1 -1
  83. data/spec/unit/chef/provisioning/aws_driver/credentials_spec.rb +13 -0
  84. data/spec/unit/chef/provisioning/aws_driver/driver_spec.rb +1 -1
  85. data/spec/unit/chef/provisioning/aws_driver/route53_spec.rb +1 -1
  86. metadata +5 -20
  87. data/spec/persistence_file.txt +0 -220
@@ -29,7 +29,7 @@ class Chef::Provider::AwsNatGateway < Chef::Provisioning::AWSDriver::AWSProvider
29
29
  }
30
30
 
31
31
  nat_gateway = new_resource.driver.ec2_resource.create_nat_gateway(options)
32
- wait_for_state(nat_gateway, ['available'])
32
+ wait_for_state(nat_gateway, :available)
33
33
  nat_gateway
34
34
  end
35
35
  end
@@ -51,7 +51,7 @@ class Chef::Provider::AwsNatGateway < Chef::Provisioning::AWSDriver::AWSProvider
51
51
  def destroy_aws_object(nat_gateway)
52
52
  converge_by "delete nat gateway #{new_resource.name} in region #{region} for subnet #{nat_gateway.subnet_id}" do
53
53
  nat_gateway.delete
54
- wait_for_state(nat_gateway, ['deleted'])
54
+ wait_for_state(nat_gateway, :deleted)
55
55
  end
56
56
  end
57
57
  end
@@ -18,14 +18,14 @@ class Chef::Provider::AwsNetworkAcl < Chef::Provisioning::AWSDriver::AWSProvider
18
18
  def create_aws_object
19
19
  converge_by "create network ACL #{new_resource.name} in #{region}" do
20
20
  options = {}
21
- options[:vpc] = new_resource.vpc if new_resource.vpc
21
+ options[:vpc_id] = new_resource.vpc if new_resource.vpc
22
22
  options = AWSResource.lookup_options(options, resource: new_resource)
23
23
 
24
- Chef::Log.debug("VPC: #{options[:vpc]}")
24
+ Chef::Log.debug("VPC: #{options[:vpc_id]}")
25
25
 
26
- network_acl = new_resource.driver.ec2.network_acls.create(options)
27
- retry_with_backoff(AWS::EC2::Errors::InvalidNetworkAclID::NotFound) do
28
- network_acl.tags['Name'] = new_resource.name
26
+ network_acl = new_resource.driver.ec2_resource.create_network_acl(options)
27
+ retry_with_backoff(::Aws::EC2::Errors::InvalidNetworkAclIDNotFound) do
28
+ network_acl.create_tags({tags: [{key: "Name", value: new_resource.name}]})
29
29
  end
30
30
  network_acl
31
31
  end
@@ -83,6 +83,9 @@ class Chef::Provider::AwsNetworkAcl < Chef::Provisioning::AWSDriver::AWSProvider
83
83
  # Anything unhandled will be added
84
84
  desired_rules.delete(desired_rule)
85
85
 
86
+ # Converting matching_rule [:rule_action] and [:port_range] to symbol & hash to match correctly with desired_rule
87
+ matching_rule[:rule_action] = matching_rule[:rule_action].to_sym unless matching_rule[:rule_action].nil?
88
+ matching_rule[:port_range] = matching_rule[:port_range].to_hash unless matching_rule[:port_range].nil?
86
89
  if matching_rule.merge(desired_rule) != matching_rule
87
90
  # Replace anything with a matching rule number but different attributes
88
91
  replace_rules << desired_rule
@@ -115,7 +118,7 @@ class Chef::Provider::AwsNetworkAcl < Chef::Provisioning::AWSDriver::AWSProvider
115
118
  def remove_rules(network_acl, rules)
116
119
  rules.each do |rule|
117
120
  action_handler.report_progress " remove #{rule_direction(rule)} rule #{rule[:rule_number]}"
118
- network_acl.delete_entry(rule_direction(rule).to_sym, rule[:rule_number])
121
+ network_acl.delete_entry(egress: rule[:egress], rule_number: rule[:rule_number])
119
122
  end
120
123
  end
121
124
 
@@ -125,8 +128,8 @@ class Chef::Provider::AwsNetworkAcl < Chef::Provisioning::AWSDriver::AWSProvider
125
128
 
126
129
  def entry_to_hash(entry)
127
130
  options = [
128
- :rule_number, :action, :protocol, :cidr_block, :egress,
129
- :port_range, :icmp_code, :icmp_type
131
+ :rule_number, :rule_action, :protocol, :cidr_block, :egress,
132
+ :port_range, :icmp_type_code
130
133
  ]
131
134
  entry_hash = {}
132
135
  options.each { |option| entry_hash.merge!(option => entry.send(option.to_sym)) }
@@ -33,9 +33,12 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
33
33
  def create_aws_object
34
34
  eni = nil
35
35
  converge_by "create new #{new_resource} in #{region}" do
36
- eni = new_resource.driver.ec2.network_interfaces.create(options)
37
- retry_with_backoff(AWS::EC2::Errors::InvalidNetworkInterfaceID::NotFound) do
38
- eni.tags['Name'] = new_resource.name
36
+ ec2_resource = ::Aws::EC2::Resource.new(new_resource.driver.ec2)
37
+ # we require all the parameter from options except :device_index so deleted & then passed.
38
+ option_without_device_index = options.dup.tap { |h| h.delete(:device_index) }
39
+ eni = ec2_resource.create_network_interface(option_without_device_index)
40
+ retry_with_backoff(::Aws::EC2::Errors::InvalidNetworkInterfaceIDNotFound) do
41
+ ec2_resource.create_tags(resources: [eni.id], tags: [{ key: "Name", value: new_resource.name }])
39
42
  end
40
43
  eni
41
44
  end
@@ -47,8 +50,8 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
47
50
  end
48
51
 
49
52
  def update_aws_object(eni)
50
- if options.has_key?(:subnet)
51
- if Chef::Resource::AwsSubnet.get_aws_object(options[:subnet], resource: new_resource) != eni.subnet
53
+ if options.has_key?(:subnet_id)
54
+ if Chef::Resource::AwsSubnet.get_aws_object(options[:subnet_id], resource: new_resource).id != eni.subnet.id
52
55
  raise "#{new_resource} subnet is #{new_resource.subnet}, but actual network interface has subnet set to #{eni.subnet_id}. Cannot be modified!"
53
56
  end
54
57
  end
@@ -65,20 +68,21 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
65
68
  converge_by "set #{new_resource} description to #{new_resource.description}" do
66
69
  eni.client.modify_network_interface_attribute(:network_interface_id => eni.network_interface_id,
67
70
  :description => {
68
- :value => new_resource.description
69
- })
71
+ :value => new_resource.description })
70
72
  end
71
73
  end
72
74
  end
73
75
 
74
- if options.has_key?(:security_groups)
75
- groups = new_resource.security_groups.map { |sg|
76
- Chef::Resource::AwsSecurityGroup.get_aws_object(sg, resource: new_resource)
77
- }
78
- if groups.sort != eni.security_groups.sort
76
+ if options.has_key?(:groups)
77
+ groups = new_resource.security_groups
78
+ eni_security_groups = []
79
+ eni.groups.each do |group|
80
+ eni_security_groups.push(group.group_id)
81
+ end
82
+
83
+ if groups.sort != eni_security_groups.sort
79
84
  converge_by "set #{new_resource} security groups to #{groups}" do
80
- eni.set_security_groups(groups)
81
- eni
85
+ eni.client.modify_network_interface_attribute(:network_interface_id => eni.network_interface_id, :groups => groups)
82
86
  end
83
87
  end
84
88
  end
@@ -87,7 +91,7 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
87
91
  end
88
92
 
89
93
  def destroy_aws_object(eni)
90
- detach(eni) if eni.status == :in_use
94
+ detach(eni) if eni.status == "in-use"
91
95
  delete(eni)
92
96
  end
93
97
 
@@ -105,10 +109,10 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
105
109
  def options
106
110
  @options ||= begin
107
111
  options = {}
108
- options[:subnet] = new_resource.subnet if !new_resource.subnet.nil?
112
+ options[:subnet_id] = new_resource.subnet if !new_resource.subnet.nil?
109
113
  options[:private_ip_address] = new_resource.private_ip_address if !new_resource.private_ip_address.nil?
110
114
  options[:description] = new_resource.description if !new_resource.description.nil?
111
- options[:security_groups] = new_resource.security_groups if !new_resource.security_groups.nil?
115
+ options[:groups] = new_resource.security_groups if !new_resource.security_groups.nil?
112
116
  options[:device_index] = new_resource.device_index if !new_resource.device_index.nil?
113
117
 
114
118
  AWSResource.lookup_options(options, resource: new_resource)
@@ -116,18 +120,18 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
116
120
  end
117
121
 
118
122
  def update_eni(eni)
119
- status = eni.status
123
+ status = new_resource.driver.ec2_resource.network_interface(eni.id).status
120
124
  #
121
125
  # If we were told to attach the network interface to a machine, do so
122
126
  #
123
- if expected_instance.is_a?(AWS::EC2::Instance) || expected_instance.is_a?(::Aws::EC2::Instance)
127
+ if expected_instance.is_a?(::Aws::EC2::Instance) || expected_instance.is_a?(::Aws::EC2::Instance)
124
128
  case status
125
- when :available
129
+ when "available"
126
130
  attach(eni)
127
- when :in_use
131
+ when "in-use"
128
132
  # We don't want to attempt to reattach to the same instance or device index
129
133
  attachment = current_attachment(eni)
130
- if attachment.instance.id != expected_instance.id || (options[:device_index] && attachment.device_index != new_resource.device_index)
134
+ if attachment.instance_id != expected_instance.id || (options[:device_index] && attachment.device_index != new_resource.device_index)
131
135
  detach(eni)
132
136
  attach(eni)
133
137
  end
@@ -144,7 +148,7 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
144
148
  case status
145
149
  when nil
146
150
  Chef::Log.warn NetworkInterfaceNotFoundError.new(new_resource)
147
- when :in_use
151
+ when "in-use"
148
152
  detach(eni)
149
153
  end
150
154
  end
@@ -152,10 +156,9 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
152
156
  end
153
157
 
154
158
  def detach(eni)
155
- attachment = current_attachment(eni)
156
- instance = attachment.instance
159
+ attachment = current_attachment(eni)
157
160
 
158
- converge_by "detach #{new_resource} from #{instance.id}" do
161
+ converge_by "detach #{new_resource} from #{attachment.instance_id}" do
159
162
  eni.detach
160
163
  end
161
164
 
@@ -167,7 +170,7 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
167
170
 
168
171
  def attach(eni)
169
172
  converge_by "attach #{new_resource} to #{new_resource.machine} (#{expected_instance.id})" do
170
- eni.attach(expected_instance.id, options)
173
+ eni.attach(instance_id: expected_instance.id, device_index: options[:device_index])
171
174
  end
172
175
 
173
176
  converge_by "wait for #{new_resource} to attach" do
@@ -187,13 +190,15 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
187
190
 
188
191
  converge_by "wait for #{new_resource} in #{region} to delete" do
189
192
  log_callback = proc {
190
- Chef::Log.info('waiting for network interface to delete...')
193
+ Chef::Log.info("waiting for network interface to delete...")
191
194
  }
192
195
 
193
196
  Retryable.retryable(:tries => 30, :sleep => 2, :on => NetworkInterfaceStatusTimeoutError, :ensure => log_callback) do
194
- raise NetworkInterfaceStatusTimeoutError.new(new_resource, 'exists', 'deleted') if eni.exists?
197
+ result = new_resource.driver.ec2_resource.network_interface(eni.id) if eni.id
198
+ raise NetworkInterfaceStatusTimeoutError.new(new_resource, "exists", "deleted") if new_resource.exists?(result)
195
199
  end
196
200
  eni
197
201
  end
198
202
  end
203
+
199
204
  end
@@ -122,6 +122,6 @@ class Chef::Provider::AwsRdsParameterGroup < Chef::Provisioning::AWSDriver::AWSP
122
122
  end
123
123
 
124
124
  def driver
125
- new_resource.driver.rds.client
125
+ new_resource.driver.rds
126
126
  end
127
127
  end
@@ -84,6 +84,6 @@ class Chef::Provider::AwsRdsSubnetGroup < Chef::Provisioning::AWSDriver::AWSProv
84
84
  end
85
85
 
86
86
  def driver
87
- new_resource.driver.rds.client
87
+ new_resource.driver.rds
88
88
  end
89
89
  end
@@ -135,15 +135,15 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
135
135
  def get_route_target(vpc, route_target)
136
136
  case route_target
137
137
  when :internet_gateway
138
- route_target = { internet_gateway: vpc.internet_gateways.first.id }
139
- if !route_target[:internet_gateway]
140
- raise "VPC #{new_resource.vpc} (#{vpc.id}) does not have an internet gateway to route to! Use `internet_gateway true` on the VPC itself to create one."
138
+ if vpc.internet_gateways.first.nil?
139
+ raise "VPC #{new_resource.vpc} (#{vpc.id}) does not have an internet gateway to route to! Use `internet_gateway true` on the VPC itself to create one."
141
140
  end
142
- when /^igw-[A-Fa-f0-9]{8}$/, Chef::Resource::AwsInternetGateway, AWS::EC2::InternetGateway
141
+ route_target = { internet_gateway: vpc.internet_gateways.first.id }
142
+ when /^igw-[A-Fa-f0-9]{8}$/, Chef::Resource::AwsInternetGateway, ::Aws::EC2::InternetGateway
143
143
  route_target = { internet_gateway: route_target }
144
- when /^nat-[A-Fa-f0-9]{17}$/, Chef::Resource::AwsNatGateway, Aws::EC2::NatGateway
144
+ when /^nat-[A-Fa-f0-9]{17}$/, Chef::Resource::AwsNatGateway, ::Aws::EC2::NatGateway
145
145
  route_target = { nat_gateway: route_target }
146
- when /^eni-[A-Fa-f0-9]{8}$/, Chef::Resource::AwsNetworkInterface, AWS::EC2::NetworkInterface
146
+ when /^eni-[A-Fa-f0-9]{8}$/, Chef::Resource::AwsNetworkInterface, ::Aws::EC2::NetworkInterface
147
147
  route_target = { network_interface: route_target }
148
148
  when /^pcx-[A-Fa-f0-9]{8}$/, Chef::Resource::AwsVpcPeeringConnection, ::Aws::EC2::VpcPeeringConnection
149
149
  route_target = { vpc_peering_connection: route_target }
@@ -153,7 +153,7 @@ class Chef::Provider::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSProvider
153
153
  route_target = { instance: route_target }
154
154
  when Chef::Resource::Machine
155
155
  route_target = { instance: route_target.name }
156
- when AWS::EC2::Instance, ::Aws::EC2::Instance
156
+ when ::Aws::EC2::Instance, ::Aws::EC2::Instance
157
157
  route_target = { instance: route_target.id }
158
158
  when Hash
159
159
  if route_target.size != 1
@@ -26,21 +26,19 @@ class Chef::Provider::AwsS3Bucket < Chef::Provisioning::AWSDriver::AWSProvider
26
26
  bucket = super
27
27
 
28
28
  if new_resource.enable_website_hosting
29
- if !bucket.website?
29
+ if !website_exist?(new_resource,bucket)
30
30
  converge_by "enable website configuration for bucket #{new_resource.name}" do
31
- bucket.website_configuration = AWS::S3::WebsiteConfiguration.new(
32
- new_resource.website_options)
31
+ create_website(bucket,new_resource )
33
32
  end
34
33
  elsif modifies_website_configuration?(bucket)
35
34
  converge_by "reconfigure website configuration for bucket #{new_resource.name} to #{new_resource.website_options}" do
36
- bucket.website_configuration = AWS::S3::WebsiteConfiguration.new(
37
- new_resource.website_options)
35
+ create_website(bucket,new_resource )
38
36
  end
39
37
  end
40
38
  else
41
- if bucket.website?
39
+ if website_exist?(new_resource,bucket)
42
40
  converge_by "disable website configuration for bucket #{new_resource.name}" do
43
- bucket.website_configuration = nil
41
+ new_resource.driver.s3_client.delete_bucket_website(bucket: new_resource.name)
44
42
  end
45
43
  end
46
44
  end
@@ -50,7 +48,8 @@ class Chef::Provider::AwsS3Bucket < Chef::Provisioning::AWSDriver::AWSProvider
50
48
 
51
49
  def create_aws_object
52
50
  converge_by "create S3 bucket #{new_resource.name}" do
53
- new_resource.driver.s3.buckets.create(new_resource.name, new_resource.options)
51
+ options = new_resource.options.merge({bucket: new_resource.name})
52
+ new_resource.driver.s3_client.create_bucket(options)
54
53
  # S3 buckets already have a top level name property so they don't need
55
54
  # a 'Name' tag
56
55
  end
@@ -74,17 +73,30 @@ class Chef::Provider::AwsS3Bucket < Chef::Provisioning::AWSDriver::AWSProvider
74
73
 
75
74
  private
76
75
 
76
+ def website_exist?(new_resource,bucket)
77
+ return true if new_resource.driver.s3_client.get_bucket_website(bucket: new_resource.name)
78
+ rescue Aws::S3::Errors::NoSuchWebsiteConfiguration
79
+ return false
80
+ end
81
+
82
+ def create_website(bucket,new_resource )
83
+ website_configuration = Aws::S3::Types::WebsiteConfiguration.new(
84
+ new_resource.website_options)
85
+ s3_client = new_resource.driver.s3_client
86
+ s3_client.put_bucket_website( bucket: new_resource.name, website_configuration:website_configuration)
87
+ end
88
+
77
89
  def modifies_website_configuration?(aws_object)
78
90
  # This is incomplete, routing rules have many optional values, so its
79
91
  # possible aws will put in default values for those which won't be in
80
92
  # the requested config.
81
93
  new_web_config = new_resource.website_options || {}
82
94
 
83
- current_web_config = (aws_object.website_configuration || {}).to_hash
95
+ current_web_config = (aws_object.website.data || {}).to_hash
84
96
 
85
- (current_web_config[:index_document] != new_web_config.fetch(:index_document, {}) ||
86
- current_web_config[:error_document] != new_web_config.fetch(:error_document, {}) ||
87
- current_web_config[:routing_rules] != new_web_config.fetch(:routing_rules, []))
97
+ (current_web_config[:index_document] != new_web_config.fetch(:index_document, nil) ||
98
+ current_web_config[:error_document] != new_web_config.fetch(:error_document, nil) ||
99
+ current_web_config[:routing_rules] != new_web_config.fetch(:routing_rules, nil))
88
100
  end
89
101
 
90
102
  def s3_website_endpoint_region
@@ -18,14 +18,18 @@ class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvi
18
18
 
19
19
  def create_aws_object
20
20
  converge_by "create security group #{new_resource.name} in #{region}" do
21
- options = { description: new_resource.description }
22
- options[:vpc] = new_resource.vpc if new_resource.vpc
21
+ options = { description: new_resource.description.to_s }
22
+ options[:vpc_id] = new_resource.vpc if new_resource.vpc
23
+ options[:group_name] = new_resource.name
24
+ if options[:description].nil? or options[:description]==""
25
+ options[:description] = new_resource.name.to_s
26
+ end
23
27
  options = AWSResource.lookup_options(options, resource: new_resource)
24
- Chef::Log.debug("VPC: #{options[:vpc]}")
28
+ Chef::Log.debug("VPC: #{options[:vpc_id]}")
25
29
 
26
- sg = new_resource.driver.ec2.security_groups.create(new_resource.name, options)
27
- retry_with_backoff(AWS::EC2::Errors::InvalidSecurityGroupsID::NotFound, AWS::EC2::Errors::InvalidGroup::NotFound) do
28
- sg.tags['Name'] = new_resource.name
30
+ sg = new_resource.driver.ec2_resource.create_security_group(options)
31
+ retry_with_backoff(::Aws::EC2::Errors::InvalidSecurityGroupsIDNotFound, ::Aws::EC2::Errors::InvalidGroupNotFound) do
32
+ new_resource.driver.ec2_resource.create_tags(resources: [sg.id],tags: [{key: "Name", value: new_resource.name}])
29
33
  end
30
34
  sg
31
35
  end
@@ -46,14 +50,14 @@ class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvi
46
50
 
47
51
  def destroy_aws_object(sg)
48
52
  converge_by "delete security group #{new_resource.to_s} in #{region}" do
49
- sg.delete
53
+ sg.delete({ dry_run: false })
50
54
  end
51
55
  end
52
56
 
53
57
  private
54
58
 
55
59
  def apply_rules(sg)
56
- vpc = sg.vpc
60
+ vpc = sg.vpc_id
57
61
  if !new_resource.outbound_rules.nil?
58
62
  update_outbound_rules(sg, vpc)
59
63
  end
@@ -89,19 +93,98 @@ class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvi
89
93
  #
90
94
  # Actually update the rules (remove, add)
91
95
  #
92
- update_rules(desired_rules, sg.ip_permissions_list,
93
-
96
+ update_rules(desired_rules, sg.ip_permissions,
94
97
  authorize: proc do |port_range, protocol, actors|
95
98
  names = actors.map { |a| a.is_a?(Hash) ? a[:group_id] : a }
96
99
  converge_by "authorize #{names.join(', ')} to send traffic to group #{new_resource.name} (#{sg.id}) on port_range #{port_range.inspect} with protocol #{protocol || 'nil'}" do
97
- sg.authorize_ingress(protocol, port_range, *actors)
100
+ names.each do |iprange|
101
+ begin
102
+ if iprange.include?('-')
103
+ # user_id_group_pairs allows to add inbound rules for source security group
104
+ sg.authorize_ingress({
105
+ ip_permissions: [{
106
+ ip_protocol: protocol,
107
+ from_port: port_range.first,
108
+ to_port: port_range.last,
109
+ user_id_group_pairs: actors
110
+ }]
111
+ })
112
+ =begin
113
+ sg.authorize_ingress({
114
+ group
115
+ ip_permissions: [{
116
+ ip_protocol: protocol,
117
+ from_port: port_range.first,
118
+ to_port: port_range.last,
119
+ prefix_list_ids: [{
120
+ prefix_list_id: iprange
121
+ }]
122
+ }]
123
+ })
124
+ =end
125
+ else
126
+ sg.authorize_ingress({
127
+ ip_permissions: [{
128
+ ip_protocol: protocol,
129
+ from_port: port_range.first,
130
+ to_port: port_range.last,
131
+ ip_ranges: [{
132
+ cidr_ip: iprange
133
+ }]
134
+ }]
135
+ })
136
+ end
137
+ rescue ::Aws::EC2::Errors::InvalidPermissionDuplicate => e
138
+ Chef::Log.debug("Ignoring duplicate permission")
139
+ end
140
+ end
98
141
  end
99
142
  end,
100
143
 
101
144
  revoke: proc do |port_range, protocol, actors|
102
145
  names = actors.map { |a| a.is_a?(Hash) ? a[:group_id] : a }
103
146
  converge_by "revoke the ability of #{names.join(', ')} to send traffic to group #{new_resource.name} (#{sg.id}) on port_range #{port_range.inspect} with protocol #{protocol || 'nil'}" do
104
- sg.revoke_ingress(protocol, port_range, *actors)
147
+ names.each do |iprange|
148
+ begin
149
+ if iprange.include?('-')
150
+ # user_id_group_pairs allows to revoke inbound rules for source security group
151
+ sg.revoke_ingress({
152
+ ip_permissions: [{
153
+ ip_protocol: protocol,
154
+ from_port: port_range.first,
155
+ to_port: port_range.last,
156
+ user_id_group_pairs: actors
157
+ }]
158
+ })
159
+ =begin
160
+ sg.revoke_ingress({
161
+ group
162
+ ip_permissions: [{
163
+ ip_protocol: protocol,
164
+ from_port: port_range.first,
165
+ to_port: port_range.last,
166
+ prefix_list_ids: [{
167
+ prefix_list_id: iprange
168
+ }]
169
+ }]
170
+ })
171
+ =end
172
+ else
173
+ sg.revoke_ingress({
174
+ ip_permissions: [{
175
+ ip_protocol: protocol,
176
+ from_port: port_range.first,
177
+ to_port: port_range.last,
178
+ ip_ranges: [{
179
+ cidr_ip: iprange
180
+ }]
181
+ }]
182
+ })
183
+ end
184
+ rescue ::Aws::EC2::Errors::InvalidPermissionNotFound => e
185
+ Chef::Log.debug("Ignoring missing permission")
186
+ end
187
+ end
105
188
  end
106
189
  end
107
190
  )
@@ -132,19 +215,100 @@ class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvi
132
215
  #
133
216
  # Actually update the rules (remove, add)
134
217
  #
135
- update_rules(desired_rules, sg.ip_permissions_list_egress,
218
+ Chef::Log.info("dr: #{desired_rules}")
219
+ update_rules(desired_rules, sg.ip_permissions_egress,
136
220
 
137
221
  authorize: proc do |port_range, protocol, actors|
222
+ Chef::Log.info("proto: #{protocol.inspect}")
223
+ Chef::Log.info("port_range: #{port_range.inspect}")
138
224
  names = actors.map { |a| a.is_a?(Hash) ? a[:group_id] : a }
139
225
  converge_by "authorize group #{new_resource.name} (#{sg.id}) to send traffic to #{names.join(', ')} on port_range #{port_range.inspect} with protocol #{protocol || 'nil'}" do
140
- sg.authorize_egress(*actors, ports: port_range, protocol: protocol)
226
+ names.each do |iprange|
227
+ begin
228
+ if iprange.include?('-')
229
+ sg.authorize_egress({
230
+ ip_permissions: [{
231
+ ip_protocol: protocol,
232
+ from_port: port_range.first,
233
+ to_port: port_range.last,
234
+ user_id_group_pairs: actors
235
+ }]
236
+ })
237
+ =begin
238
+ sg.authorize_egress({
239
+ group
240
+ ip_permissions: [{
241
+ ip_protocol: protocol,
242
+ from_port: port_range.first,
243
+ to_port: port_range.last,
244
+ prefix_list_ids: [{
245
+ prefix_list_id: iprange
246
+ }]
247
+ }]
248
+ })
249
+ =end
250
+ else
251
+ sg.authorize_egress({
252
+ ip_permissions: [{
253
+ ip_protocol: protocol,
254
+ from_port: port_range.first,
255
+ to_port: port_range.last,
256
+ ip_ranges: [{
257
+ cidr_ip: iprange
258
+ }]
259
+ }]
260
+ })
261
+ end
262
+ rescue ::Aws::EC2::Errors::InvalidPermissionDuplicate => e
263
+ Chef::Log.debug("Ignoring duplicate permission")
264
+ end
265
+ end
141
266
  end
142
267
  end,
143
268
 
144
269
  revoke: proc do |port_range, protocol, actors|
145
270
  names = actors.map { |a| a.is_a?(Hash) ? a[:group_id] : a }
146
271
  converge_by "revoke the ability of group #{new_resource.name} (#{sg.id}) to send traffic to #{names.join(', ')} on port_range #{port_range.inspect} with protocol #{protocol || 'nil'}" do
147
- sg.revoke_egress(*actors, ports: port_range, protocol: protocol)
272
+ names.each do |iprange|
273
+ begin
274
+ if iprange.include?('-')
275
+ sg.revoke_egress({
276
+ ip_permissions: [{
277
+ ip_protocol: protocol,
278
+ from_port: port_range.first,
279
+ to_port: port_range.last,
280
+ user_id_group_pairs: actors
281
+ }]
282
+ })
283
+ =begin
284
+ sg.revoke_egress({
285
+ group
286
+ ip_permissions: [{
287
+ ip_protocol: protocol,
288
+ from_port: port_range.first,
289
+ to_port: port_range.last,
290
+ prefix_list_ids: [{
291
+ prefix_list_id: iprange
292
+ }]
293
+ }]
294
+ })
295
+ =end
296
+ else
297
+ sg.revoke_egress({
298
+ ip_permissions: [{
299
+ ip_protocol: protocol,
300
+ from_port: port_range.first,
301
+ to_port: port_range.last,
302
+ ip_ranges: [{
303
+ cidr_ip: iprange
304
+ }]
305
+ }]
306
+ })
307
+ end
308
+ rescue ::Aws::EC2::Errors::InvalidPermissionNotFound => e
309
+ Chef::Log.debug("Ignoring missing permission")
310
+ end
311
+ end
148
312
  end
149
313
  end
150
314
  )
@@ -153,12 +317,13 @@ class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvi
153
317
  def update_rules(desired_rules, actual_rules_list, authorize: nil, revoke: nil)
154
318
  actual_rules = {}
155
319
  actual_rules_list.each do |rule|
320
+ rule = rule.to_h
156
321
  port_range = {
157
322
  port_range: rule[:from_port] ? rule[:from_port]..rule[:to_port] : -1..-1,
158
323
  protocol: rule[:ip_protocol].to_s.to_sym
159
324
  }
160
- rule[:groups].map! { |h| h.select{|x| x != :group_name } } if rule[:groups]
161
- add_rule(actual_rules, [ port_range ], rule[:groups]) if rule[:groups]
325
+ rule[:user_id_group_pairs].map! { |h| h.select { |x| x != :group_name} }
326
+ add_rule(actual_rules, [ port_range ], rule[:user_id_group_pairs]) if rule[:user_id_group_pairs]
162
327
  add_rule(actual_rules, [ port_range ], rule[:ip_ranges].map { |r| r[:cidr_ip] }) if rule[:ip_ranges]
163
328
  end
164
329
 
@@ -244,7 +409,7 @@ class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvi
244
409
  end
245
410
 
246
411
  #
247
- # Turns an actor_spec into a uniform array, containing CIDRs, AWS::EC2::LoadBalancers and AWS::EC2::SecurityGroups.
412
+ # Turns an actor_spec into a uniform array, containing CIDRs, ::Aws::EC2::LoadBalancers and ::Aws::EC2::SecurityGroups.
248
413
  #
249
414
  def get_actors(vpc, actor_spec)
250
415
  result = case actor_spec
@@ -258,9 +423,11 @@ class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvi
258
423
  # The default AWS Ruby SDK form with :user_id, :group_id and :group_name forms
259
424
  if actor_spec.keys.all? { |key| [ :user_id, :group_id, :group_name ].include?(key) }
260
425
  if actor_spec.has_key?(:group_name)
261
- actor_spec[:group_id] ||= vpc.security_groups.filter('group-name', actor_spec[:group_name]).first.id
426
+ vpc_object = Chef::Resource::AwsVpc.get_aws_object(vpc, resource: new_resource)
427
+ actor_spec[:group_id] ||= vpc_object.security_groups({filters: [name: "group-name", values: [actor_spec[:group_name]]]}).first.id
262
428
  end
263
429
  actor_spec[:user_id] ||= new_resource.driver.account_id
430
+
264
431
  { user_id: actor_spec[:user_id], group_id: actor_spec[:group_id] }
265
432
 
266
433
  # load_balancer: <load balancer name>
@@ -277,12 +444,22 @@ class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvi
277
444
  end
278
445
 
279
446
  # If a load balancer is specified, grab it and then get its automatic security group
280
- when /^elb-[a-fA-F0-9]{8}$/, AWS::ELB::LoadBalancer, Chef::Resource::AwsLoadBalancer
281
- lb = Chef::Resource::AwsLoadBalancer.get_aws_object(actor_spec, resource: new_resource)
282
- get_actors(vpc, lb.source_security_group)
447
+ when /^elb-[a-fA-F0-9]{8}$/, Aws::ElasticLoadBalancing::Types::LoadBalancerDescription, Chef::Resource::AwsLoadBalancer
448
+ lb=actor_spec
449
+ if lb.class != Aws::ElasticLoadBalancing::Types::LoadBalancerDescription
450
+ lb = Chef::Resource::AwsLoadBalancer.get_aws_object(actor_spec, resource: new_resource)
451
+ end
452
+ # get secgroup via vpc_id
453
+ vpc_object = Chef::Resource::AwsVpc.get_aws_object(vpc, resource: new_resource)
454
+ results = vpc_object.security_groups.to_a.select { |s| s.group_name == lb.source_security_group.group_name }
455
+ if results.size == 1
456
+ get_actors(vpc, results.first.id)
457
+ else
458
+ raise ::Chef::Provisioning::AWSDriver::Exceptions::MultipleSecurityGroupError.new(lb.source_security_group.group_name, results)
459
+ end
283
460
 
284
461
  # If a security group is specified, grab it
285
- when /^sg-[a-fA-F0-9]{8}$/, AWS::EC2::SecurityGroup, Chef::Resource::AwsSecurityGroup
462
+ when /^sg-[a-fA-F0-9]{8}$/, ::Aws::EC2::SecurityGroup, Chef::Resource::AwsSecurityGroup
286
463
  Chef::Resource::AwsSecurityGroup.get_aws_object(actor_spec, resource: new_resource)
287
464
 
288
465
  # If an IP addresses / CIDR are passed, return it verbatim; otherwise, assume it's the
@@ -297,10 +474,10 @@ class Chef::Provider::AwsSecurityGroup < Chef::Provisioning::AWSDriver::AWSProvi
297
474
  end
298
475
 
299
476
  else
300
- raise "Unexpected actor #{actor_spec} in rules list"
477
+ raise "Unexpected actor #{actor_spec} / #{actor_spec.class} in rules list"
301
478
  end
302
479
 
303
- result = { user_id: result.owner_id, group_id: result.id } if result.is_a?(AWS::EC2::SecurityGroup)
480
+ result = { user_id: result.owner_id, group_id: result.id } if result.is_a?(::Aws::EC2::SecurityGroup)
304
481
 
305
482
  [ result ].flatten
306
483
  end