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) =>
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 }) => {
......
......@@ -29,7 +29,7 @@ module Clusters
rescue *ERRORS => e
Gitlab::ErrorTracking.track_exception(e)
Response.new(:unprocessable_entity, {})
Response.new(:unprocessable_entity, response_details(e))
end
private
......@@ -47,6 +47,18 @@ module Clusters
def credentials
Clusters::Aws::FetchCredentialsService.new(role).execute
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
---
title: 'EKS: Provide user feedback on AWS authorization errors'
merge_request: 49278
author:
type: changed
......@@ -195,7 +195,38 @@ describe('EKS Cluster Store Actions', () => {
payload,
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
end
context 'errors' do
let(:body) { {} }
shared_examples 'bad request' do
it 'returns an empty hash' do
expect(subject.status).to eq(:unprocessable_entity)
expect(subject.body).to eq({})
expect(subject.body).to eq(body)
end
it 'logs the error' do
......@@ -58,6 +60,7 @@ RSpec.describe Clusters::Aws::AuthorizeRoleService do
context 'supplied ARN is invalid' do
let(:role_arn) { 'invalid' }
let(:body) { { message: 'Validation failed: Role arn must be a valid Amazon Resource Name' } }
include_examples 'bad request'
end
......@@ -73,6 +76,14 @@ RSpec.describe Clusters::Aws::AuthorizeRoleService do
include_examples 'bad request'
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
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