chef-provisioning-aws 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -4
- data/lib/chef/provider/aws_auto_scaling_group.rb +15 -1
- data/lib/chef/provider/aws_cloudwatch_alarm.rb +84 -0
- data/lib/chef/provider/aws_ebs_volume.rb +1 -1
- data/lib/chef/provider/aws_image.rb +13 -5
- data/lib/chef/provider/aws_launch_configuration.rb +4 -4
- data/lib/chef/provider/aws_nat_gateway.rb +57 -0
- data/lib/chef/provider/aws_network_interface.rb +1 -1
- data/lib/chef/provider/aws_route_table.rb +7 -3
- data/lib/chef/provider/aws_vpc.rb +20 -0
- data/lib/chef/provisioning/aws_driver.rb +2 -0
- data/lib/chef/provisioning/aws_driver/aws_provider.rb +1 -1
- data/lib/chef/provisioning/aws_driver/driver.rb +10 -5
- data/lib/chef/provisioning/aws_driver/tagging_strategy/auto_scaling.rb +76 -0
- data/lib/chef/provisioning/aws_driver/version.rb +1 -1
- data/lib/chef/resource/aws_auto_scaling_group.rb +12 -8
- data/lib/chef/resource/aws_cloudwatch_alarm.rb +35 -0
- data/lib/chef/resource/aws_image.rb +4 -4
- data/lib/chef/resource/aws_launch_configuration.rb +1 -1
- data/lib/chef/resource/aws_nat_gateway.rb +98 -0
- data/lib/chef/resource/aws_route_table.rb +1 -0
- data/spec/aws_support.rb +1 -1
- data/spec/integration/aws_auto_scaling_group_spec.rb +118 -0
- data/spec/integration/aws_cloudwatch_alarm_spec.rb +286 -0
- data/spec/integration/aws_nat_gateway_spec.rb +52 -0
- data/spec/integration/aws_rds_instance_spec.rb +10 -10
- data/spec/integration/aws_route_table_spec.rb +22 -0
- data/spec/integration/aws_vpc_spec.rb +31 -3
- data/spec/spec_helper.rb +4 -2
- metadata +11 -3
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'chef/provisioning/aws_driver/aws_tagger'
|
2
|
+
|
3
|
+
module Chef::Provisioning::AWSDriver::TaggingStrategy
|
4
|
+
module AutoScalingConvergeTags
|
5
|
+
def aws_tagger
|
6
|
+
@aws_tagger ||= begin
|
7
|
+
auto_scaling_strategy = Chef::Provisioning::AWSDriver::TaggingStrategy::AutoScaling.new(
|
8
|
+
new_resource.driver.auto_scaling_client,
|
9
|
+
new_resource.name,
|
10
|
+
new_resource.aws_tags
|
11
|
+
)
|
12
|
+
Chef::Provisioning::AWSDriver::AWSTagger.new(auto_scaling_strategy, action_handler)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
def converge_tags
|
16
|
+
aws_tagger.converge_tags
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Chef::Provisioning::AWSDriver::TaggingStrategy
|
22
|
+
class AutoScaling
|
23
|
+
|
24
|
+
attr_reader :auto_scaling_client, :group_name, :desired_tags
|
25
|
+
|
26
|
+
def initialize(auto_scaling_client, group_name, desired_tags)
|
27
|
+
@auto_scaling_client = auto_scaling_client
|
28
|
+
@group_name = group_name
|
29
|
+
@desired_tags = desired_tags
|
30
|
+
end
|
31
|
+
|
32
|
+
def current_tags
|
33
|
+
# http://docs.aws.amazon.com/sdkforruby/api/Aws/AutoScaling/Client.html#describe_tags-instance_method
|
34
|
+
resp = auto_scaling_client.describe_tags({
|
35
|
+
filters: [
|
36
|
+
{
|
37
|
+
name: "auto-scaling-group",
|
38
|
+
values: [group_name]
|
39
|
+
}
|
40
|
+
]
|
41
|
+
})
|
42
|
+
Hash[resp.tags.map {|t| [t.key, t.value]}]
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_tags(tags)
|
46
|
+
# http://docs.aws.amazon.com/sdkforruby/api/Aws/AutoScaling/Client.html#create_or_update_tags-instance_method
|
47
|
+
auto_scaling_client.create_or_update_tags({
|
48
|
+
tags: tags.map {|k,v|
|
49
|
+
{
|
50
|
+
resource_id: group_name,
|
51
|
+
key: k,
|
52
|
+
value: v,
|
53
|
+
resource_type: "auto-scaling-group",
|
54
|
+
propagate_at_launch: false
|
55
|
+
}
|
56
|
+
}
|
57
|
+
})
|
58
|
+
end
|
59
|
+
|
60
|
+
def delete_tags(tag_keys)
|
61
|
+
# http://docs.aws.amazon.com/sdkforruby/api/Aws/AutoScaling/Client.html#delete_tags-instance_method
|
62
|
+
auto_scaling_client.delete_tags({
|
63
|
+
tags: tag_keys.map {|k|
|
64
|
+
{
|
65
|
+
resource_id: group_name,
|
66
|
+
key: k,
|
67
|
+
value: nil,
|
68
|
+
resource_type: "auto-scaling-group",
|
69
|
+
propagate_at_launch: false
|
70
|
+
}
|
71
|
+
}
|
72
|
+
})
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -1,16 +1,20 @@
|
|
1
1
|
require 'chef/provisioning/aws_driver/aws_resource'
|
2
2
|
|
3
3
|
class Chef::Resource::AwsAutoScalingGroup < Chef::Provisioning::AWSDriver::AWSResource
|
4
|
+
include Chef::Provisioning::AWSDriver::AWSTaggable
|
5
|
+
|
4
6
|
aws_sdk_type AWS::AutoScaling::Group
|
5
7
|
|
6
|
-
attribute :name,
|
7
|
-
attribute :options,
|
8
|
-
attribute :availability_zones,
|
9
|
-
attribute :desired_capacity,
|
10
|
-
attribute :launch_configuration,
|
11
|
-
attribute :min_size,
|
12
|
-
attribute :max_size,
|
13
|
-
attribute :load_balancers,
|
8
|
+
attribute :name, kind_of: String, name_attribute: true
|
9
|
+
attribute :options, kind_of: Hash, default: {}
|
10
|
+
attribute :availability_zones, kind_of: Array
|
11
|
+
attribute :desired_capacity, kind_of: Integer
|
12
|
+
attribute :launch_configuration, kind_of: String
|
13
|
+
attribute :min_size, kind_of: Integer
|
14
|
+
attribute :max_size, kind_of: Integer
|
15
|
+
attribute :load_balancers, kind_of: Array, coerce: proc { |value| [value].flatten }
|
16
|
+
attribute :notification_configurations, kind_of: Array, default: []
|
17
|
+
attribute :scaling_policies, kind_of: Hash, default: {}
|
14
18
|
|
15
19
|
def aws_object
|
16
20
|
result = driver.auto_scaling.groups[name]
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'chef/provisioning/aws_driver/aws_resource'
|
2
|
+
|
3
|
+
class Chef::Resource::AwsCloudwatchAlarm < Chef::Provisioning::AWSDriver::AWSResource
|
4
|
+
include Chef::Provisioning::AWSDriver::AWSTaggable
|
5
|
+
|
6
|
+
aws_sdk_type ::Aws::CloudWatch::Alarm, id: :name
|
7
|
+
|
8
|
+
# This name must be unique within the user's AWS account
|
9
|
+
attribute :name, :kind_of => String, :name_attribute => true
|
10
|
+
attribute :namespace, :kind_of => String
|
11
|
+
attribute :metric_name, :kind_of => String
|
12
|
+
attribute :dimensions, :kind_of => Array
|
13
|
+
attribute :comparison_operator, :kind_of => String
|
14
|
+
attribute :evaluation_periods, :kind_of => Integer
|
15
|
+
attribute :period, :kind_of => [Integer,Float], coerce: proc {|v| v.to_f}
|
16
|
+
attribute :statistic, :kind_of => String
|
17
|
+
attribute :threshold, :kind_of => Integer
|
18
|
+
attribute :insufficient_data_actions, :kind_of => Array, coerce: proc {|v| [v].flatten}
|
19
|
+
attribute :ok_actions, :kind_of => Array, coerce: proc {|v| [v].flatten}
|
20
|
+
attribute :alarm_actions, :kind_of => Array, coerce: proc {|v| [v].flatten}
|
21
|
+
attribute :actions_enabled, :kind_of => [TrueClass, FalseClass]
|
22
|
+
attribute :alarm_description, :kind_of => String
|
23
|
+
attribute :unit, :kind_of => String
|
24
|
+
|
25
|
+
def aws_object
|
26
|
+
# TODO exists? isn't defined yet
|
27
|
+
# https://github.com/aws/aws-sdk-ruby/issues/1171
|
28
|
+
a = driver.cloudwatch_resource.alarm(name)
|
29
|
+
return nil if a.data.nil?
|
30
|
+
a
|
31
|
+
rescue ::Aws::CloudWatch::Errors::NoSuchEntity
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -4,11 +4,11 @@ require 'chef/provisioning/aws_driver/aws_taggable'
|
|
4
4
|
class Chef::Resource::AwsImage < Chef::Provisioning::AWSDriver::AWSResourceWithEntry
|
5
5
|
include Chef::Provisioning::AWSDriver::AWSTaggable
|
6
6
|
|
7
|
-
aws_sdk_type
|
8
|
-
managed_entry_type:
|
7
|
+
aws_sdk_type ::Aws::EC2::Image,
|
8
|
+
managed_entry_type: :machine_image,
|
9
9
|
managed_entry_id_name: 'image_id'
|
10
10
|
|
11
|
-
attribute :name, kind_of: String,
|
11
|
+
attribute :name, kind_of: String, name_attribute: true
|
12
12
|
|
13
13
|
attribute :image_id, kind_of: String, aws_id_attribute: true, default: lazy {
|
14
14
|
name =~ /^ami-[a-f0-9]{8}$/ ? name : nil
|
@@ -16,7 +16,7 @@ class Chef::Resource::AwsImage < Chef::Provisioning::AWSDriver::AWSResourceWithE
|
|
16
16
|
|
17
17
|
def aws_object
|
18
18
|
driver, id = get_driver_and_id
|
19
|
-
result = driver.
|
19
|
+
result = driver.ec2_resource.image(id) if id
|
20
20
|
result && result.exists? ? result : nil
|
21
21
|
end
|
22
22
|
end
|
@@ -4,7 +4,7 @@ class Chef::Resource::AwsLaunchConfiguration < Chef::Provisioning::AWSDriver::AW
|
|
4
4
|
aws_sdk_type AWS::AutoScaling::LaunchConfiguration, id: :name
|
5
5
|
|
6
6
|
attribute :name, kind_of: String, name_attribute: true
|
7
|
-
attribute :image, kind_of: [ String, AWS::EC2::Image ]
|
7
|
+
attribute :image, kind_of: [ String, AWS::EC2::Image, ::Aws::EC2::Image ]
|
8
8
|
attribute :instance_type, kind_of: String
|
9
9
|
attribute :options, kind_of: Hash, default: {}
|
10
10
|
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#
|
2
|
+
# An AWS nat gateway, enable instances in a private subnet to connect to
|
3
|
+
# the Internet or other AWS services, but prevent the Internet from
|
4
|
+
# initiating a connection with those instances
|
5
|
+
#
|
6
|
+
# `name` is not guaranteed unique for an AWS account; therefore, Chef will
|
7
|
+
# store the nat gateway ID associated with this name in your Chef server in the
|
8
|
+
# data bag `data/aws_nat_gateway/<name>`.
|
9
|
+
#
|
10
|
+
# API documentation for the AWS Ruby SDK for Nat gateway can be found here:
|
11
|
+
#
|
12
|
+
# - http://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Types/NatGateway.html
|
13
|
+
#
|
14
|
+
|
15
|
+
# We provide this class because the AWS SDK V2 does not provide it (as of
|
16
|
+
# May 2016). We copied the pattern in their SDK so when they do add a real
|
17
|
+
# resource there shouldn't be a need for much translation.
|
18
|
+
class Aws::EC2::NatGateway < Aws::Resources::Resource
|
19
|
+
attr_reader :resource, :id, :nat_gateway_id, :vpc_id, :subnet_id, :nat_gateway_addresses
|
20
|
+
|
21
|
+
def initialize(id, options = {})
|
22
|
+
@id = id
|
23
|
+
@nat_gateway_id = id
|
24
|
+
@client = options[:client]
|
25
|
+
nat_gateway_struct = get_nat_gateway_struct
|
26
|
+
@vpc_id = nat_gateway_struct.vpc_id
|
27
|
+
@subnet_id = nat_gateway_struct.subnet_id
|
28
|
+
@nat_gateway_addresses = nat_gateway_struct.nat_gateway_addresses
|
29
|
+
end
|
30
|
+
|
31
|
+
def state
|
32
|
+
get_nat_gateway_struct.state
|
33
|
+
end
|
34
|
+
|
35
|
+
def delete
|
36
|
+
@client.delete_nat_gateway({ nat_gateway_id: @id })
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def get_nat_gateway_struct
|
41
|
+
@client.describe_nat_gateways({ nat_gateway_ids: [@id] }).nat_gateways.first
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# See comment on class above as to why we add these methods to the AWS SDK
|
46
|
+
class Aws::EC2::Resource
|
47
|
+
def create_nat_gateway(options)
|
48
|
+
nat_gateway_struct = self.client.create_nat_gateway(options).nat_gateway
|
49
|
+
self.nat_gateway(nat_gateway_struct.nat_gateway_id)
|
50
|
+
end
|
51
|
+
|
52
|
+
def nat_gateway(nat_gateway_id)
|
53
|
+
::Aws::EC2::NatGateway.new(nat_gateway_id, {client: client})
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Chef::Resource::AwsNatGateway < Chef::Provisioning::AWSDriver::AWSResourceWithEntry
|
58
|
+
|
59
|
+
aws_sdk_type ::Aws::EC2::NatGateway, id: :nat_gateway_id, managed_entry_id_name: 'nat_gateway_id'
|
60
|
+
|
61
|
+
require 'chef/resource/aws_subnet'
|
62
|
+
require 'chef/resource/aws_eip_address'
|
63
|
+
|
64
|
+
#
|
65
|
+
# The name of this nat gateway.
|
66
|
+
#
|
67
|
+
attribute :name, kind_of: String, name_attribute: true
|
68
|
+
|
69
|
+
#
|
70
|
+
# A subnet to attach to the internet gateway.
|
71
|
+
#
|
72
|
+
# May be one of:
|
73
|
+
# - The name of an `aws_subnet` Chef resource.
|
74
|
+
# - An actual `aws_subnet` resource.
|
75
|
+
# - An Aws `Subnet` object.
|
76
|
+
#
|
77
|
+
attribute :subnet, kind_of: [ String, AwsSubnet, ::Aws::EC2::Subnet ]
|
78
|
+
|
79
|
+
#
|
80
|
+
# A elastic ip address for the nat gateway.
|
81
|
+
#
|
82
|
+
# May be one of:
|
83
|
+
# - The name of an `aws_eip_address` Chef resource.
|
84
|
+
# - An actual `aws_eip_address` resource.
|
85
|
+
# - nil, meaning that no EIP exists yet and needs to be created.
|
86
|
+
#
|
87
|
+
attribute :eip_address, kind_of: [ String, AWS::EC2::ElasticIp, AwsEipAddress, nil ], default: nil
|
88
|
+
|
89
|
+
attribute :nat_gateway_id, kind_of: String, aws_id_attribute: true, default: lazy {
|
90
|
+
name =~ /^nat-[A-Fa-f0-9]{17}$/ ? name : nil
|
91
|
+
}
|
92
|
+
|
93
|
+
def aws_object
|
94
|
+
driver, nat_gateway_id = get_driver_and_id
|
95
|
+
result = driver.ec2_resource.nat_gateway(nat_gateway_id) if nat_gateway_id
|
96
|
+
result && result.id ? result : nil
|
97
|
+
end
|
98
|
+
end
|
@@ -62,6 +62,7 @@ class Chef::Resource::AwsRouteTable < Chef::Provisioning::AWSDriver::AWSResource
|
|
62
62
|
# The destination (the left side of the `=>`) is always a CIDR block.
|
63
63
|
# The target (the right side of the `=>`) can be one of several things:
|
64
64
|
# - { internet_gateway: <AWS Internet Gateway ID or object> }
|
65
|
+
# - { nat_gateway: <AWS Nat Gateway ID or object> }
|
65
66
|
# - { instance: <Chef machine name or resource, AWS Instance ID or object> }
|
66
67
|
# - { network_interface: <AWS Network Interface ID or object> }
|
67
68
|
# - { vpc_peering_connection: <AWS VPC Peering Connection ID or object> }
|
data/spec/aws_support.rb
CHANGED
@@ -23,7 +23,7 @@ module AWSSupport
|
|
23
23
|
require 'aws'
|
24
24
|
require 'aws_support/deep_matcher/matchable_object'
|
25
25
|
require 'aws_support/deep_matcher/matchable_array'
|
26
|
-
DeepMatcher::MatchableObject.matchable_classes << proc { |o| o.class.name =~ /^(AWS|Aws)::(EC2|ELB|IAM|S3|RDS|CloudSearch|Route53|ElasticsearchService)($|::)/ }
|
26
|
+
DeepMatcher::MatchableObject.matchable_classes << proc { |o| o.class.name =~ /^(AWS|Aws)::(AutoScaling|EC2|ELB|IAM|S3|RDS|CloudSearch|CloudWatch|Route53|ElasticsearchService)($|::)/ }
|
27
27
|
DeepMatcher::MatchableArray.matchable_classes << AWS::Core::Data::List
|
28
28
|
|
29
29
|
def purge_all
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chef::Resource::AwsAutoScalingGroup do
|
4
|
+
extend AWSSupport
|
5
|
+
|
6
|
+
when_the_chef_12_server 'exists', organization: 'foo', server_scope: :context do
|
7
|
+
with_aws 'When connected to AWS' do
|
8
|
+
# Select an amazon linux ami based upon region
|
9
|
+
ami = {
|
10
|
+
'eu-west-1' => 'ami-3850624c',
|
11
|
+
'eu-central-1' => 'ami-993383ea',
|
12
|
+
'us-east-1' => 'ami-e024bf89',
|
13
|
+
'us-west-1' => 'ami-951945d0',
|
14
|
+
'us-west-2' => 'ami-16fd7026',
|
15
|
+
'ap-northeast-1' => 'ami-dcfa4edd',
|
16
|
+
'ap-northeast-2' => 'ami-7308c51d',
|
17
|
+
'ap-southeast-1' => 'ami-74dda626',
|
18
|
+
'ap-southeast-2' => 'ami-b5990e8f',
|
19
|
+
'sa-east-1' => 'ami-3e3be423'
|
20
|
+
}[driver.aws_config.region]
|
21
|
+
|
22
|
+
aws_launch_configuration 'test_config' do
|
23
|
+
image ami
|
24
|
+
instance_type 't1.micro'
|
25
|
+
end
|
26
|
+
|
27
|
+
aws_sns_topic 'test_topic'
|
28
|
+
|
29
|
+
it "aws_auto_scaling_group 'test_group' creates an auto scaling group" do
|
30
|
+
expect_recipe {
|
31
|
+
aws_auto_scaling_group 'test_group' do
|
32
|
+
launch_configuration 'test_config'
|
33
|
+
availability_zones ["#{driver.aws_config.region}a"]
|
34
|
+
min_size 1
|
35
|
+
max_size 2
|
36
|
+
end
|
37
|
+
}.to create_an_aws_auto_scaling_group(
|
38
|
+
'test_group').and be_idempotent
|
39
|
+
end
|
40
|
+
|
41
|
+
it "aws_auto_scaling_group 'test_group_with_policy' creates an auto scaling group" do
|
42
|
+
expect_recipe {
|
43
|
+
aws_auto_scaling_group 'test_group_with_policy' do
|
44
|
+
launch_configuration 'test_config'
|
45
|
+
availability_zones ["#{driver.aws_config.region}a"]
|
46
|
+
min_size 1
|
47
|
+
max_size 2
|
48
|
+
notification_configurations [{
|
49
|
+
topic: driver.build_arn(service: 'sns', resource: 'test_topic'),
|
50
|
+
types: [
|
51
|
+
'autoscaling:EC2_INSTANCE_LAUNCH',
|
52
|
+
'autoscaling:EC2_INSTANCE_TERMINATE'
|
53
|
+
]
|
54
|
+
}]
|
55
|
+
scaling_policies(
|
56
|
+
test_policy: {
|
57
|
+
adjustment_type: 'ChangeInCapacity',
|
58
|
+
scaling_adjustment: 1
|
59
|
+
}
|
60
|
+
)
|
61
|
+
end
|
62
|
+
}.to create_an_aws_auto_scaling_group(
|
63
|
+
'test_group_with_policy').and be_idempotent
|
64
|
+
end
|
65
|
+
|
66
|
+
it "creates aws_auto_scaling_group tags" do
|
67
|
+
expect_recipe {
|
68
|
+
aws_auto_scaling_group 'test_group_with_policy' do
|
69
|
+
launch_configuration 'test_config'
|
70
|
+
availability_zones ["#{driver.aws_config.region}a"]
|
71
|
+
min_size 1
|
72
|
+
max_size 2
|
73
|
+
aws_tags key1: "value"
|
74
|
+
end
|
75
|
+
}.to create_an_aws_auto_scaling_group('test_group_with_policy'
|
76
|
+
).and have_aws_auto_scaling_group_tags('test_group_with_policy',
|
77
|
+
{
|
78
|
+
'key1' => 'value'
|
79
|
+
}
|
80
|
+
).and be_idempotent
|
81
|
+
end
|
82
|
+
|
83
|
+
context "with existing tags" do
|
84
|
+
aws_auto_scaling_group 'test_group_with_policy' do
|
85
|
+
launch_configuration 'test_config'
|
86
|
+
availability_zones ["#{driver.aws_config.region}a"]
|
87
|
+
min_size 1
|
88
|
+
max_size 2
|
89
|
+
aws_tags key1: "value"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "updates aws_auto_scaling_group tags" do
|
93
|
+
expect_recipe {
|
94
|
+
aws_auto_scaling_group 'test_group_with_policy' do
|
95
|
+
aws_tags key1: "value2", key2: nil
|
96
|
+
end
|
97
|
+
}.to have_aws_auto_scaling_group_tags('test_group_with_policy',
|
98
|
+
{
|
99
|
+
'key1' => 'value2',
|
100
|
+
'key2' => ''
|
101
|
+
}
|
102
|
+
).and be_idempotent
|
103
|
+
end
|
104
|
+
|
105
|
+
it "removes all aws_network_acl tags" do
|
106
|
+
expect_recipe {
|
107
|
+
aws_auto_scaling_group 'test_group_with_policy' do
|
108
|
+
aws_tags({})
|
109
|
+
end
|
110
|
+
}.to have_aws_auto_scaling_group_tags('test_group_with_policy',
|
111
|
+
{}
|
112
|
+
).and be_idempotent
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,286 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chef::Resource::AwsCloudwatchAlarm do
|
4
|
+
extend AWSSupport
|
5
|
+
|
6
|
+
when_the_chef_12_server 'exists', organization: 'foo', server_scope: :context do
|
7
|
+
with_aws 'When connected to AWS' do
|
8
|
+
|
9
|
+
aws_sns_topic 'mytesttopic1'
|
10
|
+
aws_sns_topic 'mytesttopic2'
|
11
|
+
|
12
|
+
it "creates an aws_cloudwatch_alarm with minimum properties" do
|
13
|
+
expect_recipe {
|
14
|
+
aws_cloudwatch_alarm 'my-test-alert' do
|
15
|
+
namespace 'AWS/EC2'
|
16
|
+
metric_name 'CPUUtilization'
|
17
|
+
comparison_operator 'GreaterThanThreshold'
|
18
|
+
evaluation_periods 1
|
19
|
+
period 60
|
20
|
+
statistic 'Average'
|
21
|
+
threshold 80
|
22
|
+
end
|
23
|
+
}.to create_an_aws_cloudwatch_alarm('my-test-alert',
|
24
|
+
namespace: 'AWS/EC2',
|
25
|
+
metric_name: 'CPUUtilization',
|
26
|
+
comparison_operator: 'GreaterThanThreshold',
|
27
|
+
evaluation_periods: 1,
|
28
|
+
period: 60,
|
29
|
+
statistic: 'Average',
|
30
|
+
threshold: 80,
|
31
|
+
actions_enabled: true # this is true by default
|
32
|
+
).and be_idempotent
|
33
|
+
end
|
34
|
+
|
35
|
+
it "creates an aws_cloudwatch_alarm with maximum properties" do
|
36
|
+
expect_recipe {
|
37
|
+
aws_cloudwatch_alarm 'my-test-alert' do
|
38
|
+
namespace 'AWS/EC2'
|
39
|
+
metric_name 'CPUUtilization'
|
40
|
+
comparison_operator 'GreaterThanThreshold'
|
41
|
+
evaluation_periods 1
|
42
|
+
period 60
|
43
|
+
statistic 'Average'
|
44
|
+
threshold 80
|
45
|
+
dimensions([
|
46
|
+
{
|
47
|
+
name: "foo1",
|
48
|
+
value: "bar1"
|
49
|
+
},
|
50
|
+
{
|
51
|
+
name: "foo2",
|
52
|
+
value: "bar2"
|
53
|
+
}
|
54
|
+
])
|
55
|
+
insufficient_data_actions ['mytesttopic1']
|
56
|
+
ok_actions ['mytesttopic1']
|
57
|
+
alarm_actions ['mytesttopic1']
|
58
|
+
actions_enabled false
|
59
|
+
alarm_description "description"
|
60
|
+
unit "Percent"
|
61
|
+
end
|
62
|
+
}.to create_an_aws_cloudwatch_alarm('my-test-alert',
|
63
|
+
namespace: 'AWS/EC2',
|
64
|
+
metric_name: 'CPUUtilization',
|
65
|
+
comparison_operator: 'GreaterThanThreshold',
|
66
|
+
evaluation_periods: 1,
|
67
|
+
period: 60,
|
68
|
+
statistic: 'Average',
|
69
|
+
threshold: 80,
|
70
|
+
dimensions: [
|
71
|
+
{
|
72
|
+
name: "foo1",
|
73
|
+
value: "bar1"
|
74
|
+
},
|
75
|
+
{
|
76
|
+
name: "foo2",
|
77
|
+
value: "bar2"
|
78
|
+
}
|
79
|
+
],
|
80
|
+
insufficient_data_actions: [mytesttopic1.aws_object.arn],
|
81
|
+
ok_actions: [mytesttopic1.aws_object.arn],
|
82
|
+
alarm_actions: [mytesttopic1.aws_object.arn],
|
83
|
+
actions_enabled: false,
|
84
|
+
alarm_description: "description",
|
85
|
+
unit: "Percent",
|
86
|
+
).and be_idempotent
|
87
|
+
end
|
88
|
+
|
89
|
+
context "with an existing minimum cloudwatch alarm" do
|
90
|
+
aws_cloudwatch_alarm 'my-test-alert' do
|
91
|
+
namespace 'AWS/EC2'
|
92
|
+
metric_name 'CPUUtilization'
|
93
|
+
comparison_operator 'GreaterThanThreshold'
|
94
|
+
evaluation_periods 1
|
95
|
+
period 60
|
96
|
+
statistic 'Average'
|
97
|
+
threshold 80
|
98
|
+
end
|
99
|
+
|
100
|
+
it "updates an aws_cloudwatch_alarm with maximum properties" do
|
101
|
+
expect_recipe {
|
102
|
+
aws_cloudwatch_alarm 'my-test-alert' do
|
103
|
+
namespace 'AWS/EC2'
|
104
|
+
metric_name 'CPUUtilization'
|
105
|
+
comparison_operator 'GreaterThanThreshold'
|
106
|
+
evaluation_periods 1
|
107
|
+
period 60
|
108
|
+
statistic 'Average'
|
109
|
+
threshold 80
|
110
|
+
dimensions([
|
111
|
+
{
|
112
|
+
name: "foo1",
|
113
|
+
value: "bar1"
|
114
|
+
},
|
115
|
+
{
|
116
|
+
name: "foo2",
|
117
|
+
value: "bar2"
|
118
|
+
}
|
119
|
+
])
|
120
|
+
insufficient_data_actions ['mytesttopic1']
|
121
|
+
ok_actions ['mytesttopic1']
|
122
|
+
alarm_actions ['mytesttopic1']
|
123
|
+
actions_enabled false
|
124
|
+
alarm_description "description"
|
125
|
+
unit "Percent"
|
126
|
+
end
|
127
|
+
}.to update_an_aws_cloudwatch_alarm('my-test-alert',
|
128
|
+
namespace: 'AWS/EC2',
|
129
|
+
metric_name: 'CPUUtilization',
|
130
|
+
comparison_operator: 'GreaterThanThreshold',
|
131
|
+
evaluation_periods: 1,
|
132
|
+
period: 60,
|
133
|
+
statistic: 'Average',
|
134
|
+
threshold: 80,
|
135
|
+
dimensions: [
|
136
|
+
{
|
137
|
+
name: "foo1",
|
138
|
+
value: "bar1"
|
139
|
+
},
|
140
|
+
{
|
141
|
+
name: "foo2",
|
142
|
+
value: "bar2"
|
143
|
+
}
|
144
|
+
],
|
145
|
+
insufficient_data_actions: [mytesttopic1.aws_object.arn],
|
146
|
+
ok_actions: [mytesttopic1.aws_object.arn],
|
147
|
+
alarm_actions: [mytesttopic1.aws_object.arn],
|
148
|
+
actions_enabled: false,
|
149
|
+
alarm_description: "description",
|
150
|
+
unit: "Percent",
|
151
|
+
).and be_idempotent
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
context "with an existing maximum cloudwatch alarm" do
|
157
|
+
aws_cloudwatch_alarm 'my-test-alert' do
|
158
|
+
namespace 'AWS/EC2'
|
159
|
+
metric_name 'CPUUtilization'
|
160
|
+
comparison_operator 'GreaterThanThreshold'
|
161
|
+
evaluation_periods 1
|
162
|
+
period 60
|
163
|
+
statistic 'Average'
|
164
|
+
threshold 80
|
165
|
+
dimensions([
|
166
|
+
{
|
167
|
+
name: "foo1",
|
168
|
+
value: "bar1"
|
169
|
+
},
|
170
|
+
{
|
171
|
+
name: "foo2",
|
172
|
+
value: "bar2"
|
173
|
+
}
|
174
|
+
])
|
175
|
+
insufficient_data_actions ['mytesttopic1']
|
176
|
+
ok_actions ['mytesttopic1']
|
177
|
+
alarm_actions ['mytesttopic1']
|
178
|
+
actions_enabled false
|
179
|
+
alarm_description "description"
|
180
|
+
unit "Percent"
|
181
|
+
end
|
182
|
+
|
183
|
+
it "updates all updateable attributes" do
|
184
|
+
expect_recipe {
|
185
|
+
aws_cloudwatch_alarm 'my-test-alert' do
|
186
|
+
namespace 'AWS/S3'
|
187
|
+
metric_name 'foo'
|
188
|
+
comparison_operator 'LessThanThreshold'
|
189
|
+
evaluation_periods 2
|
190
|
+
period 120
|
191
|
+
statistic 'Maximum'
|
192
|
+
threshold 70
|
193
|
+
dimensions([
|
194
|
+
{
|
195
|
+
name: "foo3",
|
196
|
+
value: "bar3"
|
197
|
+
}
|
198
|
+
])
|
199
|
+
insufficient_data_actions ['mytesttopic2']
|
200
|
+
ok_actions ['mytesttopic1', 'mytesttopic2']
|
201
|
+
alarm_actions ['mytesttopic2']
|
202
|
+
actions_enabled true
|
203
|
+
alarm_description "description2"
|
204
|
+
unit "Bits"
|
205
|
+
end
|
206
|
+
}.to update_an_aws_cloudwatch_alarm('my-test-alert',
|
207
|
+
namespace: 'AWS/S3',
|
208
|
+
metric_name: 'foo',
|
209
|
+
comparison_operator: 'LessThanThreshold',
|
210
|
+
evaluation_periods: 2,
|
211
|
+
period: 120,
|
212
|
+
statistic: 'Maximum',
|
213
|
+
threshold: 70,
|
214
|
+
dimensions: [
|
215
|
+
{
|
216
|
+
name: "foo3",
|
217
|
+
value: "bar3"
|
218
|
+
}
|
219
|
+
],
|
220
|
+
insufficient_data_actions: [mytesttopic2.aws_object.arn],
|
221
|
+
ok_actions: Set[mytesttopic1.aws_object.arn, mytesttopic2.aws_object.arn],
|
222
|
+
alarm_actions: [mytesttopic2.aws_object.arn],
|
223
|
+
actions_enabled: true,
|
224
|
+
alarm_description: "description2",
|
225
|
+
unit: "Bits",
|
226
|
+
).and be_idempotent
|
227
|
+
end
|
228
|
+
|
229
|
+
it "updates only the specified properties" do
|
230
|
+
expect_recipe {
|
231
|
+
aws_cloudwatch_alarm 'my-test-alert' do
|
232
|
+
unit "Gigabytes"
|
233
|
+
end
|
234
|
+
}.to update_an_aws_cloudwatch_alarm('my-test-alert',
|
235
|
+
namespace: 'AWS/S3',
|
236
|
+
metric_name: 'foo',
|
237
|
+
comparison_operator: 'LessThanThreshold',
|
238
|
+
evaluation_periods: 2,
|
239
|
+
period: 120,
|
240
|
+
statistic: 'Maximum',
|
241
|
+
threshold: 70,
|
242
|
+
dimensions: [
|
243
|
+
{
|
244
|
+
name: "foo3",
|
245
|
+
value: "bar3"
|
246
|
+
}
|
247
|
+
],
|
248
|
+
insufficient_data_actions: [mytesttopic2.aws_object.arn],
|
249
|
+
ok_actions: Set[mytesttopic1.aws_object.arn, mytesttopic2.aws_object.arn],
|
250
|
+
alarm_actions: [mytesttopic2.aws_object.arn],
|
251
|
+
actions_enabled: true,
|
252
|
+
alarm_description: "description2",
|
253
|
+
unit: "Gigabytes",
|
254
|
+
).and be_idempotent
|
255
|
+
end
|
256
|
+
|
257
|
+
it "clears out all clearable arrays" do
|
258
|
+
expect_recipe {
|
259
|
+
aws_cloudwatch_alarm 'my-test-alert' do
|
260
|
+
dimensions []
|
261
|
+
insufficient_data_actions []
|
262
|
+
ok_actions []
|
263
|
+
alarm_actions []
|
264
|
+
end
|
265
|
+
}.to create_an_aws_cloudwatch_alarm('my-test-alert',
|
266
|
+
namespace: 'AWS/S3',
|
267
|
+
metric_name: 'foo',
|
268
|
+
comparison_operator: 'LessThanThreshold',
|
269
|
+
evaluation_periods: 2,
|
270
|
+
period: 120,
|
271
|
+
statistic: 'Maximum',
|
272
|
+
threshold: 70,
|
273
|
+
dimensions: [],
|
274
|
+
insufficient_data_actions: [],
|
275
|
+
ok_actions: [],
|
276
|
+
alarm_actions: [],
|
277
|
+
actions_enabled: true,
|
278
|
+
alarm_description: "description2",
|
279
|
+
unit: "Gigabytes",
|
280
|
+
).and be_idempotent
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|