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.
- checksums.yaml +4 -4
- data/README.md +70 -69
- data/Rakefile +22 -2
- data/lib/chef/provider/aws_auto_scaling_group.rb +3 -2
- data/lib/chef/provider/aws_cache_cluster.rb +3 -2
- data/lib/chef/provider/aws_cache_replication_group.rb +5 -4
- data/lib/chef/provider/aws_cache_subnet_group.rb +5 -4
- data/lib/chef/provider/aws_cloudsearch_domain.rb +163 -0
- data/lib/chef/provider/aws_dhcp_options.rb +9 -6
- data/lib/chef/provider/aws_ebs_volume.rb +7 -3
- data/lib/chef/provider/aws_eip_address.rb +8 -7
- data/lib/chef/provider/aws_image.rb +8 -3
- data/lib/chef/provider/aws_instance.rb +14 -2
- data/lib/chef/provider/aws_key_pair.rb +2 -1
- data/lib/chef/provider/aws_launch_configuration.rb +4 -2
- data/lib/chef/provider/aws_load_balancer.rb +18 -0
- data/lib/chef/provider/aws_network_acl.rb +6 -2
- data/lib/chef/provider/aws_network_interface.rb +11 -24
- data/lib/chef/provider/aws_rds_instance.rb +66 -0
- data/lib/chef/provider/aws_rds_subnet_group.rb +89 -0
- data/lib/chef/provider/aws_route_table.rb +42 -23
- data/lib/chef/provider/aws_s3_bucket.rb +32 -8
- data/lib/chef/provider/aws_security_group.rb +11 -4
- data/lib/chef/provider/aws_server_certificate.rb +23 -0
- data/lib/chef/provider/aws_sns_topic.rb +4 -3
- data/lib/chef/provider/aws_sqs_queue.rb +3 -2
- data/lib/chef/provider/aws_subnet.rb +10 -7
- data/lib/chef/provider/aws_vpc.rb +54 -21
- data/lib/chef/provider/aws_vpc_peering_connection.rb +88 -0
- data/lib/chef/provisioning/aws_driver.rb +8 -0
- data/lib/chef/provisioning/aws_driver/aws_provider.rb +45 -76
- data/lib/chef/provisioning/aws_driver/aws_rds_resource.rb +11 -0
- data/lib/chef/provisioning/aws_driver/aws_resource.rb +14 -2
- data/lib/chef/provisioning/aws_driver/aws_resource_with_entry.rb +2 -8
- data/lib/chef/provisioning/aws_driver/aws_taggable.rb +18 -0
- data/lib/chef/provisioning/aws_driver/aws_tagger.rb +61 -0
- data/lib/chef/provisioning/aws_driver/credentials2.rb +51 -0
- data/lib/chef/provisioning/aws_driver/driver.rb +214 -162
- data/lib/chef/provisioning/aws_driver/tagging_strategy/ec2.rb +64 -0
- data/lib/chef/provisioning/aws_driver/tagging_strategy/elb.rb +39 -0
- data/lib/chef/provisioning/aws_driver/tagging_strategy/rds.rb +92 -0
- data/lib/chef/provisioning/aws_driver/tagging_strategy/s3.rb +41 -0
- data/lib/chef/provisioning/aws_driver/version.rb +1 -1
- data/lib/chef/resource/aws_cache_cluster.rb +1 -2
- data/lib/chef/resource/aws_cloudsearch_domain.rb +46 -0
- data/lib/chef/resource/aws_dhcp_options.rb +2 -0
- data/lib/chef/resource/aws_ebs_volume.rb +3 -1
- data/lib/chef/resource/aws_eip_address.rb +0 -3
- data/lib/chef/resource/aws_image.rb +3 -0
- data/lib/chef/resource/aws_instance.rb +7 -2
- data/lib/chef/resource/aws_internet_gateway.rb +2 -0
- data/lib/chef/resource/aws_load_balancer.rb +3 -0
- data/lib/chef/resource/aws_network_acl.rb +2 -0
- data/lib/chef/resource/aws_network_interface.rb +3 -1
- data/lib/chef/resource/aws_rds_instance.rb +42 -0
- data/lib/chef/resource/aws_rds_subnet_group.rb +29 -0
- data/lib/chef/resource/aws_route_table.rb +7 -5
- data/lib/chef/resource/aws_s3_bucket.rb +3 -0
- data/lib/chef/resource/aws_security_group.rb +2 -7
- data/lib/chef/resource/aws_server_certificate.rb +21 -0
- data/lib/chef/resource/aws_subnet.rb +2 -0
- data/lib/chef/resource/aws_vpc.rb +4 -1
- data/lib/chef/resource/aws_vpc_peering_connection.rb +73 -0
- data/spec/acceptance/aws_ebs_volume/nodes/ettores-mbp.lan.json +3 -0
- data/spec/aws_support.rb +25 -8
- data/spec/aws_support/aws_resource_run_wrapper.rb +5 -1
- data/spec/aws_support/deep_matcher/match_values_failure_messages.rb +19 -0
- data/spec/aws_support/matchers/create_an_aws_object.rb +1 -1
- data/spec/aws_support/matchers/destroy_an_aws_object.rb +1 -1
- data/spec/aws_support/matchers/have_aws_object_tags.rb +9 -15
- data/spec/aws_support/matchers/match_an_aws_object.rb +1 -1
- data/spec/aws_support/matchers/update_an_aws_object.rb +1 -1
- data/spec/integration/aws_cloudsearch_domain_spec.rb +31 -0
- data/spec/integration/aws_dhcp_options_spec.rb +73 -0
- data/spec/integration/aws_ebs_volume_spec.rb +97 -0
- data/spec/integration/aws_network_acl_spec.rb +51 -0
- data/spec/integration/aws_network_interface_spec.rb +89 -0
- data/spec/integration/aws_rds_instance_spec.rb +150 -0
- data/spec/integration/aws_rds_subnet_group_spec.rb +105 -0
- data/spec/integration/aws_route_table_spec.rb +94 -7
- data/spec/integration/aws_s3_bucket_spec.rb +88 -0
- data/spec/integration/aws_security_group_spec.rb +47 -0
- data/spec/integration/aws_server_certificate_spec.rb +24 -0
- data/spec/integration/aws_subnet_spec.rb +51 -2
- data/spec/integration/aws_vpc_peering_connection_spec.rb +99 -0
- data/spec/integration/aws_vpc_spec.rb +73 -0
- data/spec/integration/load_balancer_spec.rb +101 -0
- data/spec/integration/machine_image_spec.rb +61 -6
- data/spec/integration/machine_spec.rb +26 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/unit/{aws_driver → chef/provisioning/aws_driver}/credentials_spec.rb +0 -0
- data/spec/unit/chef/provisioning/aws_driver/driver_spec.rb +88 -0
- metadata +63 -20
- data/spec/integration/aws_tagged_items_spec.rb +0 -166
@@ -1,7 +1,10 @@
|
|
1
1
|
require 'chef/provisioning/aws_driver/aws_provider'
|
2
|
-
require 'retryable'
|
3
2
|
|
4
3
|
class Chef::Provider::AwsDhcpOptions < Chef::Provisioning::AWSDriver::AWSProvider
|
4
|
+
include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
|
5
|
+
|
6
|
+
provides :aws_dhcp_options
|
7
|
+
|
5
8
|
protected
|
6
9
|
|
7
10
|
def create_aws_object
|
@@ -10,7 +13,7 @@ class Chef::Provider::AwsDhcpOptions < Chef::Provisioning::AWSDriver::AWSProvide
|
|
10
13
|
options[:domain_name_servers] = "AmazonProvidedDNS"
|
11
14
|
end
|
12
15
|
|
13
|
-
converge_by "create
|
16
|
+
converge_by "create DHCP options #{new_resource.name} in #{region}" do
|
14
17
|
dhcp_options = new_resource.driver.ec2.dhcp_options.create(options)
|
15
18
|
retry_with_backoff(AWS::EC2::Errors::InvalidDhcpOptionsID::NotFound) do
|
16
19
|
dhcp_options.tags['Name'] = new_resource.name
|
@@ -35,17 +38,17 @@ class Chef::Provider::AwsDhcpOptions < Chef::Provisioning::AWSDriver::AWSProvide
|
|
35
38
|
if action_handler.should_perform_actions
|
36
39
|
dhcp_options = AWS.ec2(config: dhcp_options.config).dhcp_options.create(config.merge(desired_options))
|
37
40
|
end
|
38
|
-
action_handler.report_progress "create
|
41
|
+
action_handler.report_progress "create DHCP options #{dhcp_options.id} with new attributes in #{region}"
|
39
42
|
|
40
43
|
# attach dhcp_options to existing vpcs
|
41
44
|
old_dhcp_options.vpcs.each do |vpc|
|
42
|
-
action_handler.perform_action "attach
|
45
|
+
action_handler.perform_action "attach DHCP options #{dhcp_options.id} to vpc #{vpc.id}" do
|
43
46
|
vpc.dhcp_options = dhcp_options
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
47
50
|
# delete old dhcp_options
|
48
|
-
action_handler.perform_action "delete
|
51
|
+
action_handler.perform_action "delete DHCP options #{old_dhcp_options.id}" do
|
49
52
|
old_dhcp_options.delete
|
50
53
|
end
|
51
54
|
|
@@ -54,7 +57,7 @@ class Chef::Provider::AwsDhcpOptions < Chef::Provisioning::AWSDriver::AWSProvide
|
|
54
57
|
end
|
55
58
|
|
56
59
|
def destroy_aws_object(dhcp_options)
|
57
|
-
converge_by "delete
|
60
|
+
converge_by "delete DHCP options #{new_resource.name} in #{region}" do
|
58
61
|
dhcp_options.delete
|
59
62
|
end
|
60
63
|
end
|
@@ -4,6 +4,10 @@ require 'date'
|
|
4
4
|
require 'retryable'
|
5
5
|
|
6
6
|
class Chef::Provider::AwsEbsVolume < Chef::Provisioning::AWSDriver::AWSProvider
|
7
|
+
include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
|
8
|
+
|
9
|
+
provides :aws_ebs_volume
|
10
|
+
|
7
11
|
class VolumeNotFoundError < RuntimeError
|
8
12
|
def initialize(new_resource)
|
9
13
|
super("#{new_resource} does not exist!")
|
@@ -34,7 +38,7 @@ class Chef::Provider::AwsEbsVolume < Chef::Provisioning::AWSDriver::AWSProvider
|
|
34
38
|
|
35
39
|
def create_aws_object
|
36
40
|
volume = nil
|
37
|
-
converge_by "create
|
41
|
+
converge_by "create #{new_resource} in #{region}" do
|
38
42
|
volume = new_resource.driver.ec2.volumes.create(initial_options)
|
39
43
|
retry_with_backoff(AWS::EC2::Errors::InvalidVolumeID::NotFound) do
|
40
44
|
volume.tags['Name'] = new_resource.name
|
@@ -119,12 +123,12 @@ class Chef::Provider::AwsEbsVolume < Chef::Provisioning::AWSDriver::AWSProvider
|
|
119
123
|
#
|
120
124
|
# If we were told to attach the volume to a machine, do so
|
121
125
|
#
|
122
|
-
if expected_instance.is_a?(AWS::EC2::Instance)
|
126
|
+
if expected_instance.is_a?(AWS::EC2::Instance) || expected_instance.is_a?(::Aws::EC2::Instance)
|
123
127
|
case status
|
124
128
|
when :in_use
|
125
129
|
# We don't want to attempt to reattach to the same instance and device
|
126
130
|
attachment = current_attachment(volume)
|
127
|
-
if attachment.instance != expected_instance || attachment.device != new_resource.device
|
131
|
+
if attachment.instance.id != expected_instance.id || attachment.device != new_resource.device
|
128
132
|
detach(volume)
|
129
133
|
attach(volume)
|
130
134
|
end
|
@@ -4,6 +4,7 @@ require 'chef/provisioning/machine_spec'
|
|
4
4
|
require 'cheffish'
|
5
5
|
|
6
6
|
class Chef::Provider::AwsEipAddress < Chef::Provisioning::AWSDriver::AWSProvider
|
7
|
+
provides :aws_eip_address
|
7
8
|
|
8
9
|
def action_create
|
9
10
|
elastic_ip = super
|
@@ -16,10 +17,10 @@ class Chef::Provider::AwsEipAddress < Chef::Provisioning::AWSDriver::AWSProvider
|
|
16
17
|
protected
|
17
18
|
|
18
19
|
def create_aws_object
|
19
|
-
converge_by "create
|
20
|
+
converge_by "create Elastic IP address in #{region}" do
|
20
21
|
associate_to_vpc = new_resource.associate_to_vpc
|
21
22
|
if associate_to_vpc.nil?
|
22
|
-
if desired_instance.is_a?(AWS::EC2::Instance)
|
23
|
+
if desired_instance.is_a?(AWS::EC2::Instance) || desired_instance.is_a?(::Aws::EC2::Instance)
|
23
24
|
associate_to_vpc = !!desired_instance.vpc_id
|
24
25
|
Chef::Log.debug "Since associate_to_vpc is not specified and instance #{new_resource.machine} (#{desired_instance.id}) and #{associate_to_vpc ? "is" : "is not"} in a VPC, setting associate_to_vpc to #{associate_to_vpc}."
|
25
26
|
end
|
@@ -39,11 +40,11 @@ class Chef::Provider::AwsEipAddress < Chef::Provisioning::AWSDriver::AWSProvider
|
|
39
40
|
def destroy_aws_object(elastic_ip)
|
40
41
|
#if it's attached to something in a vpc, disassociate first
|
41
42
|
if elastic_ip.instance_id != nil && elastic_ip.domain == 'vpc'
|
42
|
-
converge_by "dissociate Elastic IP
|
43
|
+
converge_by "dissociate Elastic IP address #{new_resource.name} (#{elastic_ip.public_ip}) from #{elastic_ip.instance_id}" do
|
43
44
|
elastic_ip.disassociate
|
44
45
|
end
|
45
46
|
end
|
46
|
-
converge_by "delete Elastic IP
|
47
|
+
converge_by "delete Elastic IP address #{new_resource.name} (#{elastic_ip.public_ip}) in #{region}" do
|
47
48
|
elastic_ip.delete
|
48
49
|
end
|
49
50
|
end
|
@@ -65,9 +66,9 @@ class Chef::Provider::AwsEipAddress < Chef::Provisioning::AWSDriver::AWSProvider
|
|
65
66
|
#
|
66
67
|
# If we were told to associate the IP to a machine, do so
|
67
68
|
#
|
68
|
-
if desired_instance.is_a?(AWS::EC2::Instance)
|
69
|
+
if desired_instance.is_a?(AWS::EC2::Instance) || desired_instance.is_a?(::Aws::EC2::Instance)
|
69
70
|
if desired_instance.id != elastic_ip.instance_id
|
70
|
-
converge_by "associate Elastic IP
|
71
|
+
converge_by "associate Elastic IP address #{new_resource.name} (#{elastic_ip.public_ip}) with #{new_resource.machine} (#{desired_instance.id})" do
|
71
72
|
elastic_ip.associate instance: desired_instance.id
|
72
73
|
end
|
73
74
|
end
|
@@ -77,7 +78,7 @@ class Chef::Provider::AwsEipAddress < Chef::Provisioning::AWSDriver::AWSProvider
|
|
77
78
|
#
|
78
79
|
else
|
79
80
|
if elastic_ip.associated?
|
80
|
-
converge_by "disassociate Elastic IP
|
81
|
+
converge_by "disassociate Elastic IP address #{new_resource.name} (#{elastic_ip.public_ip}) from #{elastic_ip.instance_id} in #{region}" do
|
81
82
|
aws_object.disassociate
|
82
83
|
end
|
83
84
|
end
|
@@ -1,13 +1,18 @@
|
|
1
1
|
require 'chef/provisioning/aws_driver/aws_provider'
|
2
|
+
require 'chef/provisioning/aws_driver/tagging_strategy/ec2'
|
2
3
|
|
3
4
|
class Chef::Provider::AwsImage < Chef::Provisioning::AWSDriver::AWSProvider
|
5
|
+
include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
|
6
|
+
|
7
|
+
provides :aws_image
|
8
|
+
|
4
9
|
def destroy_aws_object(image)
|
5
|
-
instance_id = image.tags['
|
6
|
-
Chef::Log.debug("Found
|
10
|
+
instance_id = image.tags['from-instance']
|
11
|
+
Chef::Log.debug("Found from-instance tag [#{instance_id}] on #{image.id}")
|
7
12
|
unless instance_id
|
8
13
|
# This is an old image and doesn't have the tag added - lets try and find it from the block device mapping
|
9
14
|
image.block_device_mappings.map do |dev, opts|
|
10
|
-
snapshot = ec2.snapshots[opts[:snapshot_id]]
|
15
|
+
snapshot = new_resource.driver.ec2.snapshots[opts[:snapshot_id]]
|
11
16
|
desc = snapshot.description
|
12
17
|
m = /CreateImage\(([^\)]+)\)/.match(desc)
|
13
18
|
if m
|
@@ -1,6 +1,11 @@
|
|
1
1
|
require 'chef/provisioning/aws_driver/aws_provider'
|
2
|
+
require 'chef/provisioning/aws_driver/tagging_strategy/ec2'
|
2
3
|
|
3
4
|
class Chef::Provider::AwsInstance < Chef::Provisioning::AWSDriver::AWSProvider
|
5
|
+
include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
|
6
|
+
|
7
|
+
provides :aws_instance
|
8
|
+
|
4
9
|
def create_aws_object(instance); end
|
5
10
|
|
6
11
|
def update_aws_object(instance); end
|
@@ -10,12 +15,19 @@ class Chef::Provider::AwsInstance < Chef::Provisioning::AWSDriver::AWSProvider
|
|
10
15
|
message += " in VPC #{instance.vpc.id}" unless instance.vpc.nil?
|
11
16
|
message += " in #{region}"
|
12
17
|
converge_by message do
|
13
|
-
instance.
|
18
|
+
instance.terminate
|
14
19
|
end
|
15
20
|
converge_by "waited until instance #{new_resource} is :terminated" do
|
16
21
|
# When purging, we must wait until the instance is fully terminated - thats the only way
|
17
22
|
# to delete the network interface that I can see
|
18
|
-
|
23
|
+
instance.wait_until_terminated do |w|
|
24
|
+
# TODO look at `wait_for_status` - delay and max_attempts should be configurable
|
25
|
+
w.delay = 5
|
26
|
+
w.max_attempts = 60
|
27
|
+
w.before_wait do |attempts, response|
|
28
|
+
action_handler.report_progress "waited #{(attempts-1)*5}/#{60*5}s for #{instance.id} status to terminate..."
|
29
|
+
end
|
30
|
+
end
|
19
31
|
end
|
20
32
|
end
|
21
33
|
end
|
@@ -2,6 +2,8 @@ require 'chef/provisioning/aws_driver/aws_provider'
|
|
2
2
|
require 'chef/resource/aws_image'
|
3
3
|
|
4
4
|
class Chef::Provider::AwsLaunchConfiguration < Chef::Provisioning::AWSDriver::AWSProvider
|
5
|
+
provides :aws_launch_configuration
|
6
|
+
|
5
7
|
protected
|
6
8
|
|
7
9
|
def create_aws_object
|
@@ -9,7 +11,7 @@ class Chef::Provider::AwsLaunchConfiguration < Chef::Provisioning::AWSDriver::AW
|
|
9
11
|
instance_type = new_resource.instance_type || new_resource.driver.default_instance_type
|
10
12
|
options = AWSResource.lookup_options(new_resource.options || options, resource: new_resource)
|
11
13
|
|
12
|
-
converge_by "
|
14
|
+
converge_by "create launch configuration #{new_resource.name} in #{region}" do
|
13
15
|
new_resource.driver.auto_scaling.launch_configurations.create(
|
14
16
|
new_resource.name,
|
15
17
|
image,
|
@@ -35,7 +37,7 @@ class Chef::Provider::AwsLaunchConfiguration < Chef::Provisioning::AWSDriver::AW
|
|
35
37
|
end
|
36
38
|
|
37
39
|
def destroy_aws_object(launch_configuration)
|
38
|
-
converge_by "delete
|
40
|
+
converge_by "delete launch configuration #{new_resource.name} in #{region}" do
|
39
41
|
# TODO add a timeout here.
|
40
42
|
# TODO is InUse really a status guaranteed to go away??
|
41
43
|
begin
|
@@ -1,6 +1,24 @@
|
|
1
1
|
require 'chef/provisioning/aws_driver/aws_provider'
|
2
2
|
|
3
3
|
class Chef::Provider::AwsLoadBalancer < Chef::Provisioning::AWSDriver::AWSProvider
|
4
|
+
|
5
|
+
def aws_tagger
|
6
|
+
@aws_tagger ||= begin
|
7
|
+
elb_strategy = Chef::Provisioning::AWSDriver::TaggingStrategy::ELB.new(
|
8
|
+
new_resource.driver.elb_client,
|
9
|
+
new_resource.name,
|
10
|
+
new_resource.aws_tags
|
11
|
+
)
|
12
|
+
Chef::Provisioning::AWSDriver::AWSTagger.new(elb_strategy, action_handler)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def converge_tags
|
17
|
+
aws_tagger.converge_tags
|
18
|
+
end
|
19
|
+
|
20
|
+
provides :aws_load_balancer
|
21
|
+
|
4
22
|
def destroy_aws_object(load_balancer)
|
5
23
|
converge_by "delete load balancer #{new_resource.name} (#{load_balancer.name}) in #{region}" do
|
6
24
|
load_balancer.delete
|
@@ -3,6 +3,10 @@ require 'chef/resource/aws_vpc'
|
|
3
3
|
require 'retryable'
|
4
4
|
|
5
5
|
class Chef::Provider::AwsNetworkAcl < Chef::Provisioning::AWSDriver::AWSProvider
|
6
|
+
include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
|
7
|
+
|
8
|
+
provides :aws_network_acl
|
9
|
+
|
6
10
|
def action_create
|
7
11
|
network_acl = super
|
8
12
|
|
@@ -12,7 +16,7 @@ class Chef::Provider::AwsNetworkAcl < Chef::Provisioning::AWSDriver::AWSProvider
|
|
12
16
|
protected
|
13
17
|
|
14
18
|
def create_aws_object
|
15
|
-
converge_by "create
|
19
|
+
converge_by "create network ACL #{new_resource.name} in #{region}" do
|
16
20
|
options = {}
|
17
21
|
options[:vpc] = new_resource.vpc if new_resource.vpc
|
18
22
|
options = AWSResource.lookup_options(options, resource: new_resource)
|
@@ -87,7 +91,7 @@ class Chef::Provider::AwsNetworkAcl < Chef::Provisioning::AWSDriver::AWSProvider
|
|
87
91
|
end
|
88
92
|
|
89
93
|
unless replace_rules.empty? && desired_rules.empty? && current_rules.empty?
|
90
|
-
action_handler.report_progress "update
|
94
|
+
action_handler.report_progress "update network ACL #{new_resource.name} #{direction.to_s} rules"
|
91
95
|
replace_rules(network_acl, replace_rules)
|
92
96
|
add_rules(network_acl, desired_rules)
|
93
97
|
remove_rules(network_acl, current_rules)
|
@@ -4,11 +4,9 @@ require 'date'
|
|
4
4
|
require 'retryable'
|
5
5
|
|
6
6
|
class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSProvider
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
7
|
+
include Chef::Provisioning::AWSDriver::TaggingStrategy::EC2ConvergeTags
|
8
|
+
|
9
|
+
provides :aws_network_interface
|
12
10
|
|
13
11
|
class NetworkInterfaceStatusTimeoutError < TimeoutError
|
14
12
|
def initialize(new_resource, initial_status, expected_status)
|
@@ -43,7 +41,7 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
|
|
43
41
|
end
|
44
42
|
|
45
43
|
converge_by "wait for new #{new_resource} in #{region} to become available" do
|
46
|
-
|
44
|
+
wait_for_status(eni, :available)
|
47
45
|
eni
|
48
46
|
end
|
49
47
|
end
|
@@ -122,14 +120,14 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
|
|
122
120
|
#
|
123
121
|
# If we were told to attach the network interface to a machine, do so
|
124
122
|
#
|
125
|
-
if expected_instance.is_a?(AWS::EC2::Instance)
|
123
|
+
if expected_instance.is_a?(AWS::EC2::Instance) || expected_instance.is_a?(::Aws::EC2::Instance)
|
126
124
|
case status
|
127
125
|
when :available
|
128
126
|
attach(eni)
|
129
127
|
when :in_use
|
130
128
|
# We don't want to attempt to reattach to the same instance or device index
|
131
129
|
attachment = current_attachment(eni)
|
132
|
-
if attachment.instance != expected_instance || (options[:device_index] && attachment.device_index != new_resource.device_index)
|
130
|
+
if attachment.instance.id != expected_instance.id || (options[:device_index] && attachment.device_index != new_resource.device_index)
|
133
131
|
detach(eni)
|
134
132
|
attach(eni)
|
135
133
|
end
|
@@ -153,38 +151,27 @@ class Chef::Provider::AwsNetworkInterface < Chef::Provisioning::AWSDriver::AWSPr
|
|
153
151
|
eni
|
154
152
|
end
|
155
153
|
|
156
|
-
def wait_for_eni_status(eni, expected_status)
|
157
|
-
initial_status = eni.status
|
158
|
-
log_callback = proc {
|
159
|
-
Chef::Log.info("waiting for #{new_resource} status to change to #{expected_status}...")
|
160
|
-
}
|
161
|
-
|
162
|
-
Retryable.retryable(:tries => 30, :sleep => 2, :on => NetworkInterfaceStatusTimeoutError, :ensure => log_callback) do
|
163
|
-
raise NetworkInterfaceStatusTimeoutError.new(new_resource, initial_status, expected_status) if eni.status != expected_status
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
154
|
def detach(eni)
|
168
155
|
attachment = current_attachment(eni)
|
169
156
|
instance = attachment.instance
|
170
157
|
|
171
|
-
converge_by "detach #{new_resource} from #{instance.
|
158
|
+
converge_by "detach #{new_resource} from #{instance.id}" do
|
172
159
|
eni.detach
|
173
160
|
end
|
174
161
|
|
175
162
|
converge_by "wait for #{new_resource} to detach" do
|
176
|
-
|
163
|
+
wait_for_status(eni, :available)
|
177
164
|
eni
|
178
165
|
end
|
179
166
|
end
|
180
167
|
|
181
168
|
def attach(eni)
|
182
|
-
converge_by "attach #{new_resource} to #{new_resource.machine} (#{expected_instance.
|
183
|
-
eni.attach(expected_instance, options)
|
169
|
+
converge_by "attach #{new_resource} to #{new_resource.machine} (#{expected_instance.id})" do
|
170
|
+
eni.attach(expected_instance.id, options)
|
184
171
|
end
|
185
172
|
|
186
173
|
converge_by "wait for #{new_resource} to attach" do
|
187
|
-
|
174
|
+
wait_for_status(eni, :in_use)
|
188
175
|
eni
|
189
176
|
end
|
190
177
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'chef/provisioning/aws_driver/aws_provider'
|
2
|
+
require 'chef/provisioning/aws_driver/tagging_strategy/rds'
|
3
|
+
|
4
|
+
class Chef::Provider::AwsRdsInstance < Chef::Provisioning::AWSDriver::AWSProvider
|
5
|
+
include Chef::Provisioning::AWSDriver::TaggingStrategy::RDSConvergeTags
|
6
|
+
|
7
|
+
provides :aws_rds_instance
|
8
|
+
|
9
|
+
REQUIRED_OPTIONS = %i(db_instance_identifier allocated_storage engine
|
10
|
+
db_instance_class master_username master_user_password)
|
11
|
+
|
12
|
+
OTHER_OPTIONS = %i(engine_version multi_az iops publicly_accessible db_name port db_subnet_group_name)
|
13
|
+
|
14
|
+
def update_aws_object(instance)
|
15
|
+
Chef::Log.warn("aws_rds_instance does not support modifying a started instance")
|
16
|
+
# There are required optiosn (like `allocated_storage`) that the use may not
|
17
|
+
# specify on a resource to perform an update. For example, they may want to
|
18
|
+
# only specify iops to modify that attribute on an update after initial
|
19
|
+
# creation. In this case we need to load the required options from the existing
|
20
|
+
# aws_object and only override it if the user has specified a value in the
|
21
|
+
# resource. Ideally, it would be nice to mark values as required on the
|
22
|
+
# resource but right now there is not a `required_on_create`. This would
|
23
|
+
# also be different if chef-provisioning performed resource cloning, which
|
24
|
+
# it does not.
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_aws_object
|
28
|
+
converge_by "create RDS instance #{new_resource.db_instance_identifier} in #{region}" do
|
29
|
+
new_resource.driver.rds.client.create_db_instance(options_hash)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy_aws_object(instance)
|
34
|
+
converge_by "delete RDS instance #{new_resource.db_instance_identifier} in #{region}" do
|
35
|
+
instance.delete(skip_final_snapshot: true)
|
36
|
+
end
|
37
|
+
# Wait up to 10 minutes for the db instance to shutdown
|
38
|
+
converge_by "waited until RDS instance #{new_resource.name} was deleted" do
|
39
|
+
wait_for(
|
40
|
+
aws_object: instance,
|
41
|
+
query_method: :exists?,
|
42
|
+
expected_responses: [false],
|
43
|
+
acceptable_errors: [AWS::RDS::Errors::DBInstanceNotFound],
|
44
|
+
tries: 60,
|
45
|
+
sleep: 10
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Sets the additional options then overrides it with all required options from
|
51
|
+
# the resource as well as optional options
|
52
|
+
def options_hash
|
53
|
+
@options_hash ||= begin
|
54
|
+
opts = Hash[new_resource.additional_options.map{|(k,v)| [k.to_sym,v]}]
|
55
|
+
REQUIRED_OPTIONS.each do |opt|
|
56
|
+
opts[opt] = new_resource.send(opt)
|
57
|
+
end
|
58
|
+
OTHER_OPTIONS.each do |opt|
|
59
|
+
opts[opt] = new_resource.send(opt) if ! new_resource.send(opt).nil?
|
60
|
+
end
|
61
|
+
AWSResource.lookup_options(opts, resource: new_resource)
|
62
|
+
opts
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'chef/provisioning/aws_driver/aws_provider'
|
2
|
+
require 'chef/provisioning/aws_driver/tagging_strategy/rds'
|
3
|
+
|
4
|
+
class Chef::Provider::AwsRdsSubnetGroup < Chef::Provisioning::AWSDriver::AWSProvider
|
5
|
+
include Chef::Provisioning::AWSDriver::TaggingStrategy::RDSConvergeTags
|
6
|
+
|
7
|
+
provides :aws_rds_subnet_group
|
8
|
+
|
9
|
+
def create_aws_object
|
10
|
+
converge_by "create RDS subnet group #{new_resource.name} in #{region}" do
|
11
|
+
driver.create_db_subnet_group(desired_options)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy_aws_object(object)
|
16
|
+
converge_by "delete RDS subnet group #{new_resource.name} in #{region}" do
|
17
|
+
driver.delete_db_subnet_group(db_subnet_group_name: new_resource.name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def update_aws_object(object)
|
22
|
+
updates = required_updates(object)
|
23
|
+
if ! updates.empty?
|
24
|
+
converge_by updates do
|
25
|
+
driver.modify_db_subnet_group(desired_options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def desired_options
|
31
|
+
@desired_options ||= begin
|
32
|
+
opts = {}
|
33
|
+
opts[:db_subnet_group_name] = new_resource.name
|
34
|
+
opts[:db_subnet_group_description] = new_resource.description
|
35
|
+
opts[:subnet_ids] = new_resource.subnets
|
36
|
+
AWSResource.lookup_options(opts, resource: new_resource)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Given an existing object, return an array of update descriptions
|
41
|
+
# representing the updates that need to be made.
|
42
|
+
#
|
43
|
+
# If no updates are needed, an empty array is returned.
|
44
|
+
#
|
45
|
+
def required_updates(object)
|
46
|
+
ret = []
|
47
|
+
if desired_options[:db_subnet_group_description] != object[:db_subnet_group_description]
|
48
|
+
ret << " set group description to #{desired_options[:db_subnet_group_description]}"
|
49
|
+
end
|
50
|
+
|
51
|
+
if ! xor_array(desired_options[:subnet_ids], subnet_ids(object[:subnets])).empty?
|
52
|
+
ret << " set subnets to #{desired_options[:subnet_ids]}"
|
53
|
+
end
|
54
|
+
|
55
|
+
if ! (desired_options[:aws_tags].nil? || desired_options[:aws_tags].empty?)
|
56
|
+
# modify_db_subnet_group doesn't support the tags key according to
|
57
|
+
# http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/RDS/Client.html#modify_db_subnet_group-instance_method
|
58
|
+
Chef::Log.warn "Updating tags for RDS subnet groups is not supported."
|
59
|
+
end
|
60
|
+
|
61
|
+
ret.unshift("update RDS subnet group #{new_resource.name} in #{region}") unless ret.empty?
|
62
|
+
ret
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def subnet_ids(subnets)
|
69
|
+
subnets.map {|i| i[:subnet_identifier] }
|
70
|
+
end
|
71
|
+
|
72
|
+
def xor_array(a, b)
|
73
|
+
(a | b) - (a & b)
|
74
|
+
end
|
75
|
+
|
76
|
+
# To be in line with the other resources. The aws_tags property
|
77
|
+
# takes a hash. But we actually need an array.
|
78
|
+
def tag_hash_to_array(tag_hash)
|
79
|
+
ret = []
|
80
|
+
tag_hash.each do |key, value|
|
81
|
+
ret << {:key => key, :value => value}
|
82
|
+
end
|
83
|
+
ret
|
84
|
+
end
|
85
|
+
|
86
|
+
def driver
|
87
|
+
new_resource.driver.rds.client
|
88
|
+
end
|
89
|
+
end
|