Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-12-12 03:07:43 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-12 03:07:43 +0300
commit2e3cbf7d89815e2915f77677388c49b48f8d20c3 (patch)
tree03bdbc99e829295e8077b2ec4032300c15b48e37 /spec
parente44bb86539a8fb4cfb06dfe281632b6f206bd0a7 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/admin/clusters_controller_spec.rb28
-rw-r--r--spec/controllers/groups/clusters_controller_spec.rb33
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb33
-rw-r--r--spec/controllers/projects/deploy_keys_controller_spec.rb26
-rw-r--r--spec/controllers/projects/error_tracking_controller_spec.rb21
-rw-r--r--spec/factories/error_tracking/error_event.rb40
-rw-r--r--spec/fixtures/api/schemas/error_tracking/error_stack_trace.json2
-rw-r--r--spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js16
-rw-r--r--spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js193
-rw-r--r--spec/frontend/create_cluster/eks_cluster/store/actions_spec.js21
-rw-r--r--spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js12
-rw-r--r--spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb58
-rw-r--r--spec/presenters/instance_clusterable_presenter_spec.rb14
-rw-r--r--spec/presenters/projects/settings/deploy_keys_presenter_spec.rb61
-rw-r--r--spec/requests/api/users_spec.rb19
-rw-r--r--spec/services/clusters/aws/authorize_role_service_spec.rb91
-rw-r--r--spec/services/clusters/aws/fetch_credentials_service_spec.rb18
-rw-r--r--spec/services/clusters/aws/proxy_service_spec.rb210
-rw-r--r--spec/services/clusters/kubernetes_spec.rb19
19 files changed, 467 insertions, 448 deletions
diff --git a/spec/controllers/admin/clusters_controller_spec.rb b/spec/controllers/admin/clusters_controller_spec.rb
index 4184c7e611a..f27519496df 100644
--- a/spec/controllers/admin/clusters_controller_spec.rb
+++ b/spec/controllers/admin/clusters_controller_spec.rb
@@ -381,10 +381,15 @@ describe Admin::ClustersController do
post :authorize_aws_role, params: params
end
+ before do
+ allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
+ .and_return(double(execute: double))
+ end
+
it 'creates an Aws::Role record' do
expect { go }.to change { Aws::Role.count }
- expect(response.status).to eq 201
+ expect(response.status).to eq 200
role = Aws::Role.last
expect(role.user).to eq admin
@@ -409,27 +414,6 @@ describe Admin::ClustersController do
end
end
- describe 'DELETE revoke AWS role for EKS cluster' do
- let!(:role) { create(:aws_role, user: admin) }
-
- def go
- delete :revoke_aws_role
- end
-
- it 'deletes the Aws::Role record' do
- expect { go }.to change { Aws::Role.count }
-
- expect(response.status).to eq 204
- expect(admin.reload_aws_role).to be_nil
- end
-
- describe 'security' do
- it { expect { go }.to be_allowed_for(:admin) }
- it { expect { go }.to be_denied_for(:user) }
- it { expect { go }.to be_denied_for(:external) }
- end
- end
-
describe 'DELETE clear cluster cache' do
let(:cluster) { create(:cluster, :instance) }
let!(:kubernetes_namespace) do
diff --git a/spec/controllers/groups/clusters_controller_spec.rb b/spec/controllers/groups/clusters_controller_spec.rb
index d47122f051e..cf90d388a61 100644
--- a/spec/controllers/groups/clusters_controller_spec.rb
+++ b/spec/controllers/groups/clusters_controller_spec.rb
@@ -443,10 +443,15 @@ describe Groups::ClustersController do
post :authorize_aws_role, params: params.merge(group_id: group)
end
+ before do
+ allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
+ .and_return(double(execute: double))
+ end
+
it 'creates an Aws::Role record' do
expect { go }.to change { Aws::Role.count }
- expect(response.status).to eq 201
+ expect(response.status).to eq 200
role = Aws::Role.last
expect(role.user).to eq user
@@ -476,32 +481,6 @@ describe Groups::ClustersController do
end
end
- describe 'DELETE revoke AWS role for EKS cluster' do
- let!(:role) { create(:aws_role, user: user) }
-
- def go
- delete :revoke_aws_role, params: { group_id: group }
- end
-
- it 'deletes the Aws::Role record' do
- expect { go }.to change { Aws::Role.count }
-
- expect(response.status).to eq 204
- expect(user.reload_aws_role).to be_nil
- end
-
- describe 'security' do
- it { expect { go }.to be_allowed_for(:admin) }
- it { expect { go }.to be_allowed_for(:owner).of(group) }
- it { expect { go }.to be_allowed_for(:maintainer).of(group) }
- it { expect { go }.to be_denied_for(:developer).of(group) }
- it { expect { go }.to be_denied_for(:reporter).of(group) }
- it { expect { go }.to be_denied_for(:guest).of(group) }
- it { expect { go }.to be_denied_for(:user) }
- it { expect { go }.to be_denied_for(:external) }
- end
- end
-
describe 'DELETE clear cluster cache' do
let(:cluster) { create(:cluster, :group, groups: [group]) }
let!(:kubernetes_namespace) do
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index 5efac44615f..ab8bfc0cabe 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -444,10 +444,15 @@ describe Projects::ClustersController do
post :authorize_aws_role, params: params.merge(namespace_id: project.namespace, project_id: project)
end
+ before do
+ allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
+ .and_return(double(execute: double))
+ end
+
it 'creates an Aws::Role record' do
expect { go }.to change { Aws::Role.count }
- expect(response.status).to eq 201
+ expect(response.status).to eq 200
role = Aws::Role.last
expect(role.user).to eq user
@@ -477,32 +482,6 @@ describe Projects::ClustersController do
end
end
- describe 'DELETE revoke AWS role for EKS cluster' do
- let!(:role) { create(:aws_role, user: user) }
-
- def go
- delete :revoke_aws_role, params: { namespace_id: project.namespace, project_id: project }
- end
-
- it 'deletes the Aws::Role record' do
- expect { go }.to change { Aws::Role.count }
-
- expect(response.status).to eq 204
- expect(user.reload_aws_role).to be_nil
- end
-
- describe 'security' do
- it { expect { go }.to be_allowed_for(:admin) }
- it { expect { go }.to be_allowed_for(:owner).of(project) }
- it { expect { go }.to be_allowed_for(:maintainer).of(project) }
- it { expect { go }.to be_denied_for(:developer).of(project) }
- it { expect { go }.to be_denied_for(:reporter).of(project) }
- it { expect { go }.to be_denied_for(:guest).of(project) }
- it { expect { go }.to be_denied_for(:user) }
- it { expect { go }.to be_denied_for(:external) }
- end
- end
-
describe 'DELETE clear cluster cache' do
let(:cluster) { create(:cluster, :project, projects: [project]) }
let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, cluster: cluster) }
diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb
index 8b1ca2efab2..2c7c99eabf6 100644
--- a/spec/controllers/projects/deploy_keys_controller_spec.rb
+++ b/spec/controllers/projects/deploy_keys_controller_spec.rb
@@ -46,17 +46,27 @@ describe Projects::DeployKeysController do
create(:deploy_keys_project, project: project_private, deploy_key: create(:another_deploy_key))
end
- before do
- project2.add_developer(user)
+ context 'when user has access to all projects where deploy keys are used' do
+ before do
+ project2.add_developer(user)
+ end
+
+ it 'returns json in a correct format' do
+ get :index, params: params.merge(format: :json)
+
+ expect(json_response.keys).to match_array(%w(enabled_keys available_project_keys public_keys))
+ expect(json_response['enabled_keys'].count).to eq(1)
+ expect(json_response['available_project_keys'].count).to eq(1)
+ expect(json_response['public_keys'].count).to eq(1)
+ end
end
- it 'returns json in a correct format' do
- get :index, params: params.merge(format: :json)
+ context 'when user has no access to all projects where deploy keys are used' do
+ it 'returns json in a correct format' do
+ get :index, params: params.merge(format: :json)
- expect(json_response.keys).to match_array(%w(enabled_keys available_project_keys public_keys))
- expect(json_response['enabled_keys'].count).to eq(1)
- expect(json_response['available_project_keys'].count).to eq(1)
- expect(json_response['public_keys'].count).to eq(1)
+ expect(json_response['available_project_keys'].count).to eq(0)
+ end
end
end
end
diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb
index ab99e44e4ca..e5585d7b52d 100644
--- a/spec/controllers/projects/error_tracking_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking_controller_spec.rb
@@ -384,6 +384,10 @@ describe Projects::ErrorTrackingController do
).permit!
end
+ subject(:get_stack_trace) do
+ get :stack_trace, params: issue_params(issue_id: issue_id, format: :json)
+ end
+
before do
expect(ErrorTracking::IssueLatestEventService)
.to receive(:new).with(project, user, permitted_params)
@@ -398,7 +402,7 @@ describe Projects::ErrorTrackingController do
end
it 'returns no data' do
- get :stack_trace, params: issue_params(issue_id: issue_id, format: :json)
+ get_stack_trace
expect(response).to have_gitlab_http_status(:no_content)
end
@@ -408,16 +412,21 @@ describe Projects::ErrorTrackingController do
before do
expect(issue_stack_trace_service).to receive(:execute)
.and_return(status: :success, latest_event: error_event)
+
+ get_stack_trace
end
let(:error_event) { build(:error_tracking_error_event) }
it 'returns an error' do
- get :stack_trace, params: issue_params(issue_id: issue_id, format: :json)
-
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('error_tracking/issue_stack_trace')
- expect(json_response['error']).to eq(error_event.as_json)
+ end
+
+ it 'highlights stack trace source code' do
+ expect(json_response['error']).to eq(
+ Gitlab::ErrorTracking::StackTraceHighlightDecorator.decorate(error_event).as_json
+ )
end
end
@@ -431,7 +440,7 @@ describe Projects::ErrorTrackingController do
end
it 'returns 400 with message' do
- get :stack_trace, params: issue_params(issue_id: issue_id, format: :json)
+ get_stack_trace
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to eq(error_message)
@@ -450,7 +459,7 @@ describe Projects::ErrorTrackingController do
end
it 'returns http_status with message' do
- get :stack_trace, params: issue_params(issue_id: issue_id, format: :json)
+ get_stack_trace
expect(response).to have_gitlab_http_status(http_status)
expect(json_response['message']).to eq(error_message)
diff --git a/spec/factories/error_tracking/error_event.rb b/spec/factories/error_tracking/error_event.rb
index 44c127e7bf5..c4dcd67bc9f 100644
--- a/spec/factories/error_tracking/error_event.rb
+++ b/spec/factories/error_tracking/error_event.rb
@@ -5,12 +5,40 @@ FactoryBot.define do
issue_id { 'id' }
date_received { Time.now.iso8601 }
stack_trace_entries do
- {
- 'stacktrace' =>
- {
- 'frames' => [{ 'file' => 'test.rb' }]
- }
- }
+ [
+ {
+ 'function' => 'puts',
+ 'lineNo' => 14,
+ 'filename' => 'hello_world.rb',
+ 'context' => [
+ [10, "# Ruby example\n"],
+ [11, "class HelloWorld\n"],
+ [12, " def self.message\n"],
+ [13, " @name = 'World'\n"],
+ [14, " puts \"Hello \#{@name}\"\n"],
+ [15, " end\n"],
+ [16, "end\n"]
+ ]
+ },
+ {
+ 'function' => 'print',
+ 'lineNo' => 6,
+ 'filename' => 'HelloWorld.swift',
+ 'context' => [
+ [1, "// Swift example\n"],
+ [2, "struct HelloWorld {\n"],
+ [3, " let name = \"World\"\n"],
+ [4, "\n"],
+ [5, " static func message() {\n"],
+ [6, " print(\"Hello, \\(self.name)\")\n"],
+ [7, " }\n"],
+ [8, "}\n"]
+ ]
+ },
+ {
+ 'filename' => 'blank.txt'
+ }
+ ]
end
skip_create
diff --git a/spec/fixtures/api/schemas/error_tracking/error_stack_trace.json b/spec/fixtures/api/schemas/error_tracking/error_stack_trace.json
index a684dd0496a..e2eeefcdd53 100644
--- a/spec/fixtures/api/schemas/error_tracking/error_stack_trace.json
+++ b/spec/fixtures/api/schemas/error_tracking/error_stack_trace.json
@@ -7,7 +7,7 @@
],
"properties": {
"issue_id": { "type": ["string", "integer"] },
- "stack_trace_entries": { "type": "object" },
+ "stack_trace_entries": { "type": "array" },
"date_received": { "type": "string" }
},
"additionalProperties": false
diff --git a/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js b/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js
index 25d613d64ed..d3992c6751c 100644
--- a/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js
@@ -27,13 +27,11 @@ describe('EksClusterConfigurationForm', () => {
let subnetsActions;
let keyPairsActions;
let securityGroupsActions;
- let instanceTypesActions;
let vm;
beforeEach(() => {
state = eksClusterFormState();
actions = {
- signOut: jest.fn(),
createCluster: jest.fn(),
setClusterName: jest.fn(),
setEnvironmentScope: jest.fn(),
@@ -66,9 +64,6 @@ describe('EksClusterConfigurationForm', () => {
securityGroupsActions = {
fetchItems: jest.fn(),
};
- instanceTypesActions = {
- fetchItems: jest.fn(),
- };
rolesState = {
...clusterDropdownStoreState(),
};
@@ -127,7 +122,6 @@ describe('EksClusterConfigurationForm', () => {
instanceTypes: {
namespaced: true,
state: instanceTypesState,
- actions: instanceTypesActions,
},
},
});
@@ -164,7 +158,6 @@ describe('EksClusterConfigurationForm', () => {
});
};
- const findSignOutButton = () => vm.find('.js-sign-out');
const findCreateClusterButton = () => vm.find('.js-create-cluster');
const findClusterNameInput = () => vm.find('[id=eks-cluster-name]');
const findEnvironmentScopeInput = () => vm.find('[id=eks-environment-scope]');
@@ -187,15 +180,6 @@ describe('EksClusterConfigurationForm', () => {
it('fetches available roles', () => {
expect(rolesActions.fetchItems).toHaveBeenCalled();
});
-
- it('fetches available instance types', () => {
- expect(instanceTypesActions.fetchItems).toHaveBeenCalled();
- });
- });
-
- it('dispatches signOut action when sign out button is clicked', () => {
- findSignOutButton().trigger('click');
- expect(actions.signOut).toHaveBeenCalled();
});
it('sets isLoadingRoles to RoleDropdown loading property', () => {
diff --git a/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js b/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js
index 146bcc04569..490a2775b67 100644
--- a/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js
@@ -1,42 +1,62 @@
-import AxiosMockAdapter from 'axios-mock-adapter';
-import awsServicesFacadeFactory from '~/create_cluster/eks_cluster/services/aws_services_facade';
-import axios from '~/lib/utils/axios_utils';
+import AWS from 'aws-sdk/global';
+import EC2 from 'aws-sdk/clients/ec2';
+import {
+ setAWSConfig,
+ fetchRoles,
+ fetchRegions,
+ fetchKeyPairs,
+ fetchVpcs,
+ fetchSubnets,
+ fetchSecurityGroups,
+ DEFAULT_REGION,
+} from '~/create_cluster/eks_cluster/services/aws_services_facade';
+
+const mockListRolesPromise = jest.fn();
+const mockDescribeRegionsPromise = jest.fn();
+const mockDescribeKeyPairsPromise = jest.fn();
+const mockDescribeVpcsPromise = jest.fn();
+const mockDescribeSubnetsPromise = jest.fn();
+const mockDescribeSecurityGroupsPromise = jest.fn();
+
+jest.mock('aws-sdk/clients/iam', () =>
+ jest.fn().mockImplementation(() => ({
+ listRoles: jest.fn().mockReturnValue({ promise: mockListRolesPromise }),
+ })),
+);
+
+jest.mock('aws-sdk/clients/ec2', () =>
+ jest.fn().mockImplementation(() => ({
+ describeRegions: jest.fn().mockReturnValue({ promise: mockDescribeRegionsPromise }),
+ describeKeyPairs: jest.fn().mockReturnValue({ promise: mockDescribeKeyPairsPromise }),
+ describeVpcs: jest.fn().mockReturnValue({ promise: mockDescribeVpcsPromise }),
+ describeSubnets: jest.fn().mockReturnValue({ promise: mockDescribeSubnetsPromise }),
+ describeSecurityGroups: jest
+ .fn()
+ .mockReturnValue({ promise: mockDescribeSecurityGroupsPromise }),
+ })),
+);
describe('awsServicesFacade', () => {
- let apiPaths;
- let axiosMock;
- let awsServices;
let region;
let vpc;
beforeEach(() => {
- apiPaths = {
- getKeyPairsPath: '/clusters/aws/api/key_pairs',
- getRegionsPath: '/clusters/aws/api/regions',
- getRolesPath: '/clusters/aws/api/roles',
- getSecurityGroupsPath: '/clusters/aws/api/security_groups',
- getSubnetsPath: '/clusters/aws/api/subnets',
- getVpcsPath: '/clusters/aws/api/vpcs',
- getInstanceTypesPath: '/clusters/aws/api/instance_types',
- };
region = 'west-1';
vpc = 'vpc-2';
- awsServices = awsServicesFacadeFactory(apiPaths);
- axiosMock = new AxiosMockAdapter(axios);
});
- describe('when fetchRegions succeeds', () => {
- let regions;
- let regionsOutput;
+ it('setAWSConfig configures AWS SDK with provided credentials and default region', () => {
+ const awsCredentials = {
+ accessKeyId: 'access-key',
+ secretAccessKey: 'secret-key',
+ sessionToken: 'session-token',
+ };
- beforeEach(() => {
- regions = [{ region_name: 'east-1' }, { region_name: 'west-2' }];
- regionsOutput = regions.map(({ region_name: name }) => ({ name, value: name }));
- axiosMock.onGet(apiPaths.getRegionsPath).reply(200, { regions });
- });
+ setAWSConfig({ awsCredentials });
- it('return list of roles where each item has a name and value', () => {
- expect(awsServices.fetchRegions()).resolves.toEqual(regionsOutput);
+ expect(AWS.config).toEqual({
+ ...awsCredentials,
+ region: DEFAULT_REGION,
});
});
@@ -46,15 +66,32 @@ describe('awsServicesFacade', () => {
beforeEach(() => {
roles = [
- { role_name: 'admin', arn: 'aws::admin' },
- { role_name: 'read-only', arn: 'aws::read-only' },
+ { RoleName: 'admin', Arn: 'aws::admin' },
+ { RoleName: 'read-only', Arn: 'aws::read-only' },
];
- rolesOutput = roles.map(({ role_name: name, arn: value }) => ({ name, value }));
- axiosMock.onGet(apiPaths.getRolesPath).reply(200, { roles });
+ rolesOutput = roles.map(({ RoleName: name, Arn: value }) => ({ name, value }));
+
+ mockListRolesPromise.mockResolvedValueOnce({ Roles: roles });
});
it('return list of regions where each item has a name and value', () => {
- expect(awsServices.fetchRoles()).resolves.toEqual(rolesOutput);
+ expect(fetchRoles()).resolves.toEqual(rolesOutput);
+ });
+ });
+
+ describe('when fetchRegions succeeds', () => {
+ let regions;
+ let regionsOutput;
+
+ beforeEach(() => {
+ regions = [{ RegionName: 'east-1' }, { RegionName: 'west-2' }];
+ regionsOutput = regions.map(({ RegionName: name }) => ({ name, value: name }));
+
+ mockDescribeRegionsPromise.mockResolvedValueOnce({ Regions: regions });
+ });
+
+ it('return list of roles where each item has a name and value', () => {
+ expect(fetchRegions()).resolves.toEqual(regionsOutput);
});
});
@@ -63,15 +100,19 @@ describe('awsServicesFacade', () => {
let keyPairsOutput;
beforeEach(() => {
- keyPairs = [{ key_pair: 'key-pair' }, { key_pair: 'key-pair-2' }];
- keyPairsOutput = keyPairs.map(({ key_name: name }) => ({ name, value: name }));
- axiosMock
- .onGet(apiPaths.getKeyPairsPath, { params: { region } })
- .reply(200, { key_pairs: keyPairs });
+ keyPairs = [{ KeyName: 'key-pair' }, { KeyName: 'key-pair-2' }];
+ keyPairsOutput = keyPairs.map(({ KeyName: name }) => ({ name, value: name }));
+
+ mockDescribeKeyPairsPromise.mockResolvedValueOnce({ KeyPairs: keyPairs });
+ });
+
+ it('instantatiates ec2 service with provided region', () => {
+ fetchKeyPairs({ region });
+ expect(EC2).toHaveBeenCalledWith({ region });
});
it('return list of key pairs where each item has a name and value', () => {
- expect(awsServices.fetchKeyPairs({ region })).resolves.toEqual(keyPairsOutput);
+ expect(fetchKeyPairs({ region })).resolves.toEqual(keyPairsOutput);
});
});
@@ -80,13 +121,37 @@ describe('awsServicesFacade', () => {
let vpcsOutput;
beforeEach(() => {
- vpcs = [{ vpc_id: 'vpc-1' }, { vpc_id: 'vpc-2' }];
- vpcsOutput = vpcs.map(({ vpc_id: name }) => ({ name, value: name }));
- axiosMock.onGet(apiPaths.getVpcsPath, { params: { region } }).reply(200, { vpcs });
+ vpcs = [{ VpcId: 'vpc-1', Tags: [] }, { VpcId: 'vpc-2', Tags: [] }];
+ vpcsOutput = vpcs.map(({ VpcId: vpcId }) => ({ name: vpcId, value: vpcId }));
+
+ mockDescribeVpcsPromise.mockResolvedValueOnce({ Vpcs: vpcs });
+ });
+
+ it('instantatiates ec2 service with provided region', () => {
+ fetchVpcs({ region });
+ expect(EC2).toHaveBeenCalledWith({ region });
});
it('return list of vpcs where each item has a name and value', () => {
- expect(awsServices.fetchVpcs({ region })).resolves.toEqual(vpcsOutput);
+ expect(fetchVpcs({ region })).resolves.toEqual(vpcsOutput);
+ });
+ });
+
+ describe('when vpcs has a Name tag', () => {
+ const vpcName = 'vpc name';
+ const vpcId = 'vpc id';
+ let vpcs;
+ let vpcsOutput;
+
+ beforeEach(() => {
+ vpcs = [{ VpcId: vpcId, Tags: [{ Key: 'Name', Value: vpcName }] }];
+ vpcsOutput = [{ name: vpcName, value: vpcId }];
+
+ mockDescribeVpcsPromise.mockResolvedValueOnce({ Vpcs: vpcs });
+ });
+
+ it('uses name tag value as the vpc name', () => {
+ expect(fetchVpcs({ region })).resolves.toEqual(vpcsOutput);
});
});
@@ -95,15 +160,14 @@ describe('awsServicesFacade', () => {
let subnetsOutput;
beforeEach(() => {
- subnets = [{ subnet_id: 'vpc-1' }, { subnet_id: 'vpc-2' }];
- subnetsOutput = subnets.map(({ subnet_id }) => ({ name: subnet_id, value: subnet_id }));
- axiosMock
- .onGet(apiPaths.getSubnetsPath, { params: { region, vpc_id: vpc } })
- .reply(200, { subnets });
+ subnets = [{ SubnetId: 'subnet-1' }, { SubnetId: 'subnet-2' }];
+ subnetsOutput = subnets.map(({ SubnetId }) => ({ name: SubnetId, value: SubnetId }));
+
+ mockDescribeSubnetsPromise.mockResolvedValueOnce({ Subnets: subnets });
});
it('return list of subnets where each item has a name and value', () => {
- expect(awsServices.fetchSubnets({ region, vpc })).resolves.toEqual(subnetsOutput);
+ expect(fetchSubnets({ region, vpc })).resolves.toEqual(subnetsOutput);
});
});
@@ -113,40 +177,19 @@ describe('awsServicesFacade', () => {
beforeEach(() => {
securityGroups = [
- { group_name: 'admin group', group_id: 'group-1' },
- { group_name: 'basic group', group_id: 'group-2' },
+ { GroupName: 'admin group', GroupId: 'group-1' },
+ { GroupName: 'basic group', GroupId: 'group-2' },
];
- securityGroupsOutput = securityGroups.map(({ group_id: value, group_name: name }) => ({
+ securityGroupsOutput = securityGroups.map(({ GroupId: value, GroupName: name }) => ({
name,
value,
}));
- axiosMock
- .onGet(apiPaths.getSecurityGroupsPath, { params: { region, vpc_id: vpc } })
- .reply(200, { security_groups: securityGroups });
- });
- it('return list of security groups where each item has a name and value', () => {
- expect(awsServices.fetchSecurityGroups({ region, vpc })).resolves.toEqual(
- securityGroupsOutput,
- );
+ mockDescribeSecurityGroupsPromise.mockResolvedValueOnce({ SecurityGroups: securityGroups });
});
- });
-
- describe('when fetchInstanceTypes succeeds', () => {
- let instanceTypes;
- let instanceTypesOutput;
- beforeEach(() => {
- instanceTypes = [{ instance_type_name: 't2.small' }, { instance_type_name: 't2.medium' }];
- instanceTypesOutput = instanceTypes.map(({ instance_type_name }) => ({
- name: instance_type_name,
- value: instance_type_name,
- }));
- axiosMock.onGet(apiPaths.getInstanceTypesPath).reply(200, { instance_types: instanceTypes });
- });
-
- it('return list of instance types where each item has a name and value', () => {
- expect(awsServices.fetchInstanceTypes()).resolves.toEqual(instanceTypesOutput);
+ it('return list of security groups where each item has a name and value', () => {
+ expect(fetchSecurityGroups({ region, vpc })).resolves.toEqual(securityGroupsOutput);
});
});
});
diff --git a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
index 578d82cfc26..fda1f71b1f9 100644
--- a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
@@ -1,5 +1,4 @@
import testAction from 'helpers/vuex_action_helper';
-
import MockAdapter from 'axios-mock-adapter';
import createState from '~/create_cluster/eks_cluster/store/state';
import * as actions from '~/create_cluster/eks_cluster/store/actions';
@@ -21,7 +20,6 @@ import {
CREATE_ROLE_ERROR,
REQUEST_CREATE_CLUSTER,
CREATE_CLUSTER_ERROR,
- SIGN_OUT,
} from '~/create_cluster/eks_cluster/store/mutation_types';
import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
@@ -64,7 +62,6 @@ describe('EKS Cluster Store Actions', () => {
state = {
...createState(),
createRolePath: '/clusters/roles/',
- signOutPath: '/aws/signout',
createClusterPath: '/clusters/',
};
});
@@ -102,6 +99,10 @@ describe('EKS Cluster Store Actions', () => {
roleArn: 'role_arn',
externalId: 'externalId',
};
+ const response = {
+ accessKeyId: 'access-key-id',
+ secretAccessKey: 'secret-key-id',
+ };
describe('when request succeeds', () => {
beforeEach(() => {
@@ -110,7 +111,7 @@ describe('EKS Cluster Store Actions', () => {
role_arn: payload.roleArn,
role_external_id: payload.externalId,
})
- .reply(201);
+ .reply(201, response);
});
it('dispatches createRoleSuccess action', () =>
@@ -119,7 +120,7 @@ describe('EKS Cluster Store Actions', () => {
payload,
state,
[],
- [{ type: 'requestCreateRole' }, { type: 'createRoleSuccess' }],
+ [{ type: 'requestCreateRole' }, { type: 'createRoleSuccess', payload: response }],
));
});
@@ -281,14 +282,4 @@ describe('EKS Cluster Store Actions', () => {
expect(createFlash).toHaveBeenCalledWith(payload.name[0]);
});
});
-
- describe('signOut', () => {
- beforeEach(() => {
- mock.onDelete(state.signOutPath).reply(200, null);
- });
-
- it('commits signOut mutation', () => {
- testAction(actions.signOut, null, state, [{ type: SIGN_OUT }]);
- });
- });
});
diff --git a/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js b/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js
index 0fb392f5eea..8bb014d4758 100644
--- a/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js
@@ -16,7 +16,6 @@ import {
CREATE_ROLE_ERROR,
REQUEST_CREATE_CLUSTER,
CREATE_CLUSTER_ERROR,
- SIGN_OUT,
} from '~/create_cluster/eks_cluster/store/mutation_types';
import createState from '~/create_cluster/eks_cluster/store/state';
import mutations from '~/create_cluster/eks_cluster/store/mutations';
@@ -159,15 +158,4 @@ describe('Create EKS cluster store mutations', () => {
expect(state.createClusterError).toBe(error);
});
});
-
- describe(`mutation ${SIGN_OUT}`, () => {
- beforeEach(() => {
- state.hasCredentials = true;
- mutations[SIGN_OUT](state);
- });
-
- it('sets hasCredentials to false', () => {
- expect(state.hasCredentials).toBe(false);
- });
- });
});
diff --git a/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb b/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb
new file mode 100644
index 00000000000..04ef5ba516e
--- /dev/null
+++ b/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::ErrorTracking::StackTraceHighlightDecorator do
+ let(:error_event) { build(:error_tracking_error_event) }
+
+ describe '.decorate' do
+ subject(:decorate) { described_class.decorate(error_event) }
+
+ it 'does not change issue_id' do
+ expect(decorate.issue_id).to eq(error_event.issue_id)
+ end
+
+ it 'does not change date_received' do
+ expect(decorate.date_received).to eq(error_event.date_received)
+ end
+
+ it 'decorates the stack trace context' do
+ expect(decorate.stack_trace_entries).to eq(
+ [
+ {
+ 'function' => 'puts',
+ 'lineNo' => 14,
+ 'filename' => 'hello_world.rb',
+ 'context' => [
+ [10, '<span id="LC1" class="line" lang="ruby"><span class="c1"># Ruby example</span></span>'],
+ [11, '<span id="LC1" class="line" lang="ruby"><span class="k">class</span> <span class="nc">HelloWorld</span></span>'],
+ [12, '<span id="LC1" class="line" lang="ruby"> <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">message</span></span>'],
+ [13, '<span id="LC1" class="line" lang="ruby"> <span class="vi">@name</span> <span class="o">=</span> <span class="s1">\'World\'</span></span>'],
+ [14, %Q[<span id="LC1" class="line" lang="ruby"> <span class="nb">puts</span> <span class="s2">"Hello </span><span class="si">\#{</span><span class="vi">@name</span><span class="si">}</span><span class="s2">"</span></span>]],
+ [15, '<span id="LC1" class="line" lang="ruby"> <span class="k">end</span></span>'],
+ [16, '<span id="LC1" class="line" lang="ruby"><span class="k">end</span></span>']
+ ]
+ },
+ {
+ 'function' => 'print',
+ 'lineNo' => 6,
+ 'filename' => 'HelloWorld.swift',
+ 'context' => [
+ [1, '<span id="LC1" class="line" lang="swift"><span class="c1">// Swift example</span></span>'],
+ [2, '<span id="LC1" class="line" lang="swift"><span class="kd">struct</span> <span class="kt">HelloWorld</span> <span class="p">{</span></span>'],
+ [3, '<span id="LC1" class="line" lang="swift"> <span class="k">let</span> <span class="nv">name</span> <span class="o">=</span> <span class="s">"World"</span></span>'],
+ [4, '<span id="LC1" class="line" lang="swift"></span>'],
+ [5, '<span id="LC1" class="line" lang="swift"> <span class="kd">static</span> <span class="kd">func</span> <span class="nf">message</span><span class="p">()</span> <span class="p">{</span></span>'],
+ [6, '<span id="LC1" class="line" lang="swift"> <span class="nf">print</span><span class="p">(</span><span class="s">"Hello, </span><span class="se">\\(</span><span class="k">self</span><span class="o">.</span><span class="n">name</span><span class="se">)</span><span class="s">"</span><span class="p">)</span></span>'],
+ [7, '<span id="LC1" class="line" lang="swift"> <span class="p">}</span></span>'],
+ [8, '<span id="LC1" class="line" lang="swift"><span class="p">}</span></span>']
+ ]
+ },
+ {
+ 'filename' => 'blank.txt'
+ }
+ ]
+ )
+ end
+ end
+end
diff --git a/spec/presenters/instance_clusterable_presenter_spec.rb b/spec/presenters/instance_clusterable_presenter_spec.rb
index 3e7ee7a0ff6..4265e2fcb69 100644
--- a/spec/presenters/instance_clusterable_presenter_spec.rb
+++ b/spec/presenters/instance_clusterable_presenter_spec.rb
@@ -21,20 +21,6 @@ describe InstanceClusterablePresenter do
it { is_expected.to eq(authorize_aws_role_admin_clusters_path) }
end
- describe '#revoke_aws_role_path' do
- subject { described_class.new(instance).revoke_aws_role_path }
-
- it { is_expected.to eq(revoke_aws_role_admin_clusters_path) }
- end
-
- describe '#aws_api_proxy_path' do
- let(:resource) { 'resource' }
-
- subject { described_class.new(instance).aws_api_proxy_path(resource) }
-
- it { is_expected.to eq(aws_proxy_admin_clusters_path(resource: resource)) }
- end
-
describe '#clear_cluster_cache_path' do
subject { presenter.clear_cluster_cache_path(cluster) }
diff --git a/spec/presenters/projects/settings/deploy_keys_presenter_spec.rb b/spec/presenters/projects/settings/deploy_keys_presenter_spec.rb
index de58733c8ea..b9cb60e414f 100644
--- a/spec/presenters/projects/settings/deploy_keys_presenter_spec.rb
+++ b/spec/presenters/projects/settings/deploy_keys_presenter_spec.rb
@@ -5,11 +5,6 @@ require 'spec_helper'
describe Projects::Settings::DeployKeysPresenter do
let(:project) { create(:project) }
let(:user) { create(:user) }
- let(:deploy_key) { create(:deploy_key, public: true) }
-
- let!(:deploy_keys_project) do
- create(:deploy_keys_project, project: project, deploy_key: deploy_key)
- end
subject(:presenter) do
described_class.new(project, current_user: user)
@@ -20,6 +15,12 @@ describe Projects::Settings::DeployKeysPresenter do
end
describe '#enabled_keys' do
+ let!(:deploy_key) { create(:deploy_key, public: true) }
+
+ let!(:deploy_keys_project) do
+ create(:deploy_keys_project, project: project, deploy_key: deploy_key)
+ end
+
it 'returns currently enabled keys' do
expect(presenter.enabled_keys).to eq [deploy_keys_project.deploy_key]
end
@@ -53,4 +54,54 @@ describe Projects::Settings::DeployKeysPresenter do
expect(presenter.available_project_keys_size).to eq(1)
end
end
+
+ context 'prevent N + 1 queries' do
+ before do
+ create_records
+
+ project.add_maintainer(user)
+ end
+
+ def create_records
+ other_project = create(:project)
+ other_project.add_maintainer(user)
+
+ create(:deploy_keys_project, project: project, deploy_key: create(:deploy_key))
+ create(:deploy_keys_project, project: other_project, deploy_key: create(:deploy_key))
+ create(:deploy_key, public: true)
+ end
+
+ def execute_with_query_count
+ ActiveRecord::QueryRecorder.new { execute_presenter }.count
+ end
+
+ def execute_presenter
+ described_class.new(project, current_user: user).as_json
+ end
+
+ it 'returns correct counts' do
+ result = execute_presenter
+
+ expect(result[:enabled_keys].size).to eq(1)
+ expect(result[:available_project_keys].size).to eq(1)
+ expect(result[:public_keys].size).to eq(1)
+ end
+
+ it 'does not increase the query count' do
+ execute_presenter # make sure everything is cached
+
+ count_before = execute_with_query_count
+
+ 3.times { create_records }
+
+ count_after = execute_with_query_count
+
+ expect(count_after).to eq(count_before)
+
+ result = execute_presenter
+ expect(result[:enabled_keys].size).to eq(4)
+ expect(result[:available_project_keys].size).to eq(4)
+ expect(result[:public_keys].size).to eq(4)
+ end
+ end
end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 1a1e80f1ce3..29088a42fbe 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -1261,6 +1261,25 @@ describe API::Users do
expect { Namespace.find(namespace.id) }.to raise_error ActiveRecord::RecordNotFound
end
+ context "sole owner of a group" do
+ let!(:group) { create(:group).tap { |group| group.add_owner(user) } }
+
+ context "hard delete disabled" do
+ it "does not delete user" do
+ perform_enqueued_jobs { delete api("/users/#{user.id}", admin)}
+ expect(response).to have_gitlab_http_status(409)
+ end
+ end
+
+ context "hard delete enabled" do
+ it "delete user and group", :sidekiq_might_not_need_inline do
+ perform_enqueued_jobs { delete api("/users/#{user.id}?hard_delete=true", admin)}
+ expect(response).to have_gitlab_http_status(204)
+ expect(Group.exists?(group.id)).to be_falsy
+ end
+ end
+ end
+
it_behaves_like '412 response' do
let(:request) { api("/users/#{user.id}", admin) }
end
diff --git a/spec/services/clusters/aws/authorize_role_service_spec.rb b/spec/services/clusters/aws/authorize_role_service_spec.rb
new file mode 100644
index 00000000000..3ef332558a2
--- /dev/null
+++ b/spec/services/clusters/aws/authorize_role_service_spec.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Clusters::Aws::AuthorizeRoleService do
+ let(:user) { create(:user) }
+ let(:credentials) { instance_double(Aws::Credentials) }
+ let(:credentials_service) { instance_double(Clusters::Aws::FetchCredentialsService, execute: credentials) }
+
+ let(:params) do
+ params = ActionController::Parameters.new({
+ cluster: {
+ role_arn: 'arn:my-role',
+ role_external_id: 'external-id'
+ }
+ })
+
+ params.require(:cluster).permit(:role_arn, :role_external_id)
+ end
+
+ subject { described_class.new(user, params: params).execute }
+
+ before do
+ allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
+ .with(instance_of(Aws::Role)).and_return(credentials_service)
+ end
+
+ context 'role does not exist' do
+ it 'creates an Aws::Role record and returns a set of credentials' do
+ expect(user).to receive(:create_aws_role!)
+ .with(params).and_call_original
+
+ expect(subject.status).to eq(:ok)
+ expect(subject.body).to eq(credentials)
+ end
+ end
+
+ context 'role already exists' do
+ let(:role) { create(:aws_role, user: user) }
+
+ it 'updates the existing Aws::Role record and returns a set of credentials' do
+ expect(role).to receive(:update!)
+ .with(params).and_call_original
+
+ expect(subject.status).to eq(:ok)
+ expect(subject.body).to eq(credentials)
+ end
+ end
+
+ context 'errors' do
+ shared_examples 'bad request' do
+ it 'returns an empty hash' do
+ expect(subject.status).to eq(:unprocessable_entity)
+ expect(subject.body).to eq({})
+ end
+ end
+
+ context 'cannot create role' do
+ before do
+ allow(user).to receive(:create_aws_role!)
+ .and_raise(ActiveRecord::RecordInvalid.new(user))
+ end
+
+ include_examples 'bad request'
+ end
+
+ context 'client errors' do
+ before do
+ allow(credentials_service).to receive(:execute).and_raise(error)
+ end
+
+ context 'error fetching credentials' do
+ let(:error) { Aws::STS::Errors::ServiceError.new(nil, 'error message') }
+
+ include_examples 'bad request'
+ end
+
+ context 'credentials not configured' do
+ let(:error) { Aws::Errors::MissingCredentialsError.new('error message') }
+
+ include_examples 'bad request'
+ end
+
+ context 'role not configured' do
+ let(:error) { Clusters::Aws::FetchCredentialsService::MissingRoleError.new('error message') }
+
+ include_examples 'bad request'
+ end
+ end
+ end
+end
diff --git a/spec/services/clusters/aws/fetch_credentials_service_spec.rb b/spec/services/clusters/aws/fetch_credentials_service_spec.rb
index 726d1c30603..9194947c67f 100644
--- a/spec/services/clusters/aws/fetch_credentials_service_spec.rb
+++ b/spec/services/clusters/aws/fetch_credentials_service_spec.rb
@@ -5,19 +5,18 @@ require 'spec_helper'
describe Clusters::Aws::FetchCredentialsService do
describe '#execute' do
let(:user) { create(:user) }
- let(:provider) { create(:cluster_provider_aws) }
+ let(:provider) { create(:cluster_provider_aws, region: 'ap-southeast-2') }
let(:gitlab_access_key_id) { 'gitlab-access-key-id' }
let(:gitlab_secret_access_key) { 'gitlab-secret-access-key' }
- let(:region) { 'us-east-1' }
let(:gitlab_credentials) { Aws::Credentials.new(gitlab_access_key_id, gitlab_secret_access_key) }
let(:sts_client) { Aws::STS::Client.new(credentials: gitlab_credentials, region: region) }
let(:assumed_role) { instance_double(Aws::AssumeRoleCredentials, credentials: assumed_role_credentials) }
let(:assumed_role_credentials) { double }
- subject { described_class.new(provision_role, region: region, provider: provider).execute }
+ subject { described_class.new(provision_role, provider: provider).execute }
context 'provision role is configured' do
let(:provision_role) { create(:aws_role, user: user) }
@@ -39,19 +38,30 @@ describe Clusters::Aws::FetchCredentialsService do
client: sts_client,
role_arn: provision_role.role_arn,
role_session_name: session_name,
- external_id: provision_role.role_external_id
+ external_id: provision_role.role_external_id,
+ policy: session_policy
).and_return(assumed_role)
end
context 'provider is specified' do
+ let(:region) { provider.region }
let(:session_name) { "gitlab-eks-cluster-#{provider.cluster_id}-user-#{user.id}" }
+ let(:session_policy) { nil }
it { is_expected.to eq assumed_role_credentials }
end
context 'provider is not specifed' do
let(:provider) { nil }
+ let(:region) { Clusters::Providers::Aws::DEFAULT_REGION }
let(:session_name) { "gitlab-eks-autofill-user-#{user.id}" }
+ let(:session_policy) { 'policy-document' }
+
+ before do
+ allow(File).to receive(:read)
+ .with(Rails.root.join('vendor', 'aws', 'iam', 'eks_cluster_read_only_policy.json'))
+ .and_return(session_policy)
+ end
it { is_expected.to eq assumed_role_credentials }
end
diff --git a/spec/services/clusters/aws/proxy_service_spec.rb b/spec/services/clusters/aws/proxy_service_spec.rb
deleted file mode 100644
index 7b0e0512b95..00000000000
--- a/spec/services/clusters/aws/proxy_service_spec.rb
+++ /dev/null
@@ -1,210 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Clusters::Aws::ProxyService do
- let(:role) { create(:aws_role) }
- let(:credentials) { instance_double(Aws::Credentials) }
- let(:client_instance) { instance_double(client) }
-
- let(:region) { 'region' }
- let(:vpc_id) { }
- let(:params) do
- ActionController::Parameters.new({
- resource: resource,
- region: region,
- vpc_id: vpc_id
- })
- end
-
- subject { described_class.new(role, params: params).execute }
-
- context 'external resources' do
- before do
- allow(Clusters::Aws::FetchCredentialsService).to receive(:new) do
- double(execute: credentials)
- end
-
- allow(client).to receive(:new)
- .with(
- credentials: credentials, region: region,
- http_open_timeout: 5, http_read_timeout: 10)
- .and_return(client_instance)
- end
-
- shared_examples 'bad request' do
- it 'returns an empty hash' do
- expect(subject.status).to eq :bad_request
- expect(subject.body).to eq({})
- end
- end
-
- describe 'key_pairs' do
- let(:client) { Aws::EC2::Client }
- let(:resource) { 'key_pairs' }
- let(:response) { double(to_hash: :key_pairs) }
-
- it 'requests a list of key pairs' do
- expect(client_instance).to receive(:describe_key_pairs).once.and_return(response)
- expect(subject.status).to eq :ok
- expect(subject.body).to eq :key_pairs
- end
- end
-
- describe 'roles' do
- let(:client) { Aws::IAM::Client }
- let(:resource) { 'roles' }
- let(:response) { double(to_hash: :roles) }
-
- it 'requests a list of roles' do
- expect(client_instance).to receive(:list_roles).once.and_return(response)
- expect(subject.status).to eq :ok
- expect(subject.body).to eq :roles
- end
- end
-
- describe 'regions' do
- let(:client) { Aws::EC2::Client }
- let(:resource) { 'regions' }
- let(:response) { double(to_hash: :regions) }
-
- it 'requests a list of regions' do
- expect(client_instance).to receive(:describe_regions).once.and_return(response)
- expect(subject.status).to eq :ok
- expect(subject.body).to eq :regions
- end
- end
-
- describe 'security_groups' do
- let(:client) { Aws::EC2::Client }
- let(:resource) { 'security_groups' }
- let(:response) { double(to_hash: :security_groups) }
-
- include_examples 'bad request'
-
- context 'VPC is specified' do
- let(:vpc_id) { 'vpc-1' }
-
- it 'requests a list of security groups for a VPC' do
- expect(client_instance).to receive(:describe_security_groups).once
- .with(filters: [{ name: 'vpc-id', values: [vpc_id] }])
- .and_return(response)
- expect(subject.status).to eq :ok
- expect(subject.body).to eq :security_groups
- end
- end
- end
-
- describe 'subnets' do
- let(:client) { Aws::EC2::Client }
- let(:resource) { 'subnets' }
- let(:response) { double(to_hash: :subnets) }
-
- include_examples 'bad request'
-
- context 'VPC is specified' do
- let(:vpc_id) { 'vpc-1' }
-
- it 'requests a list of subnets for a VPC' do
- expect(client_instance).to receive(:describe_subnets).once
- .with(filters: [{ name: 'vpc-id', values: [vpc_id] }])
- .and_return(response)
- expect(subject.status).to eq :ok
- expect(subject.body).to eq :subnets
- end
- end
- end
-
- describe 'vpcs' do
- let(:client) { Aws::EC2::Client }
- let(:resource) { 'vpcs' }
- let(:response) { double(to_hash: :vpcs) }
-
- it 'requests a list of VPCs' do
- expect(client_instance).to receive(:describe_vpcs).once.and_return(response)
- expect(subject.status).to eq :ok
- expect(subject.body).to eq :vpcs
- end
- end
-
- context 'errors' do
- let(:client) { Aws::EC2::Client }
-
- context 'unknown resource' do
- let(:resource) { 'instances' }
-
- include_examples 'bad request'
- end
-
- context 'client and configuration errors' do
- let(:resource) { 'vpcs' }
-
- before do
- allow(client_instance).to receive(:describe_vpcs).and_raise(error)
- end
-
- context 'error fetching credentials' do
- let(:error) { Aws::STS::Errors::ServiceError.new(nil, 'error message') }
-
- include_examples 'bad request'
- end
-
- context 'credentials not configured' do
- let(:error) { Aws::Errors::MissingCredentialsError.new('error message') }
-
- include_examples 'bad request'
- end
-
- context 'role not configured' do
- let(:error) { Clusters::Aws::FetchCredentialsService::MissingRoleError.new('error message') }
-
- include_examples 'bad request'
- end
-
- context 'EC2 error' do
- let(:error) { Aws::EC2::Errors::ServiceError.new(nil, 'error message') }
-
- include_examples 'bad request'
- end
-
- context 'IAM error' do
- let(:error) { Aws::IAM::Errors::ServiceError.new(nil, 'error message') }
-
- include_examples 'bad request'
- end
-
- context 'STS error' do
- let(:error) { Aws::STS::Errors::ServiceError.new(nil, 'error message') }
-
- include_examples 'bad request'
- end
- end
- end
- end
-
- context 'local resources' do
- describe 'instance_types' do
- let(:resource) { 'instance_types' }
- let(:cloudformation_template) { double }
- let(:instance_types) { double(dig: %w(t3.small)) }
-
- before do
- allow(File).to receive(:read)
- .with(Rails.root.join('vendor', 'aws', 'cloudformation', 'eks_cluster.yaml'))
- .and_return(cloudformation_template)
-
- allow(YAML).to receive(:safe_load)
- .with(cloudformation_template)
- .and_return(instance_types)
- end
-
- it 'returns a list of instance types' do
- expect(subject.status).to eq :ok
- expect(subject.body).to have_key(:instance_types)
- expect(subject.body[:instance_types]).to match_array([
- instance_type_name: 't3.small'
- ])
- end
- end
- end
-end
diff --git a/spec/services/clusters/kubernetes_spec.rb b/spec/services/clusters/kubernetes_spec.rb
new file mode 100644
index 00000000000..7f2c5e0461d
--- /dev/null
+++ b/spec/services/clusters/kubernetes_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Clusters::Kubernetes do
+ it { is_expected.to be_const_defined(:GITLAB_SERVICE_ACCOUNT_NAME) }
+ it { is_expected.to be_const_defined(:GITLAB_SERVICE_ACCOUNT_NAMESPACE) }
+ it { is_expected.to be_const_defined(:GITLAB_ADMIN_TOKEN_NAME) }
+ it { is_expected.to be_const_defined(:GITLAB_CLUSTER_ROLE_BINDING_NAME) }
+ it { is_expected.to be_const_defined(:GITLAB_CLUSTER_ROLE_NAME) }
+ it { is_expected.to be_const_defined(:PROJECT_CLUSTER_ROLE_NAME) }
+ it { is_expected.to be_const_defined(:GITLAB_KNATIVE_SERVING_ROLE_NAME) }
+ it { is_expected.to be_const_defined(:GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME) }
+ it { is_expected.to be_const_defined(:GITLAB_CROSSPLANE_DATABASE_ROLE_NAME) }
+ it { is_expected.to be_const_defined(:GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME) }
+ it { is_expected.to be_const_defined(:GITLAB_KNATIVE_VERSION_ROLE_NAME) }
+ it { is_expected.to be_const_defined(:GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME) }
+ it { is_expected.to be_const_defined(:KNATIVE_SERVING_NAMESPACE) }
+end