1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

[aws|auto_scaling] improve notification configurations

- implement describe_notification_configurations
- implement mocks for (delete|put)_notification_configurations
- tests for *_notification_configurations
- delete notification configurations in delete_auto_scaling_group mock
This commit is contained in:
Nick Osborn 2012-09-23 19:24:16 +01:00
parent c269379203
commit d60ec0bff5
9 changed files with 313 additions and 25 deletions

View file

@ -26,6 +26,7 @@ module Fog
request :describe_auto_scaling_notification_types
request :describe_launch_configurations
request :describe_metric_collection_types
request :describe_notification_configurations
request :describe_policies
request :describe_scaling_activities
request :describe_scaling_process_types
@ -58,6 +59,9 @@ module Fog
class Real
include Fog::AWS::CredentialFetcher::ConnectionMethods
attr_accessor :region
# Initialize connection to AutoScaling
#
# ==== Notes
@ -75,6 +79,7 @@ module Fog
#
# ==== Returns
# * AutoScaling object with connection to AWS.
def initialize(options={})
require 'fog/core/parser'
@ -87,6 +92,8 @@ module Fog
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.auto_scaling'
options[:region] ||= 'us-east-1'
@region = options[:region]
@host = options[:host] || "autoscaling.#{options[:region]}.amazonaws.com"
@path = options[:path] || '/'
@port = options[:port] || 443
@ -162,9 +169,9 @@ module Fog
end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_access_key_id = options[:aws_access_key_id]
@aws_secret_access_key = options[:aws_secret_access_key]
@aws_session_token = options[:aws_session_token]
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
@hmac = Fog::HMAC.new('sha256', @aws_secret_access_key)
@ -173,9 +180,13 @@ module Fog
class Mock
include Fog::AWS::CredentialFetcher::ConnectionMethods
attr_accessor :region
def self.data
@data ||= Hash.new do |hash, region|
owner_id = Fog::AWS::Mock.owner_id
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:adjustment_types => [
@ -204,6 +215,7 @@ module Fog
'GroupTotalInstances'
]
},
:notification_configurations => {},
:notification_types => [
'autoscaling:EC2_INSTANCE_LAUNCH',
'autoscaling:EC2_INSTANCE_LAUNCH_ERROR',
@ -211,6 +223,7 @@ module Fog
'autoscaling:EC2_INSTANCE_TERMINATE_ERROR',
'autoscaling:TEST_NOTIFICATION'
],
:owner_id => owner_id,
:process_types => [
'AZRebalance',
'AddToLoadBalancer',
@ -241,26 +254,28 @@ module Fog
@use_iam_profile = options[:use_iam_profile]
setup_credentials(options)
@region = options[:region] || 'us-east-1'
@owner_id = Fog::AWS::Mock.owner_id
unless ['ap-northeast-1', 'ap-southeast-1', 'eu-west-1', 'sa-east-1', 'us-east-1', 'us-west-1', 'us-west-2'].include?(@region)
raise ArgumentError, "Unknown region: #{@region.inspect}"
end
end
def region_data
self.class.data[@region]
end
def data
self.region_data[@aws_access_key_id]
end
def reset_data
self.region_data.delete(@aws_access_key_id)
end
def setup_credentials(options)
@aws_access_key_id = options[:aws_access_key_id]
end
def data
self.class.data[@region][@aws_access_key_id]
end
def reset_data
self.class.data[@region].delete(@aws_access_key_id)
end
end
end

View file

@ -0,0 +1,42 @@
module Fog
module Parsers
module AWS
module AutoScaling
class DescribeNotificationConfigurations < Fog::Parsers::Base
def reset
reset_notification_configuration
@results = { 'NotificationConfigurations' => [] }
@response = { 'DescribeNotificationConfigurationsResult' => {}, 'ResponseMetadata' => {} }
end
def reset_notification_configuration
@notification_configuration = {}
end
def end_element(name)
case name
when 'member'
@results['NotificationConfigurations'] << @notification_configuration
reset_notification_configuration
when 'AutoScalingGroupName','NotificationType', 'TopicARN'
@notification_configuration[name] = value
when 'NextToken'
@results[name] = value
when 'RequestId'
@response['ResponseMetadata'][name] = value
when 'DescribeNotificationConfigurationsResponse'
@response['DescribeNotificationConfigurationsResult'] = @results
end
end
end
end
end
end
end

View file

@ -94,14 +94,14 @@ module Fog
class Mock
def create_auto_scaling_group(auto_scaling_group_name, availability_zones, launch_configuration_name, max_size, min_size, options = {})
if data[:auto_scaling_groups].has_key?(auto_scaling_group_name)
if self.data[:auto_scaling_groups].has_key?(auto_scaling_group_name)
raise Fog::AWS::AutoScaling::IdentifierTaken.new("AutoScalingGroup by this name already exists - A group with the name #{auto_scaling_group_name} already exists")
end
unless data[:launch_configurations].has_key?(launch_configuration_name)
unless self.data[:launch_configurations].has_key?(launch_configuration_name)
raise Fog::AWS::AutoScaling::ValidationError.new('Launch configuration name not found - null')
end
data[:auto_scaling_groups][auto_scaling_group_name] = {
'AutoScalingGroupARN' => Fog::AWS::Mock.arn('autoscaling', @owner_id, "autoScalingGroup:00000000-0000-0000-0000-000000000000:autoScalingGroupName/#{auto_scaling_group_name}", @region),
self.data[:auto_scaling_groups][auto_scaling_group_name] = {
'AutoScalingGroupARN' => Fog::AWS::Mock.arn('autoscaling', self.data[:owner_id], "autoScalingGroup:00000000-0000-0000-0000-000000000000:autoScalingGroupName/#{auto_scaling_group_name}", @region),
'AutoScalingGroupName' => auto_scaling_group_name,
'AvailabilityZones' => availability_zones.to_a,
'CreatedTime' => Time.now.utc,

View file

@ -79,10 +79,10 @@ module Fog
class Mock
def create_launch_configuration(image_id, instance_type, launch_configuration_name, options = {})
if data[:launch_configurations].has_key?(launch_configuration_name)
if self.data[:launch_configurations].has_key?(launch_configuration_name)
raise Fog::AWS::AutoScaling::IdentifierTaken.new("Launch Configuration by this name already exists - A launch configuration already exists with the name #{launch_configuration_name}")
end
data[:launch_configurations][launch_configuration_name] = {
self.data[:launch_configurations][launch_configuration_name] = {
'BlockDeviceMappings' => [],
'CreatedTime' => Time.now.utc,
'ImageId' => image_id,
@ -90,7 +90,7 @@ module Fog
'InstanceType' => instance_type,
'KernelId' => nil,
'KeyName' => nil,
'LaunchConfigurationARN' => Fog::AWS::Mock.arn('autoscaling', @owner_id, "launchConfiguration:00000000-0000-0000-0000-000000000000:launchConfigurationName/#{launch_configuration_name}", @region),
'LaunchConfigurationARN' => Fog::AWS::Mock.arn('autoscaling', self.data[:owner_id], "launchConfiguration:00000000-0000-0000-0000-000000000000:launchConfigurationName/#{launch_configuration_name}", @region),
'LaunchConfigurationName' => launch_configuration_name,
'RamdiskId' => nil,
'SecurityGroups' => [],

View file

@ -44,6 +44,8 @@ module Fog
raise Fog::AWS::AutoScaling::ValidationError, "The auto scaling group '#{auto_scaling_group_name}' does not exist."
end
self.data[:notification_configurations].delete(auto_scaling_group_name)
response = Excon::Response.new
response.status = 200
response.body = {

View file

@ -37,9 +37,25 @@ module Fog
class Mock
def delete_notification_configuration(auto_scaling_group_name, topic_arn)
Fog::Mock.not_implemented
end
unless self.data[:notification_configurations].has_key?(auto_scaling_group_name)
raise Fog::AWS::AutoScaling::ValidationError.new('AutoScalingGroup name not found - %s' % auto_scaling_group_name)
end
unless self.data[:notification_configurations][auto_scaling_group_name].has_key?(topic_arn)
raise Fog::AWS::AutoScaling::ValidationError.new("Notification Topic '#{topic_arn}' doesn't exist for '#{self.data[:owner_id]}'")
end
self.data[:notification_configurations][auto_scaling_group_name].delete(topic_arn)
if self.data[:notification_configurations][auto_scaling_group_name].empty?
self.data[:notification_configurations].delete(auto_scaling_group_name)
end
response = Excon::Response.new
response.status = 200
response.body = {
'ResponseMetadata' => { 'RequestId' => Fog::AWS::Mock.request_id }
}
response
end
end
end

View file

@ -0,0 +1,79 @@
module Fog
module AWS
class AutoScaling
class Real
require 'fog/aws/parsers/auto_scaling/describe_notification_configurations'
# Returns a list of notification actions associated with Auto Scaling
# groups for specified events.
#
# ==== Parameters
# * options<~Hash>:
# * 'AutoScalingGroupsName'<~String> - The name of the Auto Scaling
# group.
# * 'MaxRecords'<~Integer> - The maximum number of records to return.
# * 'NextToken'<~String> - A string that is used to mark the start of
# the next batch of returned results for pagination.
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'ResponseMetadata'<~Hash>:
# * 'RequestId'<~String> - Id of request
# * 'DescribeNotificationConfigurationsResult'<~Hash>:
# * 'NotificationConfigurations'<~Array>:
# * notificationConfiguration<~Hash>:
# * 'AutoScalingGroupName'<~String> - Specifies the Auto
# Scaling group name.
# * 'NotificationType'<~String> - The types of events for an
# action to start.
# * 'TopicARN'<~String> - The Amazon Resource Name (ARN) of the
# Amazon Simple Notification Service (SNS) topic.
#
# ==== See Also
# http://docs.amazonwebservices.com/AutoScaling/latest/APIReference/API_DescribeNotificationConfigurations.html
#
def describe_notification_configurations(options = {})
if auto_scaling_group_names = options.delete('AutoScalingGroupNames')
options.merge!(AWS.indexed_param('AutoScalingGroupNames.member.%d', [*auto_scaling_group_names]))
end
request({
'Action' => 'DescribeNotificationConfigurations',
:parser => Fog::Parsers::AWS::AutoScaling::DescribeNotificationConfigurations.new
}.merge!(options))
end
end
class Mock
def describe_notification_configurations(options = {})
results = { 'NotificationConfigurations' => [] }
(options['AutoScalingGroupNames']||self.data[:notification_configurations].keys).each do |asg_name|
(self.data[:notification_configurations][asg_name]||{}).each do |topic_arn, notification_types|
notification_types.each do |notification_type|
results['NotificationConfigurations'] << {
'AutoScalingGroupName' => asg_name,
'NotificationType' => notification_type,
'TopicARN' => topic_arn,
}
end
end
end
response = Excon::Response.new
response.status = 200
response.body = {
'DescribeNotificationConfigurationsResult' => results,
'ResponseMetadata' => { 'RequestId' => Fog::AWS::Mock.request_id }
}
response
end
end
end
end
end

View file

@ -27,14 +27,13 @@ module Fog
# http://docs.amazonwebservices.com/AutoScaling/latest/APIReference/API_PutNotificationConfiguration.html
#
def put_notification_configuration(auto_scaling_group_name, notification_types, topic_arn)
options = {}
options.merge!(AWS.indexed_param('NotificationTypes.member.%d', [*notification_types]))
params = AWS.indexed_param('NotificationTypes.member.%d', [*notification_types])
request({
'Action' => 'PutNotificationConfiguration',
'AutoScalingGroupName' => auto_scaling_group_name,
'TopicARN' => topic_arn,
:parser => Fog::Parsers::AWS::AutoScaling::PutNotificationConfiguration.new
}.merge!(options))
}.merge!(params))
end
end
@ -42,7 +41,26 @@ module Fog
class Mock
def put_notification_configuration(auto_scaling_group_name, notification_types, topic_arn)
Fog::Mock.not_implemented
unless self.data[:auto_scaling_groups].has_key?(auto_scaling_group_name)
raise Fog::AWS::AutoScaling::ValidationError.new("AutoScalingGroup name not found - #{auto_scaling_group_name}")
end
if notification_types.to_a.empty?
raise Fog::AWS::AutoScaling::ValidationError.new("1 validation error detected: Value null at 'notificationTypes' failed to satisfy constraint: Member must not be null")
end
invalid_types = notification_types.to_a - self.data[:notification_types]
unless invalid_types.empty?
raise Fog::AWS::AutoScaling::ValidationError.new("&quot;#{invalid_types.first}&quot; is not a valid Notification Type.")
end
self.data[:notification_configurations][auto_scaling_group_name] ||= {}
self.data[:notification_configurations][auto_scaling_group_name][topic_arn] = notification_types.to_a.uniq
response = Excon::Response.new
response.status = 200
response.body = {
'ResponseMetadata' => { 'RequestId' => Fog::AWS::Mock.request_id }
}
response
end
end

View file

@ -0,0 +1,116 @@
Shindo.tests('AWS::AutoScaling | notification configuration requests', ['aws', 'auto_scaling']) do
image_id = { # Ubuntu 12.04 LTS 64-bit EBS
'ap-northeast-1' => 'ami-60c77761',
'ap-southeast-1' => 'ami-a4ca8df6',
'eu-west-1' => 'ami-e1e8d395',
'sa-east-1' => 'ami-8cd80691',
'us-east-1' => 'ami-a29943cb',
'us-west-1' => 'ami-87712ac2',
'us-west-2' => 'ami-20800c10'
}
now = Time.now.utc.to_i
lc_name = "fog-test-#{now}"
asg_name = "fog-test-#{now}"
topic_name = "fog-test-#{now}"
begin
topic = Fog::AWS[:sns].create_topic(topic_name).body
topic_arn = topic['TopicArn']
rescue Fog::Errors::MockNotImplemented
topic_arn = Fog::AWS::Mock.arn('sns', Fog::AWS[:auto_scaling].data[:owner_id], "fog-test-#{now}", Fog::AWS[:auto_scaling].region)
end
lc = Fog::AWS[:auto_scaling].create_launch_configuration(image_id[Fog::AWS[:auto_scaling].region], 't1.micro', lc_name)
asg = Fog::AWS[:auto_scaling].create_auto_scaling_group(asg_name, "#{Fog::AWS[:auto_scaling].region}a", lc_name, 0, 0)
tests('raises') do
tests("#put_notification_configuration(non-existent-group)").raises(Fog::AWS::AutoScaling::ValidationError) do
Fog::AWS[:auto_scaling].put_notification_configuration('fog-test-nonexistent-group', 'autoscaling:TEST_NOTIFICATION', topic_arn)
end
tests("#put_notification_configuration(null-types)").raises(Fog::AWS::AutoScaling::ValidationError) do
Fog::AWS[:auto_scaling].put_notification_configuration(asg_name, [], topic_arn)
end
end
tests('success') do
tests("#put_notification_configuration(string)").formats(AWS::AutoScaling::Formats::BASIC) do
Fog::AWS[:auto_scaling].put_notification_configuration(asg_name, 'autoscaling:TEST_NOTIFICATION', topic_arn).body
end
tests("#describe_notification_configurations").formats(AWS::AutoScaling::Formats::DESCRIBE_NOTIFICATION_CONFIGURATIONS) do
body = Fog::AWS[:auto_scaling].describe_notification_configurations('AutoScalingGroupNames' => asg_name).body
notification_configurations = body['DescribeNotificationConfigurationsResult']['NotificationConfigurations']
returns(true, 'exactly 1 configurations') do
notification_configurations.size == 1
end
returns(true) do
config = notification_configurations.first
config['AutoScalingGroupName'] == asg_name && config['TopicARN'] == topic_arn && config['NotificationType'] == 'autoscaling:TEST_NOTIFICATION'
end
body
end
tests("#put_notification_configuration(array)").formats(AWS::AutoScaling::Formats::BASIC) do
Fog::AWS[:auto_scaling].put_notification_configuration(asg_name, ['autoscaling:EC2_INSTANCE_LAUNCH', 'autoscaling:EC2_INSTANCE_TERMINATE'], topic_arn).body
end
tests("#describe_notification_configurations").formats(AWS::AutoScaling::Formats::DESCRIBE_NOTIFICATION_CONFIGURATIONS) do
body = Fog::AWS[:auto_scaling].describe_notification_configurations('AutoScalingGroupName' => asg_name).body
notification_configurations = body['DescribeNotificationConfigurationsResult']['NotificationConfigurations']
returns(true, 'exactly 2 configurations') do
notification_configurations.size == 2
end
[ 'autoscaling:EC2_INSTANCE_LAUNCH', 'autoscaling:EC2_INSTANCE_TERMINATE'].each do |type|
returns(true) do
notification_configurations.any? do |config|
config['AutoScalingGroupName'] == asg_name && config['TopicARN'] == topic_arn && config['NotificationType'] == type
end
end
end
body
end
tests("#describe_notification_configurations(all)").formats(AWS::AutoScaling::Formats::DESCRIBE_NOTIFICATION_CONFIGURATIONS) do
body = Fog::AWS[:auto_scaling].describe_notification_configurations().body
notification_configurations = body['DescribeNotificationConfigurationsResult']['NotificationConfigurations']
returns(true, 'at least 2 configurations') do
notification_configurations.size >= 2
end
[ 'autoscaling:EC2_INSTANCE_LAUNCH', 'autoscaling:EC2_INSTANCE_TERMINATE'].each do |type|
returns(true) do
notification_configurations.any? do |config|
config['AutoScalingGroupName'] == asg_name && config['TopicARN'] == topic_arn && config['NotificationType'] == type
end
end
end
body
end
tests("#delete_notification_configuration").formats(AWS::AutoScaling::Formats::BASIC) do
Fog::AWS[:auto_scaling].delete_notification_configuration(asg_name, topic_arn).body
end
tests("#describe_notification_configurations").formats(AWS::AutoScaling::Formats::DESCRIBE_NOTIFICATION_CONFIGURATIONS) do
body = Fog::AWS[:auto_scaling].describe_notification_configurations('AutoScalingGroupNames' => asg_name).body
returns(true) do
body['DescribeNotificationConfigurationsResult']['NotificationConfigurations'].empty?
end
body
end
end
Fog::AWS[:auto_scaling].delete_auto_scaling_group(asg_name)
Fog::AWS[:auto_scaling].delete_launch_configuration(lc_name)
if topic
begin
Fog::AWS[:sns].delete_topic(topic_arn)
rescue Fog::Errors::MockNotImplemented
end
end
end