Commit 0fe0197e authored by Stan Hu's avatar Stan Hu

EKS: Provide user feedback on AWS authorization errors

Previously if you did configure your AWS credentials properly in the EKS
integration, you see an opaque error:

```
Error: Request failed with status code 422
```

This change now provides more direct feedback to the user, such as:

Validation errors:

```
Validation failed: Role arn must be a valid Amazon Resource Name
```

Access denied errors:

```
Access denied: User: arn:aws:iam::123456789012:user/stanhu is not
authorized to perform: sts:AssumeRole on resource:
arn:aws:iam::123456789012:role/stanhu-eks-role
```

Relates to https://gitlab.com/gitlab-org/gitlab/-/issues/291016
parent aec60d60
...@@ -42,7 +42,13 @@ export const createRole = ({ dispatch, state: { createRolePath } }, payload) => ...@@ -42,7 +42,13 @@ export const createRole = ({ dispatch, state: { createRolePath } }, payload) =>
dispatch('createRoleSuccess', awsData); dispatch('createRoleSuccess', awsData);
}) })
.catch(error => dispatch('createRoleError', { error })); .catch(error => {
let message = error;
if (error.response && error.response.data && error.response.data.message) {
message = error.response.data.message;
}
dispatch('createRoleError', { error: message });
});
}; };
export const requestCreateRole = ({ commit }) => { export const requestCreateRole = ({ commit }) => {
......
...@@ -29,7 +29,7 @@ module Clusters ...@@ -29,7 +29,7 @@ module Clusters
rescue *ERRORS => e rescue *ERRORS => e
Gitlab::ErrorTracking.track_exception(e) Gitlab::ErrorTracking.track_exception(e)
Response.new(:unprocessable_entity, {}) Response.new(:unprocessable_entity, response_details(e))
end end
private private
...@@ -47,6 +47,18 @@ module Clusters ...@@ -47,6 +47,18 @@ module Clusters
def credentials def credentials
Clusters::Aws::FetchCredentialsService.new(role).execute Clusters::Aws::FetchCredentialsService.new(role).execute
end end
def response_details(exception)
message =
case exception
when ActiveRecord::RecordInvalid
exception.message
when ::Aws::STS::Errors::AccessDenied
"Access denied: #{exception.message}"
end
{ message: message }.compact
end
end end
end end
end end
---
title: 'EKS: Provide user feedback on AWS authorization errors'
merge_request: 49278
author:
type: changed
...@@ -195,7 +195,38 @@ describe('EKS Cluster Store Actions', () => { ...@@ -195,7 +195,38 @@ describe('EKS Cluster Store Actions', () => {
payload, payload,
state, state,
[], [],
[{ type: 'requestCreateRole' }, { type: 'createRoleError', payload: { error } }], [
{ type: 'requestCreateRole' },
{ type: 'createRoleError', payload: { error: 'Request failed with status code 400' } },
],
));
});
describe('when request fails with a message', () => {
let error;
beforeEach(() => {
const errResp = { message: 'Something failed' };
mock
.onPost(state.createRolePath, {
role_arn: payload.roleArn,
role_external_id: payload.externalId,
region: DEFAULT_REGION,
})
.reply(4, errResp);
});
it('dispatches createRoleError action', () =>
testAction(
actions.createRole,
payload,
state,
[],
[
{ type: 'requestCreateRole' },
{ type: 'createRoleError', payload: { error: 'Something failed' } },
],
)); ));
}); });
}); });
......
...@@ -37,10 +37,12 @@ RSpec.describe Clusters::Aws::AuthorizeRoleService do ...@@ -37,10 +37,12 @@ RSpec.describe Clusters::Aws::AuthorizeRoleService do
end end
context 'errors' do context 'errors' do
let(:body) { {} }
shared_examples 'bad request' do shared_examples 'bad request' do
it 'returns an empty hash' do it 'returns an empty hash' do
expect(subject.status).to eq(:unprocessable_entity) expect(subject.status).to eq(:unprocessable_entity)
expect(subject.body).to eq({}) expect(subject.body).to eq(body)
end end
it 'logs the error' do it 'logs the error' do
...@@ -58,6 +60,7 @@ RSpec.describe Clusters::Aws::AuthorizeRoleService do ...@@ -58,6 +60,7 @@ RSpec.describe Clusters::Aws::AuthorizeRoleService do
context 'supplied ARN is invalid' do context 'supplied ARN is invalid' do
let(:role_arn) { 'invalid' } let(:role_arn) { 'invalid' }
let(:body) { { message: 'Validation failed: Role arn must be a valid Amazon Resource Name' } }
include_examples 'bad request' include_examples 'bad request'
end end
...@@ -73,6 +76,14 @@ RSpec.describe Clusters::Aws::AuthorizeRoleService do ...@@ -73,6 +76,14 @@ RSpec.describe Clusters::Aws::AuthorizeRoleService do
include_examples 'bad request' include_examples 'bad request'
end end
context 'error in assuming role' do
let(:message) { "User foo is not authorized to perform: sts:AssumeRole on resource bar" }
let(:error) { Aws::STS::Errors::AccessDenied.new(nil, message) }
let(:body) { { message: "Access denied: #{message}" } }
include_examples 'bad request'
end
context 'credentials not configured' do context 'credentials not configured' do
let(:error) { Aws::Errors::MissingCredentialsError.new('error message') } let(:error) { Aws::Errors::MissingCredentialsError.new('error message') }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment