chef-provisioning-aws 2.2.2 → 3.0.0.pre.rc1
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/chef-provisioning-aws.gemspec +0 -1
- data/lib/chef/provider/aws_auto_scaling_group.rb +9 -6
- data/lib/chef/provider/aws_dhcp_options.rb +21 -11
- data/lib/chef/provider/aws_ebs_volume.rb +26 -24
- data/lib/chef/provider/aws_eip_address.rb +11 -12
- data/lib/chef/provider/aws_image.rb +1 -1
- data/lib/chef/provider/aws_internet_gateway.rb +18 -10
- data/lib/chef/provider/aws_key_pair.rb +6 -6
- data/lib/chef/provider/aws_launch_configuration.rb +7 -9
- data/lib/chef/provider/aws_nat_gateway.rb +2 -2
- data/lib/chef/provider/aws_network_acl.rb +11 -8
- data/lib/chef/provider/aws_network_interface.rb +34 -29
- data/lib/chef/provider/aws_rds_parameter_group.rb +1 -1
- data/lib/chef/provider/aws_rds_subnet_group.rb +1 -1
- data/lib/chef/provider/aws_route_table.rb +7 -7
- data/lib/chef/provider/aws_s3_bucket.rb +24 -12
- data/lib/chef/provider/aws_security_group.rb +202 -25
- data/lib/chef/provider/aws_server_certificate.rb +3 -4
- data/lib/chef/provider/aws_sns_topic.rb +4 -3
- data/lib/chef/provider/aws_sqs_queue.rb +7 -3
- data/lib/chef/provider/aws_subnet.rb +45 -21
- data/lib/chef/provider/aws_vpc.rb +59 -30
- data/lib/chef/provisioning/aws_driver/aws_provider.rb +12 -3
- data/lib/chef/provisioning/aws_driver/aws_resource.rb +2 -2
- data/lib/chef/provisioning/aws_driver/aws_resource_with_entry.rb +1 -1
- data/lib/chef/provisioning/aws_driver/aws_tagger.rb +2 -2
- data/lib/chef/provisioning/aws_driver/credentials.rb +1 -1
- data/lib/chef/provisioning/aws_driver/credentials2.rb +5 -1
- data/lib/chef/provisioning/aws_driver/driver.rb +124 -34
- data/lib/chef/provisioning/aws_driver/tagging_strategy/rds.rb +4 -4
- data/lib/chef/provisioning/aws_driver/tagging_strategy/s3.rb +1 -1
- data/lib/chef/provisioning/aws_driver/version.rb +1 -1
- data/lib/chef/resource/aws_auto_scaling_group.rb +2 -2
- data/lib/chef/resource/aws_cache_cluster.rb +4 -4
- data/lib/chef/resource/aws_cache_replication_group.rb +3 -3
- data/lib/chef/resource/aws_cache_subnet_group.rb +4 -4
- data/lib/chef/resource/aws_cloudsearch_domain.rb +1 -1
- data/lib/chef/resource/aws_cloudwatch_alarm.rb +1 -1
- data/lib/chef/resource/aws_dhcp_options.rb +10 -3
- data/lib/chef/resource/aws_ebs_volume.rb +10 -4
- data/lib/chef/resource/aws_eip_address.rb +4 -4
- data/lib/chef/resource/aws_elasticsearch_domain.rb +1 -1
- data/lib/chef/resource/aws_iam_role.rb +1 -1
- data/lib/chef/resource/aws_internet_gateway.rb +11 -4
- data/lib/chef/resource/aws_key_pair.rb +4 -3
- data/lib/chef/resource/aws_launch_configuration.rb +5 -4
- data/lib/chef/resource/aws_load_balancer.rb +14 -3
- data/lib/chef/resource/aws_nat_gateway.rb +2 -2
- data/lib/chef/resource/aws_network_acl.rb +10 -10
- data/lib/chef/resource/aws_network_interface.rb +12 -6
- data/lib/chef/resource/aws_rds_parameter_group.rb +6 -6
- data/lib/chef/resource/aws_rds_subnet_group.rb +4 -5
- data/lib/chef/resource/aws_route53_record_set.rb +1 -1
- data/lib/chef/resource/aws_route_table.rb +1 -1
- data/lib/chef/resource/aws_s3_bucket.rb +3 -2
- data/lib/chef/resource/aws_security_group.rb +6 -6
- data/lib/chef/resource/aws_server_certificate.rb +4 -5
- data/lib/chef/resource/aws_sns_topic.rb +4 -4
- data/lib/chef/resource/aws_sqs_queue.rb +3 -3
- data/lib/chef/resource/aws_subnet.rb +5 -5
- data/lib/chef/resource/aws_vpc.rb +12 -6
- data/lib/chef/resource/aws_vpc_peering_connection.rb +2 -2
- data/spec/aws_support.rb +12 -9
- data/spec/aws_support/deep_matcher/match_values_failure_messages.rb +15 -5
- data/spec/integration/aws_dhcp_options_spec.rb +7 -7
- data/spec/integration/aws_ebs_volume_spec.rb +1 -1
- data/spec/integration/aws_internet_gateway_spec.rb +19 -18
- data/spec/integration/aws_key_pair_spec.rb +1 -1
- data/spec/integration/aws_nat_gateway_spec.rb +3 -6
- data/spec/integration/aws_network_acl_spec.rb +19 -11
- data/spec/integration/aws_network_interface_spec.rb +26 -20
- data/spec/integration/aws_rds_instance_spec.rb +6 -7
- data/spec/integration/aws_rds_subnet_group_spec.rb +6 -6
- data/spec/integration/aws_route53_hosted_zone_spec.rb +1 -1
- data/spec/integration/aws_s3_bucket_spec.rb +1 -2
- data/spec/integration/aws_security_group_spec.rb +272 -198
- data/spec/integration/aws_server_certificate_spec.rb +60 -78
- data/spec/integration/aws_subnet_spec.rb +8 -4
- data/spec/integration/aws_vpc_spec.rb +29 -23
- data/spec/integration/machine_spec.rb +1 -1
- data/spec/unit/chef/provisioning/aws_driver/credentials_spec.rb +13 -0
- data/spec/unit/chef/provisioning/aws_driver/driver_spec.rb +1 -1
- data/spec/unit/chef/provisioning/aws_driver/route53_spec.rb +1 -1
- metadata +5 -20
- 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,
|
|
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,
|
|
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[:
|
|
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[:
|
|
24
|
+
Chef::Log.debug("VPC: #{options[:vpc_id]}")
|
|
25
25
|
|
|
26
|
-
network_acl = new_resource.driver.
|
|
27
|
-
retry_with_backoff(
|
|
28
|
-
network_acl.tags[
|
|
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(
|
|
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, :
|
|
129
|
-
:port_range, :
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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?(:
|
|
51
|
-
if Chef::Resource::AwsSubnet.get_aws_object(options[:
|
|
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?(:
|
|
75
|
-
groups = new_resource.security_groups
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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.
|
|
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 ==
|
|
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[:
|
|
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[:
|
|
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?(
|
|
127
|
+
if expected_instance.is_a?(::Aws::EC2::Instance) || expected_instance.is_a?(::Aws::EC2::Instance)
|
|
124
128
|
case status
|
|
125
|
-
when
|
|
129
|
+
when "available"
|
|
126
130
|
attach(eni)
|
|
127
|
-
when
|
|
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.
|
|
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
|
|
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
|
|
156
|
-
instance = attachment.instance
|
|
159
|
+
attachment = current_attachment(eni)
|
|
157
160
|
|
|
158
|
-
converge_by "detach #{new_resource} from #{
|
|
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(
|
|
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
|
-
|
|
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
|
|
@@ -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
|
-
|
|
139
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
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
|
-
|
|
29
|
+
if !website_exist?(new_resource,bucket)
|
|
30
30
|
converge_by "enable website configuration for bucket #{new_resource.name}" do
|
|
31
|
-
bucket
|
|
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
|
|
37
|
-
new_resource.website_options)
|
|
35
|
+
create_website(bucket,new_resource )
|
|
38
36
|
end
|
|
39
37
|
end
|
|
40
38
|
else
|
|
41
|
-
if bucket
|
|
39
|
+
if website_exist?(new_resource,bucket)
|
|
42
40
|
converge_by "disable website configuration for bucket #{new_resource.name}" do
|
|
43
|
-
bucket.
|
|
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.
|
|
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.
|
|
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[:
|
|
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[:
|
|
28
|
+
Chef::Log.debug("VPC: #{options[:vpc_id]}")
|
|
25
29
|
|
|
26
|
-
sg = new_resource.driver.
|
|
27
|
-
retry_with_backoff(
|
|
28
|
-
sg.tags[
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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[:
|
|
161
|
-
add_rule(actual_rules, [ port_range ], rule[:
|
|
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,
|
|
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
|
-
|
|
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}$/,
|
|
281
|
-
lb
|
|
282
|
-
|
|
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}$/,
|
|
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?(
|
|
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
|