From 26cbbd287695760ed29982bef88b8c1ec36271db Mon Sep 17 00:00:00 2001 From: Orien Madgwick <_@orien.io> Date: Wed, 28 Dec 2022 05:59:02 +1100 Subject: [PATCH] AWS SDK: pass an options hash instead of keyword arguments The AWS SDK accepts an options hash as arguments, not keyword arguments. We've been relying on Ruby to automatically convert keyword arguments into an options hash. Let's avoid this implicit conversion and explicitly pass an options hash. --- CHANGELOG.md | 5 ++ features/step_definitions/asume_role_steps.rb | 4 +- .../aws_driver/cloud_formation.rb | 2 +- lib/stack_master/aws_driver/s3.rb | 10 +-- lib/stack_master/change_set.rb | 6 +- lib/stack_master/commands/resources.rb | 2 +- lib/stack_master/identity.rb | 4 +- .../parameter_resolvers/acm_certificate.rb | 4 +- .../parameter_resolvers/ami_finder.rb | 6 +- .../parameter_resolvers/latest_container.rb | 2 +- .../parameter_resolvers/parameter_store.rb | 6 +- .../parameter_resolvers/stack_output.rb | 2 +- lib/stack_master/role_assumer.rb | 4 +- lib/stack_master/security_group_finder.rb | 2 +- lib/stack_master/sns_topic_finder.rb | 2 +- lib/stack_master/stack.rb | 6 +- spec/stack_master/aws_driver/s3_spec.rb | 74 +++++++++++++------ spec/stack_master/change_set_spec.rb | 8 +- spec/stack_master/commands/apply_spec.rb | 2 +- spec/stack_master/commands/delete_spec.rb | 2 +- .../acm_certificate_spec.rb | 15 ++-- .../parameter_resolvers/ami_finder_spec.rb | 15 ++-- .../latest_ami_by_tags_spec.rb | 15 ++-- .../parameter_resolvers/latest_ami_spec.rb | 15 ++-- .../latest_container_spec.rb | 44 +++++++---- .../parameter_resolvers/stack_output_spec.rb | 10 +-- spec/stack_master/role_assumer_spec.rb | 32 ++++---- spec/stack_master/stack_spec.rb | 23 +++++- spec/support/aws_stubs.rb | 21 +++--- 29 files changed, 217 insertions(+), 126 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9f86782..c4d9627d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,13 @@ The format is based on [Keep a Changelog], and this project adheres to - Test on Ruby 3.0 and 3.1 in the CI build ([#366]). +### Changed + +- Pass an options hash to the AWS SDK, instead of keyword arguments ([#371]). + [Unreleased]: https://github.com/envato/stack_master/compare/v2.13.2...HEAD [#366]: https://github.com/envato/stack_master/pull/366 +[#371]: https://github.com/envato/stack_master/pull/371 ## [2.13.2] - 2022-01-25 diff --git a/features/step_definitions/asume_role_steps.rb b/features/step_definitions/asume_role_steps.rb index 343b0fcc..0e64f44c 100644 --- a/features/step_definitions/asume_role_steps.rb +++ b/features/step_definitions/asume_role_steps.rb @@ -1,7 +1,7 @@ Then(/^I expect the role "([^"]*)" is assumed in account "([^"]*)"$/) do |role, account| - expect(Aws::AssumeRoleCredentials).to receive(:new).with( + expect(Aws::AssumeRoleCredentials).to receive(:new).with({ region: instance_of(String), role_arn: "arn:aws:iam::#{account}:role/#{role}", role_session_name: instance_of(String) - ) + }) end diff --git a/lib/stack_master/aws_driver/cloud_formation.rb b/lib/stack_master/aws_driver/cloud_formation.rb index 164f2bca..314d3927 100644 --- a/lib/stack_master/aws_driver/cloud_formation.rb +++ b/lib/stack_master/aws_driver/cloud_formation.rb @@ -36,7 +36,7 @@ def set_region(value) private def cf - @cf ||= Aws::CloudFormation::Client.new(region: region, retry_limit: 10) + @cf ||= Aws::CloudFormation::Client.new({ region: region, retry_limit: 10 }) end end diff --git a/lib/stack_master/aws_driver/s3.rb b/lib/stack_master/aws_driver/s3.rb index 2cce498b..a8f7c1dc 100644 --- a/lib/stack_master/aws_driver/s3.rb +++ b/lib/stack_master/aws_driver/s3.rb @@ -17,10 +17,10 @@ def upload_files(bucket: nil, prefix: nil, region: nil, files: {}) s3 = new_s3_client(region: region) - current_objects = s3.list_objects( + current_objects = s3.list_objects({ prefix: prefix, bucket: bucket - ).map(&:contents).flatten.inject({}){|h,obj| + }).map(&:contents).flatten.inject({}){|h,obj| h.merge(obj.key => obj) } @@ -38,12 +38,12 @@ def upload_files(bucket: nil, prefix: nil, region: nil, files: {}) s3_uri = "s3://#{bucket}/#{object_key}" StackMaster.stdout.print "- #{File.basename(path)} => #{s3_uri} " - s3.put_object( + s3.put_object({ bucket: bucket, key: object_key, body: body, metadata: { md5: compiled_template_md5 } - ) + }) StackMaster.stdout.puts "done." end end @@ -61,7 +61,7 @@ def url(bucket:, prefix:, region:, template:) private def new_s3_client(region: nil) - Aws::S3::Client.new(region: region || @region) + Aws::S3::Client.new({ region: region || @region }) end end end diff --git a/lib/stack_master/change_set.rb b/lib/stack_master/change_set.rb index 59e8f5b8..4201c6e7 100644 --- a/lib/stack_master/change_set.rb +++ b/lib/stack_master/change_set.rb @@ -25,12 +25,12 @@ def self.find(id) end def self.delete(id) - cf.delete_change_set(change_set_name: id) + cf.delete_change_set({ change_set_name: id }) end def self.execute(id, stack_name) - cf.execute_change_set(change_set_name: id, - stack_name: stack_name) + cf.execute_change_set({ change_set_name: id, + stack_name: stack_name }) end def self.cf diff --git a/lib/stack_master/commands/resources.rb b/lib/stack_master/commands/resources.rb index 16d8bda1..970d3ab1 100644 --- a/lib/stack_master/commands/resources.rb +++ b/lib/stack_master/commands/resources.rb @@ -17,7 +17,7 @@ def perform private def stack_resources - @stack_resources ||= cf.describe_stack_resources(stack_name: @stack_definition.stack_name).stack_resources + @stack_resources ||= cf.describe_stack_resources({ stack_name: @stack_definition.stack_name }).stack_resources rescue Aws::CloudFormation::Errors::ValidationError nil end diff --git a/lib/stack_master/identity.rb b/lib/stack_master/identity.rb index 00c6163b..752021fc 100644 --- a/lib/stack_master/identity.rb +++ b/lib/stack_master/identity.rb @@ -31,11 +31,11 @@ def region end def sts - @sts ||= Aws::STS::Client.new(region: region) + @sts ||= Aws::STS::Client.new({ region: region }) end def iam - @iam ||= Aws::IAM::Client.new(region: region) + @iam ||= Aws::IAM::Client.new({ region: region }) end def contains_account_id?(ids) diff --git a/lib/stack_master/parameter_resolvers/acm_certificate.rb b/lib/stack_master/parameter_resolvers/acm_certificate.rb index d9224185..d7e3c2e1 100644 --- a/lib/stack_master/parameter_resolvers/acm_certificate.rb +++ b/lib/stack_master/parameter_resolvers/acm_certificate.rb @@ -19,9 +19,9 @@ def resolve(domain_name) def all_certs certs = [] next_token = nil - client = Aws::ACM::Client.new(region: @stack_definition.region) + client = Aws::ACM::Client.new({ region: @stack_definition.region }) loop do - resp = client.list_certificates(certificate_statuses: ['ISSUED'], next_token: next_token) + resp = client.list_certificates({ certificate_statuses: ['ISSUED'], next_token: next_token }) certs << resp.certificate_summary_list next_token = resp.next_token break if next_token.nil? diff --git a/lib/stack_master/parameter_resolvers/ami_finder.rb b/lib/stack_master/parameter_resolvers/ami_finder.rb index e9ca1856..a8168a10 100644 --- a/lib/stack_master/parameter_resolvers/ami_finder.rb +++ b/lib/stack_master/parameter_resolvers/ami_finder.rb @@ -19,7 +19,7 @@ def build_filters_from_hash(hash) end def find_latest_ami(filters, owners = ['self']) - images = ec2.describe_images(owners: owners, filters: filters).images + images = ec2.describe_images({ owners: owners, filters: filters }).images sorted_images = images.sort do |a, b| Time.parse(a.creation_date) <=> Time.parse(b.creation_date) end @@ -29,8 +29,8 @@ def find_latest_ami(filters, owners = ['self']) private def ec2 - @ec2 ||= Aws::EC2::Client.new(region: @region) + @ec2 ||= Aws::EC2::Client.new({ region: @region }) end end end -end \ No newline at end of file +end diff --git a/lib/stack_master/parameter_resolvers/latest_container.rb b/lib/stack_master/parameter_resolvers/latest_container.rb index 3ca5a869..0c86bc31 100644 --- a/lib/stack_master/parameter_resolvers/latest_container.rb +++ b/lib/stack_master/parameter_resolvers/latest_container.rb @@ -14,7 +14,7 @@ def resolve(parameters) end @region = parameters['region'] || @stack_definition.region - ecr_client = Aws::ECR::Client.new(region: @region) + ecr_client = Aws::ECR::Client.new({ region: @region }) images = fetch_images(parameters['repository_name'], parameters['registry_id'], ecr_client) diff --git a/lib/stack_master/parameter_resolvers/parameter_store.rb b/lib/stack_master/parameter_resolvers/parameter_store.rb index 20b58ee4..443a3ff9 100644 --- a/lib/stack_master/parameter_resolvers/parameter_store.rb +++ b/lib/stack_master/parameter_resolvers/parameter_store.rb @@ -11,11 +11,11 @@ def initialize(config, stack_definition) def resolve(value) begin - ssm = Aws::SSM::Client.new(region: @stack_definition.region) - resp = ssm.get_parameter( + ssm = Aws::SSM::Client.new({ region: @stack_definition.region }) + resp = ssm.get_parameter({ name: value, with_decryption: true - ) + }) rescue Aws::SSM::Errors::ParameterNotFound raise ParameterNotFound, "Unable to find #{value} in Parameter Store" end diff --git a/lib/stack_master/parameter_resolvers/stack_output.rb b/lib/stack_master/parameter_resolvers/stack_output.rb index d83492f0..80658cef 100644 --- a/lib/stack_master/parameter_resolvers/stack_output.rb +++ b/lib/stack_master/parameter_resolvers/stack_output.rb @@ -53,7 +53,7 @@ def find_stack(stack_name, region) @stacks.fetch(stack_key) do regional_cf = cf_for_region(unaliased_region) - cf_stack = regional_cf.describe_stacks(stack_name: stack_name).stacks.first + cf_stack = regional_cf.describe_stacks({ stack_name: stack_name }).stacks.first @stacks[stack_key] = cf_stack end end diff --git a/lib/stack_master/role_assumer.rb b/lib/stack_master/role_assumer.rb index 8ed4a6fd..f582cfbf 100644 --- a/lib/stack_master/role_assumer.rb +++ b/lib/stack_master/role_assumer.rb @@ -44,11 +44,11 @@ def with_temporary_cf_driver(&block) def assume_role_credentials(account, role) credentials_key = "#{account}:#{role}" @credentials.fetch(credentials_key) do - @credentials[credentials_key] = Aws::AssumeRoleCredentials.new( + @credentials[credentials_key] = Aws::AssumeRoleCredentials.new({ region: StackMaster.cloud_formation_driver.region, role_arn: "arn:aws:iam::#{account}:role/#{role}", role_session_name: "stack-master-role-assumer" - ) + }) end end end diff --git a/lib/stack_master/security_group_finder.rb b/lib/stack_master/security_group_finder.rb index ba93a7bd..237009a5 100644 --- a/lib/stack_master/security_group_finder.rb +++ b/lib/stack_master/security_group_finder.rb @@ -4,7 +4,7 @@ class SecurityGroupFinder MultipleSecurityGroupsFound = Class.new(StandardError) def initialize(region) - @resource = Aws::EC2::Resource.new(region: region) + @resource = Aws::EC2::Resource.new({ region: region }) end def find(reference) diff --git a/lib/stack_master/sns_topic_finder.rb b/lib/stack_master/sns_topic_finder.rb index 7177a60a..8de5b0ba 100644 --- a/lib/stack_master/sns_topic_finder.rb +++ b/lib/stack_master/sns_topic_finder.rb @@ -3,7 +3,7 @@ class SnsTopicFinder TopicNotFound = Class.new(StandardError) def initialize(region) - @resource = Aws::SNS::Resource.new(region: region) + @resource = Aws::SNS::Resource.new({ region: region }) end def find(reference) diff --git a/lib/stack_master/stack.rb b/lib/stack_master/stack.rb index 99357dad..7977ce03 100644 --- a/lib/stack_master/stack.rb +++ b/lib/stack_master/stack.rb @@ -29,15 +29,15 @@ def parameters_with_defaults def self.find(region, stack_name) cf = StackMaster.cloud_formation_driver - cf_stack = cf.describe_stacks(stack_name: stack_name).stacks.first + cf_stack = cf.describe_stacks({ stack_name: stack_name }).stacks.first return unless cf_stack parameters = cf_stack.parameters.inject({}) do |params_hash, param_struct| params_hash[param_struct.parameter_key] = param_struct.parameter_value params_hash end - template_body ||= cf.get_template(stack_name: stack_name, template_stage: 'Original').template_body + template_body ||= cf.get_template({ stack_name: stack_name, template_stage: 'Original' }).template_body template_format = TemplateUtils.identify_template_format(template_body) - stack_policy_body ||= cf.get_stack_policy(stack_name: stack_name).stack_policy_body + stack_policy_body ||= cf.get_stack_policy({ stack_name: stack_name }).stack_policy_body outputs = cf_stack.outputs new(region: region, diff --git a/spec/stack_master/aws_driver/s3_spec.rb b/spec/stack_master/aws_driver/s3_spec.rb index 42f8c87d..2c4b5ab5 100644 --- a/spec/stack_master/aws_driver/s3_spec.rb +++ b/spec/stack_master/aws_driver/s3_spec.rb @@ -1,7 +1,7 @@ RSpec.describe StackMaster::AwsDriver::S3 do let(:region) { 'us-east-1' } let(:bucket) { 'bucket' } - let(:s3) { Aws::S3::Client.new(stub_responses: true) } + let(:s3) { Aws::S3::Client.new({ stub_responses: true }) } subject(:s3_driver) { StackMaster::AwsDriver::S3.new } before do @@ -16,7 +16,7 @@ context 'when set_region is called' do it 'defaults to that region' do s3_driver.set_region('default') - expect(Aws::S3::Client).to receive(:new).with(region: 'default').and_return(s3) + expect(Aws::S3::Client).to receive(:new).with({ region: 'default' }).and_return(s3) files = { 'template' => { path: 'spec/fixtures/templates/myapp_vpc.json', @@ -43,10 +43,16 @@ end it 'uploads files under a prefix' do - expect(s3).to receive(:put_object).with(bucket: 'bucket', - key: 'prefix/template', - body: 'file content', - metadata: {md5: "d10b4c3ff123b26dc068d43a8bef2d23"}) + expect(s3).to receive(:put_object).with( + { + bucket: 'bucket', + key: 'prefix/template', + body: 'file content', + metadata: { + md5: "d10b4c3ff123b26dc068d43a8bef2d23" + } + } + ) s3_driver.upload_files(**options) end end @@ -65,10 +71,16 @@ end it 'uploads files under the bucket root' do - expect(s3).to receive(:put_object).with(bucket: 'bucket', - key: 'template', - body: 'file content', - metadata: {md5: "d10b4c3ff123b26dc068d43a8bef2d23"}) + expect(s3).to receive(:put_object).with( + { + bucket: 'bucket', + key: 'template', + body: 'file content', + metadata: { + md5: "d10b4c3ff123b26dc068d43a8bef2d23" + } + } + ) s3_driver.upload_files(**options) end end @@ -88,10 +100,16 @@ end it 'uploads files under the prefix' do - expect(s3).to receive(:put_object).with(bucket: 'bucket', - key: 'prefix/template', - body: 'file content', - metadata: {md5: "d10b4c3ff123b26dc068d43a8bef2d23"}) + expect(s3).to receive(:put_object).with( + { + bucket: 'bucket', + key: 'prefix/template', + body: 'file content', + metadata: { + md5: "d10b4c3ff123b26dc068d43a8bef2d23" + } + } + ) s3_driver.upload_files(**options) end end @@ -115,14 +133,26 @@ end it 'uploads all the files' do - expect(s3).to receive(:put_object).with(bucket: 'bucket', - key: 'template1', - body: 'file content', - metadata: {md5: "d10b4c3ff123b26dc068d43a8bef2d23"}) - expect(s3).to receive(:put_object).with(bucket: 'bucket', - key: 'template2', - body: 'file content', - metadata: {md5: "d10b4c3ff123b26dc068d43a8bef2d23"}) + expect(s3).to receive(:put_object).with( + { + bucket: 'bucket', + key: 'template1', + body: 'file content', + metadata: { + md5: "d10b4c3ff123b26dc068d43a8bef2d23" + } + } + ) + expect(s3).to receive(:put_object).with( + { + bucket: 'bucket', + key: 'template2', + body: 'file content', + metadata: { + md5: "d10b4c3ff123b26dc068d43a8bef2d23" + } + } + ) s3_driver.upload_files(**options) end end diff --git a/spec/stack_master/change_set_spec.rb b/spec/stack_master/change_set_spec.rb index fa2679ba..911a3eb6 100644 --- a/spec/stack_master/change_set_spec.rb +++ b/spec/stack_master/change_set_spec.rb @@ -21,22 +21,22 @@ context 'successful response' do before do - allow(cf).to receive(:describe_change_set).with(change_set_name: 'id-1', next_token: nil).and_return(double(next_token: nil, changes: [], :changes= => nil, :next_token= => nil, status: 'CREATE_COMPLETE')) + allow(cf).to receive(:describe_change_set).with({ change_set_name: 'id-1', next_token: nil }).and_return(double(next_token: nil, changes: [], :changes= => nil, :next_token= => nil, status: 'CREATE_COMPLETE')) end it 'calls the create change set API with the addition of a name' do change_set = StackMaster::ChangeSet.create(stack_name: '123') - expect(cf).to have_received(:create_change_set).with( + expect(cf).to have_received(:create_change_set).with({ stack_name: '123', change_set_name: change_set_name - ) + }) expect(change_set.failed?).to eq false end end context 'unsuccessful response' do before do - allow(cf).to receive(:describe_change_set).with(change_set_name: 'id-1', next_token: nil).and_return(double(next_token: nil, changes: [], :changes= => nil, :next_token= => nil, status: 'FAILED', status_reason: 'No changes')) + allow(cf).to receive(:describe_change_set).with({ change_set_name: 'id-1', next_token: nil }).and_return(double(next_token: nil, changes: [], :changes= => nil, :next_token= => nil, status: 'FAILED', status_reason: 'No changes')) end it 'is marked as failed' do diff --git a/spec/stack_master/commands/apply_spec.rb b/spec/stack_master/commands/apply_spec.rb index e9e8f182..b8a98076 100644 --- a/spec/stack_master/commands/apply_spec.rb +++ b/spec/stack_master/commands/apply_spec.rb @@ -248,7 +248,7 @@ def apply end it "deletes the stack" do - expect(cf).to receive(:delete_stack).with(stack_name: stack_name) + expect(cf).to receive(:delete_stack).with({ stack_name: stack_name }) expect { apply }.to raise_error(StackMaster::CtrlC) end end diff --git a/spec/stack_master/commands/delete_spec.rb b/spec/stack_master/commands/delete_spec.rb index ec2f4d1d..300ea90d 100644 --- a/spec/stack_master/commands/delete_spec.rb +++ b/spec/stack_master/commands/delete_spec.rb @@ -8,7 +8,7 @@ before do StackMaster.cloud_formation_driver.set_region(region) - allow(Aws::CloudFormation::Client).to receive(:new).with(region: region, retry_limit: 10).and_return(cf) + allow(Aws::CloudFormation::Client).to receive(:new).with({ region: region, retry_limit: 10 }).and_return(cf) allow(delete).to receive(:ask?).and_return('y') allow(StackMaster::StackEvents::Streamer).to receive(:stream) end diff --git a/spec/stack_master/parameter_resolvers/acm_certificate_spec.rb b/spec/stack_master/parameter_resolvers/acm_certificate_spec.rb index 928a6ff6..f28deda1 100644 --- a/spec/stack_master/parameter_resolvers/acm_certificate_spec.rb +++ b/spec/stack_master/parameter_resolvers/acm_certificate_spec.rb @@ -10,10 +10,15 @@ context 'when a certificate is found' do before do - acm.stub_responses(:list_certificates, certificate_summary_list: [ - { certificate_arn: 'arn:aws:acm:us-east-1:12345:certificate/abc', domain_name: 'abc' }, - { certificate_arn: 'arn:aws:acm:us-east-1:12345:certificate/def', domain_name: 'def' } - ]) + acm.stub_responses( + :list_certificates, + { + certificate_summary_list: [ + { certificate_arn: 'arn:aws:acm:us-east-1:12345:certificate/abc', domain_name: 'abc' }, + { certificate_arn: 'arn:aws:acm:us-east-1:12345:certificate/def', domain_name: 'def' } + ] + } + ) end it 'returns the certificate' do @@ -23,7 +28,7 @@ context 'when no certificate is found' do before do - acm.stub_responses(:list_certificates, certificate_summary_list: []) + acm.stub_responses(:list_certificates, { certificate_summary_list: [] }) end it 'raises an error' do diff --git a/spec/stack_master/parameter_resolvers/ami_finder_spec.rb b/spec/stack_master/parameter_resolvers/ami_finder_spec.rb index 7170a070..e3041a32 100644 --- a/spec/stack_master/parameter_resolvers/ami_finder_spec.rb +++ b/spec/stack_master/parameter_resolvers/ami_finder_spec.rb @@ -44,10 +44,15 @@ context 'when matches are found' do before do - ec2.stub_responses(:describe_images, images: [ - { image_id: '1', creation_date: '2015-01-02 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] }, - { image_id: '2', creation_date: '2015-01-03 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] } - ]) + ec2.stub_responses( + :describe_images, + { + images: [ + { image_id: '1', creation_date: '2015-01-02 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] }, + { image_id: '2', creation_date: '2015-01-03 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] } + ] + } + ) end it 'returns the latest one' do @@ -57,7 +62,7 @@ context 'when no matches are found' do before do - ec2.stub_responses(:describe_images, images: []) + ec2.stub_responses(:describe_images, { images: [] }) end it 'returns nil' do diff --git a/spec/stack_master/parameter_resolvers/latest_ami_by_tags_spec.rb b/spec/stack_master/parameter_resolvers/latest_ami_by_tags_spec.rb index 75e4621a..ae0c4fdb 100644 --- a/spec/stack_master/parameter_resolvers/latest_ami_by_tags_spec.rb +++ b/spec/stack_master/parameter_resolvers/latest_ami_by_tags_spec.rb @@ -10,10 +10,15 @@ context 'when matches are found' do before do - ec2.stub_responses(:describe_images, images: [ - { image_id: '1', creation_date: '2015-01-02 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] }, - { image_id: '2', creation_date: '2015-01-03 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] } - ]) + ec2.stub_responses( + :describe_images, + { + images: [ + { image_id: '1', creation_date: '2015-01-02 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] }, + { image_id: '2', creation_date: '2015-01-03 00:00:00', tags: [{ key: 'my-tag', value: 'my-value' }] } + ] + } + ) end it 'returns the latest one' do @@ -23,7 +28,7 @@ context 'when no matches are found' do before do - ec2.stub_responses(:describe_images, images: []) + ec2.stub_responses(:describe_images, { images: [] }) end it 'returns nil' do diff --git a/spec/stack_master/parameter_resolvers/latest_ami_spec.rb b/spec/stack_master/parameter_resolvers/latest_ami_spec.rb index 48a161af..67fc1f84 100644 --- a/spec/stack_master/parameter_resolvers/latest_ami_spec.rb +++ b/spec/stack_master/parameter_resolvers/latest_ami_spec.rb @@ -10,10 +10,15 @@ context 'when matches are found' do before do - ec2.stub_responses(:describe_images, images: [ - { image_id: '1', creation_date: '2015-01-02 00:00:00', name: 'foo' }, - { image_id: '2', creation_date: '2015-01-03 00:00:00', name: 'foo' } - ]) + ec2.stub_responses( + :describe_images, + { + images: [ + { image_id: '1', creation_date: '2015-01-02 00:00:00', name: 'foo' }, + { image_id: '2', creation_date: '2015-01-03 00:00:00', name: 'foo' } + ] + } + ) end it 'returns the latest one' do @@ -23,7 +28,7 @@ context 'when no matches are found' do before do - ec2.stub_responses(:describe_images, images: []) + ec2.stub_responses(:describe_images, { images: [] }) end it 'returns nil' do diff --git a/spec/stack_master/parameter_resolvers/latest_container_spec.rb b/spec/stack_master/parameter_resolvers/latest_container_spec.rb index 76bb1b90..5333da53 100644 --- a/spec/stack_master/parameter_resolvers/latest_container_spec.rb +++ b/spec/stack_master/parameter_resolvers/latest_container_spec.rb @@ -10,10 +10,16 @@ context 'when matches are found' do before do - ecr.stub_responses(:describe_images, next_token: nil, image_details: [ - { registry_id: '012345678910', image_digest: 'sha256:decafc0ffee', image_pushed_at: Time.utc(2015,1,2,0,0), image_tags: ['v1'] }, - { registry_id: '012345678910', image_digest: 'sha256:deadbeef', image_pushed_at: Time.utc(2015,1,3,0,0), image_tags: ['v2'] } - ]) + ecr.stub_responses( + :describe_images, + { + next_token: nil, + image_details: [ + { registry_id: '012345678910', image_digest: 'sha256:decafc0ffee', image_pushed_at: Time.utc(2015,1,2,0,0), image_tags: ['v1'] }, + { registry_id: '012345678910', image_digest: 'sha256:deadbeef', image_pushed_at: Time.utc(2015,1,3,0,0), image_tags: ['v2'] } + ] + } + ) end it 'returns the latest one' do @@ -23,7 +29,7 @@ context 'when no matches are found' do before do - ecr.stub_responses(:describe_images, next_token: nil, image_details: []) + ecr.stub_responses(:describe_images, { next_token: nil, image_details: [] }) end it 'returns nil' do @@ -33,10 +39,16 @@ context 'when a tag is passed in' do before do - ecr.stub_responses(:describe_images, next_token: nil, image_details: [ - { registry_id: '012345678910', image_digest: 'sha256:decafc0ffee', image_pushed_at: Time.utc(2015,1,2,0,0), image_tags: ['v1', 'production'] }, - { registry_id: '012345678910', image_digest: 'sha256:deadbeef', image_pushed_at: Time.utc(2015,1,3,0,0), image_tags: ['v2'] } - ]) + ecr.stub_responses( + :describe_images, + { + next_token: nil, + image_details: [ + { registry_id: '012345678910', image_digest: 'sha256:decafc0ffee', image_pushed_at: Time.utc(2015,1,2,0,0), image_tags: ['v1', 'production'] }, + { registry_id: '012345678910', image_digest: 'sha256:deadbeef', image_pushed_at: Time.utc(2015,1,3,0,0), image_tags: ['v2'] } + ] + } + ) end context 'when image exists' do @@ -54,13 +66,19 @@ context 'when registry_id is passed in' do before do - ecr.stub_responses(:describe_images, next_token: nil, image_details: [ - { registry_id: '012345678910', image_digest: 'sha256:decafc0ffee', image_pushed_at: Time.utc(2015,1,2,0,0), image_tags: ['v1'] }, - ]) + ecr.stub_responses( + :describe_images, + { + next_token: nil, + image_details: [ + { registry_id: '012345678910', image_digest: 'sha256:decafc0ffee', image_pushed_at: Time.utc(2015,1,2,0,0), image_tags: ['v1'] }, + ] + } + ) end it 'passes registry_id to describe_images' do - expect(ecr).to receive(:describe_images).with(repository_name: "foo", registry_id: "012345678910", next_token: nil, filter: {:tag_status=>"TAGGED"}) + expect(ecr).to receive(:describe_images).with({repository_name: "foo", registry_id: "012345678910", next_token: nil, filter: {:tag_status=>"TAGGED"}}) resolver.resolve({'repository_name' => 'foo', 'registry_id' => '012345678910'}) end end diff --git a/spec/stack_master/parameter_resolvers/stack_output_spec.rb b/spec/stack_master/parameter_resolvers/stack_output_spec.rb index ef0bf9e0..74ec2e0c 100644 --- a/spec/stack_master/parameter_resolvers/stack_output_spec.rb +++ b/spec/stack_master/parameter_resolvers/stack_output_spec.rb @@ -38,7 +38,7 @@ def resolve(value) before do allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf) - cf.stub_responses(:describe_stacks, stacks: stacks) + cf.stub_responses(:describe_stacks, { stacks: stacks }) end context 'the stack and output exist' do @@ -53,13 +53,13 @@ def resolve(value) end it 'caches stacks for the lifetime of the instance' do - expect(cf).to receive(:describe_stacks).with(stack_name: 'my-stack').and_call_original.once + expect(cf).to receive(:describe_stacks).with({ stack_name: 'my-stack' }).and_call_original.once resolver.resolve(value) resolver.resolve(value) end it "caches stacks by region" do - expect(cf).to receive(:describe_stacks).with(stack_name: 'my-stack').and_call_original.twice + expect(cf).to receive(:describe_stacks).with({ stack_name: 'my-stack' }).and_call_original.twice resolver.resolve(value) resolver.resolve(value) resolver.resolve("ap-southeast-2:#{value}") @@ -79,7 +79,7 @@ def resolve(value) end it "caches stacks by credentials" do - expect(cf).to receive(:describe_stacks).with(stack_name: 'my-stack').and_call_original.twice + expect(cf).to receive(:describe_stacks).with({ stack_name: 'my-stack' }).and_call_original.twice resolver.resolve(value) resolver.resolve(value) Aws.config[:credentials] = "my-credentials" @@ -132,7 +132,7 @@ def resolve(value) before do allow(Aws::CloudFormation::Client).to receive(:new).and_return(cf) - cf.stub_responses(:describe_stacks, stacks: stacks) + cf.stub_responses(:describe_stacks, { stacks: stacks }) end context 'the stack and output exist' do diff --git a/spec/stack_master/role_assumer_spec.rb b/spec/stack_master/role_assumer_spec.rb index cc6d071e..eea7769e 100644 --- a/spec/stack_master/role_assumer_spec.rb +++ b/spec/stack_master/role_assumer_spec.rb @@ -16,11 +16,11 @@ end it 'calls the assume role API once' do - expect(Aws::AssumeRoleCredentials).to receive(:new).with( + expect(Aws::AssumeRoleCredentials).to receive(:new).with({ region: instance_of(String), role_arn: role_arn, role_session_name: instance_of(String) - ).once + }).once assume_role end @@ -34,11 +34,11 @@ end it 'assumes the role before calling block' do - expect(Aws::AssumeRoleCredentials).to receive(:new).with( + expect(Aws::AssumeRoleCredentials).to receive(:new).with({ region: instance_of(String), role_arn: role_arn, role_session_name: instance_of(String) - ).ordered + }).ordered expect(my_block).to receive(:call).ordered assume_role @@ -46,11 +46,11 @@ it "uses the cloudformation driver's region" do StackMaster.cloud_formation_driver.set_region('my-region') - expect(Aws::AssumeRoleCredentials).to receive(:new).with( + expect(Aws::AssumeRoleCredentials).to receive(:new).with({ region: 'my-region', role_arn: instance_of(String), role_session_name: instance_of(String) - ) + }) assume_role end @@ -130,11 +130,11 @@ describe 'when called multiple times' do context 'with the same account and role' do it 'assumes the role once' do - expect(Aws::AssumeRoleCredentials).to receive(:new).with( + expect(Aws::AssumeRoleCredentials).to receive(:new).with({ region: instance_of(String), role_arn: role_arn, role_session_name: instance_of(String) - ).once + }).once role_assumer.assume_role(account, role, &my_block) role_assumer.assume_role(account, role, &my_block) @@ -143,16 +143,16 @@ context 'with a different account' do it 'assumes each role once' do - expect(Aws::AssumeRoleCredentials).to receive(:new).with( + expect(Aws::AssumeRoleCredentials).to receive(:new).with({ region: instance_of(String), role_arn: role_arn, role_session_name: instance_of(String) - ).once - expect(Aws::AssumeRoleCredentials).to receive(:new).with( + }).once + expect(Aws::AssumeRoleCredentials).to receive(:new).with({ region: instance_of(String), role_arn: "arn:aws:iam::another-account:role/#{role}", role_session_name: instance_of(String) - ).once + }).once role_assumer.assume_role(account, role, &my_block) role_assumer.assume_role('another-account', role, &my_block) @@ -161,16 +161,16 @@ context 'with a different role' do it 'assumes each role once' do - expect(Aws::AssumeRoleCredentials).to receive(:new).with( + expect(Aws::AssumeRoleCredentials).to receive(:new).with({ region: instance_of(String), role_arn: role_arn, role_session_name: instance_of(String) - ).once - expect(Aws::AssumeRoleCredentials).to receive(:new).with( + }).once + expect(Aws::AssumeRoleCredentials).to receive(:new).with({ region: instance_of(String), role_arn: "arn:aws:iam::#{account}:role/another-role", role_session_name: instance_of(String) - ).once + }).once role_assumer.assume_role(account, role, &my_block) role_assumer.assume_role(account, 'another-role', &my_block) diff --git a/spec/stack_master/stack_spec.rb b/spec/stack_master/stack_spec.rb index e6ff5514..d3a799a7 100644 --- a/spec/stack_master/stack_spec.rb +++ b/spec/stack_master/stack_spec.rb @@ -19,9 +19,24 @@ ] } before do - cf.stub_responses(:describe_stacks, stacks: [{stack_id: stack_id, stack_name: stack_name, creation_time: Time.now, stack_status: 'UPDATE_COMPLETE', parameters: parameters, notification_arns: ['test_arn'], role_arn: 'test_service_role_arn'}]) - cf.stub_responses(:get_template, template_body: "{}") - cf.stub_responses(:get_stack_policy, stack_policy_body: stack_policy_body) + cf.stub_responses( + :describe_stacks, + { + stacks: [ + { + stack_id: stack_id, + stack_name: stack_name, + creation_time: Time.now, + stack_status: 'UPDATE_COMPLETE', + parameters: parameters, + notification_arns: ['test_arn'], + role_arn: 'test_service_role_arn' + } + ] + } + ) + cf.stub_responses(:get_template, { template_body: "{}" }) + cf.stub_responses(:get_stack_policy, { stack_policy_body: stack_policy_body }) end it 'returns a stack object with a stack_id' do @@ -62,7 +77,7 @@ context 'when CF returns no stacks' do before do - cf.stub_responses(:describe_stacks, stacks: []) + cf.stub_responses(:describe_stacks, { stacks: [] }) end it 'returns nil' do diff --git a/spec/support/aws_stubs.rb b/spec/support/aws_stubs.rb index 6e17da5e..7b90e294 100644 --- a/spec/support/aws_stubs.rb +++ b/spec/support/aws_stubs.rb @@ -2,18 +2,21 @@ module AwsHelpers def stub_drift_detection(stack_drift_detection_id: "1", stack_drift_status: "IN_SYNC") - cfn.stub_responses(:detect_stack_drift, - stack_drift_detection_id: stack_drift_detection_id) - cfn.stub_responses(:describe_stack_drift_detection_status, - stack_id: "1", - timestamp: Time.now, - stack_drift_detection_id: stack_drift_detection_id, - stack_drift_status: stack_drift_status, - detection_status: "DETECTION_COMPLETE") + cfn.stub_responses(:detect_stack_drift, { stack_drift_detection_id: stack_drift_detection_id }) + cfn.stub_responses( + :describe_stack_drift_detection_status, + { + stack_id: "1", + timestamp: Time.now, + stack_drift_detection_id: stack_drift_detection_id, + stack_drift_status: stack_drift_status, + detection_status: "DETECTION_COMPLETE" + } + ) end def stub_stack_resource_drift(stack_name:, stack_resource_drifts:) - cfn.stub_responses(:describe_stack_resource_drifts, stack_resource_drifts: stack_resource_drifts) + cfn.stub_responses(:describe_stack_resource_drifts, { stack_resource_drifts: stack_resource_drifts }) end end