-
Notifications
You must be signed in to change notification settings - Fork 47
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
Add ability to restrict which accounts can work with stacks #283
Changes from 12 commits
aef2c38
d3fa4ee
1a92477
c72a000
f79ef55
abbbd3e
4eff0f9
056aeea
83bd9a6
b30dede
3ee8a08
6351741
4233345
f02603c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
module StackMaster | ||
class Identity | ||
def running_in_allowed_account?(allowed_accounts) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems odd to pass a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea. Done in b30dede. |
||
allowed_accounts.nil? || allowed_accounts.empty? || allowed_accounts.include?(account) | ||
end | ||
|
||
def account | ||
@account ||= sts.get_caller_identity.account | ||
end | ||
|
||
private | ||
|
||
attr_reader :sts | ||
|
||
def region | ||
@region ||= ENV['AWS_REGION'] || Aws.config[:region] || Aws.shared_config.region || 'us-east-1' | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method isn't necessary. If we don't specify a region the SDK does a lookup for us automatically. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right it does, however I added this method to ensure that a default region is used if it couldn't find a region from the environment. It's also the same as the CloudFormation driver class except for the default value. This was me being more defensive, but happy to remove it if you think it'll be fine without it? |
||
|
||
def sts | ||
@sts ||= Aws::STS::Client.new(region: region) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,8 @@ | |
subject(:status) { described_class.new(config, false) } | ||
let(:config) { instance_double(StackMaster::Config, stacks: stacks) } | ||
let(:stacks) { [stack_definition_1, stack_definition_2] } | ||
let(:stack_definition_1) { double(:stack_definition_1, region: 'us-east-1', stack_name: 'stack1') } | ||
let(:stack_definition_2) { double(:stack_definition_2, region: 'us-east-1', stack_name: 'stack2', stack_status: 'CREATE_COMPLETE') } | ||
let(:stack_definition_1) { double(:stack_definition_1, region: 'us-east-1', stack_name: 'stack1', allowed_accounts: []) } | ||
let(:stack_definition_2) { double(:stack_definition_2, region: 'us-east-1', stack_name: 'stack2', stack_status: 'CREATE_COMPLETE', allowed_accounts: []) } | ||
let(:cf) { Aws::CloudFormation::Client.new(region: 'us-east-1') } | ||
|
||
before do | ||
|
@@ -23,7 +23,13 @@ | |
let(:proposed_stack2) { double(:proposed_stack2, template_body: "{}", template_format: :json, parameters_with_defaults: {a: 1}) } | ||
|
||
it "returns the status of call stacks" do | ||
out = "REGION | STACK_NAME | STACK_STATUS | DIFFERENT\n----------|------------|-----------------|----------\nus-east-1 | stack1 | UPDATE_COMPLETE | No \nus-east-1 | stack2 | CREATE_COMPLETE | Yes \n * No echo parameters can't be diffed\n" | ||
out = <<~OUTPUT | ||
REGION | STACK_NAME | STACK_STATUS | DIFFERENT | ||
----------|------------|-----------------|---------- | ||
us-east-1 | stack1 | UPDATE_COMPLETE | No | ||
us-east-1 | stack2 | CREATE_COMPLETE | Yes | ||
* No echo parameters can't be diffed | ||
OUTPUT | ||
expect { status.perform }.to output(out).to_stdout | ||
end | ||
end | ||
|
@@ -35,10 +41,66 @@ | |
let(:proposed_stack2) { double(:proposed_stack2, template_body: "{}", template_format: :json, parameters_with_defaults: {a: 1}) } | ||
|
||
it "returns the status of call stacks" do | ||
out = "REGION | STACK_NAME | STACK_STATUS | DIFFERENT\n----------|------------|-----------------|----------\nus-east-1 | stack1 | UPDATE_COMPLETE | Yes \nus-east-1 | stack2 | CREATE_COMPLETE | No \n * No echo parameters can't be diffed\n" | ||
out = <<~OUTPUT | ||
REGION | STACK_NAME | STACK_STATUS | DIFFERENT | ||
----------|------------|-----------------|---------- | ||
us-east-1 | stack1 | UPDATE_COMPLETE | Yes | ||
us-east-1 | stack2 | CREATE_COMPLETE | No | ||
* No echo parameters can't be diffed | ||
OUTPUT | ||
expect { status.perform }.to output(out).to_stdout | ||
end | ||
end | ||
|
||
context 'when identity account is not allowed' do | ||
let(:sts) { Aws::STS::Client.new(stub_responses: true) } | ||
let(:stack_definition_1) { double(:stack_definition_1, region: 'us-east-1', stack_name: 'stack1', allowed_accounts: ['not-account-id']) } | ||
let(:stack1) { double(:stack1, template_body: '{"foo": "bar"}', template_hash: {foo: 'bar'}, template_format: :json, parameters_with_defaults: {a: 1}, stack_status: 'UPDATE_COMPLETE') } | ||
let(:stack2) { double(:stack2, template_body: '{}', template_hash: {}, template_format: :json, parameters_with_defaults: {a: 1}, stack_status: 'CREATE_COMPLETE') } | ||
let(:proposed_stack1) { double(:proposed_stack1, template_body: "{}", template_format: :json, parameters_with_defaults: {a: 1}) } | ||
let(:proposed_stack2) { double(:proposed_stack2, template_body: "{}", template_format: :json, parameters_with_defaults: {a: 1}) } | ||
|
||
before do | ||
allow(Aws::STS::Client).to receive(:new).and_return(sts) | ||
sts.stub_responses(:get_caller_identity, { | ||
account: 'account-id', | ||
arn: 'an-arn', | ||
user_id: 'a-user-id' | ||
}) | ||
end | ||
|
||
it 'sets stack status and different fields accordingly' do | ||
out = <<~OUTPUT | ||
REGION | STACK_NAME | STACK_STATUS | DIFFERENT | ||
----------|------------|--------------------|---------- | ||
us-east-1 | stack1 | Disallowed account | N/A | ||
us-east-1 | stack2 | UPDATE_COMPLETE | Yes | ||
* No echo parameters can't be diffed | ||
OUTPUT | ||
expect { status.perform }.to output(out).to_stdout | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this test expect an error to be returned? If the account IDs don't match it shouldn't print the status? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a got a special case now: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What @viraptor said. Alternatively, I could leave them blank instead? I didn't go with that option because I thought it would be better to let the user know why no status is included for that stack. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another option is to include There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right I see. Are we able to have an integration test for when someone runs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea. Added integration tests in f02603c. |
||
end | ||
|
||
context 'when --skip-account-check flag is set' do | ||
before do | ||
StackMaster.skip_account_check! | ||
end | ||
|
||
after do | ||
StackMaster.reset_flags | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think spec_helper already handles this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't handle this. The cucumber features do though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right you are |
||
end | ||
|
||
it "returns the status of call stacks" do | ||
out = <<~OUTPUT | ||
REGION | STACK_NAME | STACK_STATUS | DIFFERENT | ||
----------|------------|-----------------|---------- | ||
us-east-1 | stack1 | UPDATE_COMPLETE | Yes | ||
us-east-1 | stack2 | CREATE_COMPLETE | No | ||
* No echo parameters can't be diffed | ||
OUTPUT | ||
expect { status.perform }.to output(out).to_stdout | ||
end | ||
end | ||
end | ||
end | ||
|
||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From just reading this I'm still not entirely sure what the behaviour will be. Does it allow applying
myapp-db
to account555555555
or not?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No it doesn't as the account IDs specified in the stack definition overrides the stack defaults.
I've reworded this section and example stack below. Let me know if it clarifies things.
See 4233345.