Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make names for AWS Config service objects optional #2928

Merged
merged 5 commits into from
Apr 19, 2018

Conversation

clintoncwolfe
Copy link
Contributor

As described on #2900, we were unnecessarily requiring an AWS resource name for the two Config Service inspec resources, aws_config_recoorder and aws_config_delivery_resource. If you don't provide a name in the query, the API gives you all config resources, and since they are singletons, it's easy to pick the right one.

Also found we had no unit tests for aws_config_delivery_resource; added them.

Also some general code cleanup in both affected resources.

Fixes #2900

@clintoncwolfe clintoncwolfe requested a review from a team as a code owner April 9, 2018 17:40
@clintoncwolfe clintoncwolfe added Type: Enhancement Improves an existing feature Platform: AWS Amazon Web Services-related issues and removed in progress labels Apr 9, 2018
@clintoncwolfe clintoncwolfe force-pushed the cw/aws-config-name-by-default branch from 319948b to 64d5dff Compare April 9, 2018 19:00
Copy link
Contributor

@jquick jquick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks.

Copy link
Contributor

@TrevorBramble TrevorBramble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loads of great additions and improvements. I have some suggestions to offer but I think only the typo is a blocker. ;^)

@@ -23,57 +27,70 @@ An `aws_config_delivery_channel` resource block declares the tests for a single
it { should exist }
end

However, since you may only have one DDelivery Channel per region, and InSpec connections are per-region, you may also omit the `channel_name` to obtain the one Delivery Channel (if any) that exists:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DDelivery

catch_aws_errors do
@resp = backend.describe_delivery_channels(query)
query = @channel_name ? { delivery_channel_names: [@channel_name] } : {}
response = {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the assignment on line 39 sometimes return nil? If so, maybe just response = backend.describe_delivery_channels(query) || {} instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it never returns a {}.

inspec> c = inspec.backend.aws_client(Aws::ConfigService::Client)
=> #<Aws::ConfigService::Client>
inspec> c.describe_delivery_channels
=> #<struct Aws::ConfigService::Types::DescribeDeliveryChannelsResponse delivery_channels=[]>
inspec> c.describe_delivery_channels({})
=> #<struct Aws::ConfigService::Types::DescribeDeliveryChannelsResponse delivery_channels=[]>
inspec> c.describe_delivery_channels(delivery_channel_names:['nonesuch'])
Aws::ConfigService::Errors::NoSuchDeliveryChannelException: Cannot find delivery channel with specified name 'nonesuch'.
from /Users/cwolfe/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/aws-sdk-core-2.11.21/lib/seahorse/client/plugins/raise_response_errors.rb:15:in `call'
inspec> c.describe_delivery_channels.delivery_channels
=> []
inspec> c.describe_delivery_channels.delivery_channels.empty?
=> true

Thanks for mentioning it, though - that means this is wrong:

@exists = !response.empty?

Should be:

@exists = !response.delivery_channels.empty?

response = {}
begin
response = backend.describe_delivery_channels(query)
rescue Aws::ConfigService::Errors::NoSuchDeliveryChannelException
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropping this rescue to the bottom of the method would clear up the "happy path" for readers and removes the need to early return when handling the exception.

def fetch_from_api
  # ...
rescue Aws::ConfigService::Errors::NoSuchDeliveryChannelException
  @exists = false
end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved the rescue to be method-level, as you asked. I generally dislike doing that, however. By moving the rescue away from the "dangerous" code, it obscures which line(s) are potentially dangerous. While this code only has one such dangerous expression, other methods may need to call multiple APIs that may fail.

There is an argument there for shorter, more granular methods.

@s3_bucket_name = channel[:s3_bucket_name]
@s3_key_prefix = channel[:s3_key_prefix]
@sns_topic_arn = channel[:sns_topic_arn]
@delivery_frequency_in_hours = channel[:config_snapshot_delivery_properties][:delivery_frequency] unless channel[:config_snapshot_delivery_properties].nil?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the conditional clause with dig. =^)

@delivery_frequency_in_hours = channel.dig(:config_snapshot_delivery_properties, :delivery_frequency)

rescue Aws::ConfigService::Errors::NoSuchConfigurationRecorderException
@exists = false
return
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the other fetch_from_api, re: rescue at method level instead of introducing a begin block.

def describe_delivery_channels(query = {})
fixtures = {
'default' => Aws::ConfigService::Types::DescribeDeliveryChannelsResponse.new(
:delivery_channels => [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes I see {:foo => :bar} and sometimes I see {foo: :bar}, particularly in the Rubocop-ignored test code. Shouldn't we always use JSON style for symbol keys?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it ignored by rubocop, that means we as a team have decided it is code that is not worthwhile to enforce style conventions. We can open that for discussion if you'd like.

}
return fixtures['default'] if query.empty?
return fixtures[query[:delivery_channel_names][0]] unless fixtures[query[:delivery_channel_names][0]].nil?
raise Aws::ConfigService::Errors::NoSuchDeliveryChannelException.new(nil, nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look like three cases to me. ;^)

@clintoncwolfe clintoncwolfe force-pushed the cw/aws-config-name-by-default branch from 64d5dff to 49a5031 Compare April 17, 2018 20:22
@clintoncwolfe clintoncwolfe force-pushed the cw/aws-config-name-by-default branch from 49a5031 to 6f4c356 Compare April 17, 2018 20:23
Copy link
Contributor

@TrevorBramble TrevorBramble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for considering my feedback!

@jquick jquick merged commit 8934352 into master Apr 19, 2018
@jquick jquick deleted the cw/aws-config-name-by-default branch April 19, 2018 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: AWS Amazon Web Services-related issues Type: Enhancement Improves an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants