From e4db99f3e8edf682d2c1df30e76a4a38747ea9ae Mon Sep 17 00:00:00 2001 From: Emily Ring <ering@gitlab.com> Date: Thu, 22 Oct 2020 22:01:26 +0000 Subject: [PATCH] Remove default EKS Region Dropdown in cluster form Replace dropdown with input field for EKS Regions Update authorize_role_service to authenticate with customer region --- .../eks_cluster_configuration_form.vue | 61 +++------- .../components/service_credentials_form.vue | 40 ++++++- .../create_cluster/eks_cluster/constants.js | 2 + .../services/aws_services_facade.js | 21 +--- .../eks_cluster/store/actions.js | 16 ++- .../create_cluster/eks_cluster/store/index.js | 5 - .../clusters/clusters_controller.rb | 2 +- .../clusters/aws/authorize_role_service.rb | 9 +- .../clusters/aws/fetch_credentials_service.rb | 9 +- .../216974-optional-input-field.yml | 5 + locale/gitlab.pot | 30 ++--- .../eks_cluster_configuration_form_spec.js | 112 ++++++------------ .../services/aws_services_facade_spec.js | 26 +--- .../eks_cluster/store/actions_spec.js | 61 +++++++++- .../aws/authorize_role_service_spec.rb | 8 +- .../aws/fetch_credentials_service_spec.rb | 4 +- 16 files changed, 195 insertions(+), 216 deletions(-) create mode 100644 changelogs/unreleased/216974-optional-input-field.yml diff --git a/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue b/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue index d403f370f9d57..2858561e03334 100644 --- a/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue +++ b/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue @@ -1,15 +1,12 @@ <script> import { createNamespacedHelpers, mapState, mapActions, mapGetters } from 'vuex'; -import { GlFormInput, GlFormCheckbox, GlIcon, GlLink, GlSprintf } from '@gitlab/ui'; +import { GlFormGroup, GlFormInput, GlFormCheckbox, GlIcon, GlLink, GlSprintf } from '@gitlab/ui'; import { s__ } from '~/locale'; import ClusterFormDropdown from '~/create_cluster/components/cluster_form_dropdown.vue'; import { KUBERNETES_VERSIONS } from '../constants'; import LoadingButton from '~/vue_shared/components/loading_button.vue'; const { mapState: mapRolesState, mapActions: mapRolesActions } = createNamespacedHelpers('roles'); -const { mapState: mapRegionsState, mapActions: mapRegionsActions } = createNamespacedHelpers( - 'regions', -); const { mapState: mapKeyPairsState, mapActions: mapKeyPairsActions } = createNamespacedHelpers( 'keyPairs', ); @@ -27,6 +24,7 @@ export default { components: { ClusterFormDropdown, GlFormCheckbox, + GlFormGroup, GlFormInput, GlIcon, GlLink, @@ -60,11 +58,10 @@ export default { ), roleDropdownHelpPath: 'https://docs.aws.amazon.com/eks/latest/userguide/service_IAM_role.html#create-service-role', - regionsDropdownHelpText: s__( - 'ClusterIntegration|Learn more about %{linkStart}Regions%{linkEnd}.', + regionInputLabel: s__('ClusterIntegration|Cluster Region'), + regionHelpText: s__( + 'ClusterIntegration|The region the new cluster will be created in. You must reauthenticate to change regions.', ), - regionsDropdownHelpPath: - 'https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/', keyPairDropdownHelpText: s__( 'ClusterIntegration|Select the key pair name that will be used to create EC2 nodes. To use a new key pair name, first create one on %{linkStart}Amazon Web Services%{linkEnd}.', ), @@ -117,11 +114,6 @@ export default { isLoadingRoles: 'isLoadingItems', loadingRolesError: 'loadingItemsError', }), - ...mapRegionsState({ - regions: 'items', - isLoadingRegions: 'isLoadingItems', - loadingRegionsError: 'loadingItemsError', - }), ...mapKeyPairsState({ keyPairs: 'items', isLoadingKeyPairs: 'isLoadingItems', @@ -195,8 +187,8 @@ export default { }, }, mounted() { - this.fetchRegions(); this.fetchRoles(); + this.setRegionAndFetchVpcsAndKeyPairs(); }, methods: { ...mapActions([ @@ -215,20 +207,18 @@ export default { 'setGitlabManagedCluster', 'setNamespacePerEnvironment', ]), - ...mapRegionsActions({ fetchRegions: 'fetchItems' }), ...mapVpcActions({ fetchVpcs: 'fetchItems' }), ...mapSubnetActions({ fetchSubnets: 'fetchItems' }), ...mapRolesActions({ fetchRoles: 'fetchItems' }), ...mapKeyPairsActions({ fetchKeyPairs: 'fetchItems' }), ...mapSecurityGroupsActions({ fetchSecurityGroups: 'fetchItems' }), - setRegionAndFetchVpcsAndKeyPairs(region) { - this.setRegion({ region }); + setRegionAndFetchVpcsAndKeyPairs() { this.setVpc({ vpc: null }); this.setKeyPair({ keyPair: null }); this.setSubnet({ subnet: [] }); this.setSecurityGroup({ securityGroup: null }); - this.fetchVpcs({ region }); - this.fetchKeyPairs({ region }); + this.fetchVpcs({ region: this.selectedRegion }); + this.fetchKeyPairs({ region: this.selectedRegion }); }, setVpcAndFetchSubnets(vpc) { this.setVpc({ vpc }); @@ -314,33 +304,12 @@ export default { </gl-sprintf> </p> </div> - <div class="form-group"> - <label class="label-bold" for="eks-role">{{ s__('ClusterIntegration|Region') }}</label> - <cluster-form-dropdown - field-id="eks-region" - field-name="eks-region" - :value="selectedRegion" - :items="regions" - :loading="isLoadingRegions" - :loading-text="s__('ClusterIntegration|Loading Regions')" - :placeholder="s__('ClusterIntergation|Select a region')" - :search-field-placeholder="s__('ClusterIntegration|Search regions')" - :empty-text="s__('ClusterIntegration|No region found')" - :has-errors="Boolean(loadingRegionsError)" - :error-message="s__('ClusterIntegration|Could not load regions from your AWS account')" - @input="setRegionAndFetchVpcsAndKeyPairs($event)" - /> - <p class="form-text text-muted"> - <gl-sprintf :message="$options.i18n.regionsDropdownHelpText"> - <template #link="{ content }"> - <gl-link :href="$options.i18n.regionsDropdownHelpPath" target="_blank"> - {{ content }} - <gl-icon name="external-link" class="gl-vertical-align-middle" /> - </gl-link> - </template> - </gl-sprintf> - </p> - </div> + <gl-form-group + :label="$options.i18n.regionInputLabel" + :description="$options.i18n.regionHelpText" + > + <gl-form-input id="eks-region" :value="selectedRegion" type="text" readonly /> + </gl-form-group> <div class="form-group"> <label class="label-bold" for="eks-key-pair">{{ s__('ClusterIntegration|Key pair name') diff --git a/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue b/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue index 5c13cbb27759b..a3f76241bf2bf 100644 --- a/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue +++ b/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue @@ -1,15 +1,20 @@ <script> /* eslint-disable vue/no-v-html */ -import { GlFormInput, GlButton } from '@gitlab/ui'; +import { GlButton, GlFormGroup, GlFormInput, GlIcon, GlLink, GlSprintf } from '@gitlab/ui'; import { escape } from 'lodash'; import { mapState, mapActions } from 'vuex'; +import { DEFAULT_REGION } from '../constants'; import { sprintf, s__, __ } from '~/locale'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; export default { components: { - GlFormInput, GlButton, + GlFormGroup, + GlFormInput, + GlIcon, + GlLink, + GlSprintf, ClipboardButton, }, props: { @@ -26,9 +31,18 @@ export default { required: true, }, }, + i18n: { + regionInputLabel: s__('ClusterIntegration|Cluster Region'), + regionHelpPath: 'https://aws.amazon.com/about-aws/global-infrastructure/regions_az/', + regionHelpText: s__( + 'ClusterIntegration|Select the region you want to create the new cluster in. Make sure you have access to this region for your role to be able to authenticate. If no region is selected, we will use %{codeStart}DEFAULT_REGION%{codeEnd}. Learn more about %{linkStart}Regions%{linkEnd}.', + ), + regionHelpTextDefaultRegion: DEFAULT_REGION, + }, data() { return { roleArn: this.$store.state.roleArn, + selectedRegion: this.$store.state.selectedRegion, }; }, computed: { @@ -130,13 +144,33 @@ export default { <gl-form-input id="eks-provision-role-arn" v-model="roleArn" /> <p class="form-text text-muted" v-html="provisionRoleArnHelpText"></p> </div> + + <gl-form-group :label="$options.i18n.regionInputLabel"> + <gl-form-input id="eks-region" v-model="selectedRegion" type="text" /> + + <template #description> + <gl-sprintf :message="$options.i18n.regionHelpText"> + <template #code> + <code>{{ $options.i18n.regionHelpTextDefaultRegion }}</code> + </template> + + <template #link="{ content }"> + <gl-link :href="$options.i18n.regionHelpPath" target="_blank"> + {{ content }} + <gl-icon name="external-link" /> + </gl-link> + </template> + </gl-sprintf> + </template> + </gl-form-group> + <gl-button variant="success" category="primary" type="submit" :disabled="submitButtonDisabled" :loading="isCreatingRole" - @click.prevent="createRole({ roleArn, externalId })" + @click.prevent="createRole({ roleArn, selectedRegion, externalId })" > {{ submitButtonLabel }} </gl-button> diff --git a/app/assets/javascripts/create_cluster/eks_cluster/constants.js b/app/assets/javascripts/create_cluster/eks_cluster/constants.js index 471d6e1f0aa6a..0f0db2090c102 100644 --- a/app/assets/javascripts/create_cluster/eks_cluster/constants.js +++ b/app/assets/javascripts/create_cluster/eks_cluster/constants.js @@ -1,3 +1,5 @@ +export const DEFAULT_REGION = 'us-east-2'; + export const KUBERNETES_VERSIONS = [ { name: '1.14', value: '1.14' }, { name: '1.15', value: '1.15' }, diff --git a/app/assets/javascripts/create_cluster/eks_cluster/services/aws_services_facade.js b/app/assets/javascripts/create_cluster/eks_cluster/services/aws_services_facade.js index 601ff6f9adca7..58568b5dedbcd 100644 --- a/app/assets/javascripts/create_cluster/eks_cluster/services/aws_services_facade.js +++ b/app/assets/javascripts/create_cluster/eks_cluster/services/aws_services_facade.js @@ -8,13 +8,8 @@ const lookupVpcName = ({ Tags: tags, VpcId: id }) => { return nameTag ? nameTag.Value : id; }; -export const DEFAULT_REGION = 'us-east-2'; - export const setAWSConfig = ({ awsCredentials }) => { - AWS.config = { - ...awsCredentials, - region: DEFAULT_REGION, - }; + AWS.config = awsCredentials; }; export const fetchRoles = () => { @@ -26,20 +21,6 @@ export const fetchRoles = () => { .then(({ Roles: roles }) => roles.map(({ RoleName: name, Arn: value }) => ({ name, value }))); }; -export const fetchRegions = () => { - const ec2 = new EC2(); - - return ec2 - .describeRegions() - .promise() - .then(({ Regions: regions }) => - regions.map(({ RegionName: name }) => ({ - name, - value: name, - })), - ); -}; - export const fetchKeyPairs = ({ region }) => { const ec2 = new EC2({ region }); diff --git a/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js b/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js index 48c85ff627ff1..f3950a3343a8a 100644 --- a/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js +++ b/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js @@ -1,4 +1,5 @@ import * as types from './mutation_types'; +import { DEFAULT_REGION } from '../constants'; import { setAWSConfig } from '../services/aws_services_facade'; import axios from '~/lib/utils/axios_utils'; import { deprecatedCreateFlash as createFlash } from '~/flash'; @@ -25,12 +26,22 @@ export const setKubernetesVersion = ({ commit }, payload) => { export const createRole = ({ dispatch, state: { createRolePath } }, payload) => { dispatch('requestCreateRole'); + const region = payload.selectedRegion || DEFAULT_REGION; + return axios .post(createRolePath, { role_arn: payload.roleArn, role_external_id: payload.externalId, + region, + }) + .then(({ data }) => { + const awsData = { + ...convertObjectPropsToCamelCase(data), + region, + }; + + dispatch('createRoleSuccess', awsData); }) - .then(({ data }) => dispatch('createRoleSuccess', convertObjectPropsToCamelCase(data))) .catch(error => dispatch('createRoleError', { error })); }; @@ -38,7 +49,8 @@ export const requestCreateRole = ({ commit }) => { commit(types.REQUEST_CREATE_ROLE); }; -export const createRoleSuccess = ({ commit }, awsCredentials) => { +export const createRoleSuccess = ({ dispatch, commit }, awsCredentials) => { + dispatch('setRegion', { region: awsCredentials.region }); setAWSConfig({ awsCredentials }); commit(types.CREATE_ROLE_SUCCESS); }; diff --git a/app/assets/javascripts/create_cluster/eks_cluster/store/index.js b/app/assets/javascripts/create_cluster/eks_cluster/store/index.js index 8dc55506dc285..262bbb3167a5a 100644 --- a/app/assets/javascripts/create_cluster/eks_cluster/store/index.js +++ b/app/assets/javascripts/create_cluster/eks_cluster/store/index.js @@ -8,7 +8,6 @@ import clusterDropdownStore from '~/create_cluster/store/cluster_dropdown'; import { fetchRoles, - fetchRegions, fetchKeyPairs, fetchVpcs, fetchSubnets, @@ -26,10 +25,6 @@ const createStore = ({ initialState }) => namespaced: true, ...clusterDropdownStore({ fetchFn: fetchRoles }), }, - regions: { - namespaced: true, - ...clusterDropdownStore({ fetchFn: fetchRegions }), - }, keyPairs: { namespaced: true, ...clusterDropdownStore({ fetchFn: fetchKeyPairs }), diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb index 52719e90e04f3..9800d94964d57 100644 --- a/app/controllers/clusters/clusters_controller.rb +++ b/app/controllers/clusters/clusters_controller.rb @@ -272,7 +272,7 @@ def create_user_cluster_params end def aws_role_params - params.require(:cluster).permit(:role_arn) + params.require(:cluster).permit(:role_arn, :region) end def generate_gcp_authorize_url diff --git a/app/services/clusters/aws/authorize_role_service.rb b/app/services/clusters/aws/authorize_role_service.rb index 2712a4b05bbb3..1f6f350bcc89b 100644 --- a/app/services/clusters/aws/authorize_role_service.rb +++ b/app/services/clusters/aws/authorize_role_service.rb @@ -17,7 +17,8 @@ class AuthorizeRoleService def initialize(user, params:) @user = user - @params = params + @role_arn = params[:role_arn] + @region = params[:region] end def execute @@ -33,18 +34,18 @@ def execute private - attr_reader :role, :params + attr_reader :role, :role_arn, :region def ensure_role_exists! @role = ::Aws::Role.find_by_user_id!(user.id) end def update_role_arn! - role.update!(params) + role.update!(role_arn: role_arn) end def credentials - Clusters::Aws::FetchCredentialsService.new(role).execute + Clusters::Aws::FetchCredentialsService.new(role, region: region).execute end end end diff --git a/app/services/clusters/aws/fetch_credentials_service.rb b/app/services/clusters/aws/fetch_credentials_service.rb index 33efc4cc12077..f94d8d8c66d15 100644 --- a/app/services/clusters/aws/fetch_credentials_service.rb +++ b/app/services/clusters/aws/fetch_credentials_service.rb @@ -7,9 +7,10 @@ class FetchCredentialsService MissingRoleError = Class.new(StandardError) - def initialize(provision_role, provider: nil) + def initialize(provision_role, provider: nil, region: nil) @provision_role = provision_role @provider = provider + @region = provider&.region || region end def execute @@ -26,7 +27,7 @@ def execute private - attr_reader :provider + attr_reader :provider, :region def client ::Aws::STS::Client.new(credentials: gitlab_credentials, region: region) @@ -44,10 +45,6 @@ def secret_access_key Gitlab::CurrentSettings.eks_secret_access_key end - def region - provider&.region || Clusters::Providers::Aws::DEFAULT_REGION - end - ## # If we haven't created a provider record yet, # we restrict ourselves to read only access so diff --git a/changelogs/unreleased/216974-optional-input-field.yml b/changelogs/unreleased/216974-optional-input-field.yml new file mode 100644 index 0000000000000..1816b6202bf4b --- /dev/null +++ b/changelogs/unreleased/216974-optional-input-field.yml @@ -0,0 +1,5 @@ +--- +title: Remove default EKS Region dropdown in cluster create form +merge_request: 43017 +author: +type: fixed diff --git a/locale/gitlab.pot b/locale/gitlab.pot index fd2ca67c3d89f..447fb5b508630 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -5687,6 +5687,9 @@ msgstr "" msgid "ClusterIntegration|Clear the local cache of namespace and service accounts." msgstr "" +msgid "ClusterIntegration|Cluster Region" +msgstr "" + msgid "ClusterIntegration|Cluster management project (alpha)" msgstr "" @@ -5744,9 +5747,6 @@ msgstr "" msgid "ClusterIntegration|Could not load networks" msgstr "" -msgid "ClusterIntegration|Could not load regions from your AWS account" -msgstr "" - msgid "ClusterIntegration|Could not load security groups for the selected VPC" msgstr "" @@ -6002,9 +6002,6 @@ msgstr "" msgid "ClusterIntegration|Learn more about %{help_link_start}zones%{help_link_end}." msgstr "" -msgid "ClusterIntegration|Learn more about %{linkStart}Regions%{linkEnd}." -msgstr "" - msgid "ClusterIntegration|Learn more about Kubernetes" msgstr "" @@ -6020,9 +6017,6 @@ msgstr "" msgid "ClusterIntegration|Loading Key Pairs" msgstr "" -msgid "ClusterIntegration|Loading Regions" -msgstr "" - msgid "ClusterIntegration|Loading VPCs" msgstr "" @@ -6089,9 +6083,6 @@ msgstr "" msgid "ClusterIntegration|No projects matched your search" msgstr "" -msgid "ClusterIntegration|No region found" -msgstr "" - msgid "ClusterIntegration|No security group found" msgstr "" @@ -6158,9 +6149,6 @@ msgstr "" msgid "ClusterIntegration|Real-time web application monitoring, logging and access control. %{linkStart}More information%{linkEnd}" msgstr "" -msgid "ClusterIntegration|Region" -msgstr "" - msgid "ClusterIntegration|Remove Kubernetes cluster integration" msgstr "" @@ -6227,9 +6215,6 @@ msgstr "" msgid "ClusterIntegration|Search projects" msgstr "" -msgid "ClusterIntegration|Search regions" -msgstr "" - msgid "ClusterIntegration|Search security groups" msgstr "" @@ -6290,6 +6275,9 @@ msgstr "" msgid "ClusterIntegration|Select the key pair name that will be used to create EC2 nodes. To use a new key pair name, first create one on %{linkStart}Amazon Web Services%{linkEnd}." msgstr "" +msgid "ClusterIntegration|Select the region you want to create the new cluster in. Make sure you have access to this region for your role to be able to authenticate. If no region is selected, we will use %{codeStart}DEFAULT_REGION%{codeEnd}. Learn more about %{linkStart}Regions%{linkEnd}." +msgstr "" + msgid "ClusterIntegration|Select zone" msgstr "" @@ -6374,6 +6362,9 @@ msgstr "" msgid "ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, logs, and Web terminals." msgstr "" +msgid "ClusterIntegration|The region the new cluster will be created in. You must reauthenticate to change regions." +msgstr "" + msgid "ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid." msgstr "" @@ -6515,9 +6506,6 @@ msgstr "" msgid "ClusterIntergation|Select a network" msgstr "" -msgid "ClusterIntergation|Select a region" -msgstr "" - msgid "ClusterIntergation|Select a security group" msgstr "" 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 2600415fc9fd5..f9984091df0d7 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 @@ -16,7 +16,6 @@ describe('EksClusterConfigurationForm', () => { let getters; let state; let rolesState; - let regionsState; let vpcsState; let subnetsState; let keyPairsState; @@ -24,7 +23,6 @@ describe('EksClusterConfigurationForm', () => { let instanceTypesState; let vpcsActions; let rolesActions; - let regionsActions; let subnetsActions; let keyPairsActions; let securityGroupsActions; @@ -46,9 +44,6 @@ describe('EksClusterConfigurationForm', () => { setNodeCount: jest.fn(), setGitlabManagedCluster: jest.fn(), }; - regionsActions = { - fetchItems: jest.fn(), - }; keyPairsActions = { fetchItems: jest.fn(), }; @@ -72,10 +67,6 @@ describe('EksClusterConfigurationForm', () => { ...clusterDropdownStoreState(), ...config.rolesState, }; - regionsState = { - ...clusterDropdownStoreState(), - ...config.regionsState, - }; vpcsState = { ...clusterDropdownStoreState(), ...config.vpcsState, @@ -109,11 +100,6 @@ describe('EksClusterConfigurationForm', () => { state: vpcsState, actions: vpcsActions, }, - regions: { - namespaced: true, - state: regionsState, - actions: regionsActions, - }, subnets: { namespaced: true, state: subnetsState, @@ -189,7 +175,6 @@ describe('EksClusterConfigurationForm', () => { const findClusterNameInput = () => vm.find('[id=eks-cluster-name]'); const findEnvironmentScopeInput = () => vm.find('[id=eks-environment-scope]'); const findKubernetesVersionDropdown = () => vm.find('[field-id="eks-kubernetes-version"]'); - const findRegionDropdown = () => vm.find('[field-id="eks-region"]'); const findKeyPairDropdown = () => vm.find('[field-id="eks-key-pair"]'); const findVpcDropdown = () => vm.find('[field-id="eks-vpc"]'); const findSubnetDropdown = () => vm.find('[field-id="eks-subnet"]'); @@ -200,13 +185,44 @@ describe('EksClusterConfigurationForm', () => { const findGitlabManagedClusterCheckbox = () => vm.find(GlFormCheckbox); describe('when mounted', () => { - it('fetches available regions', () => { - expect(regionsActions.fetchItems).toHaveBeenCalled(); - }); - it('fetches available roles', () => { expect(rolesActions.fetchItems).toHaveBeenCalled(); }); + + describe('when fetching vpcs and key pairs', () => { + const region = 'us-west-2'; + + beforeEach(() => { + createValidStateStore({ selectedRegion: region }); + buildWrapper(); + }); + + it('fetches available vpcs', () => { + expect(vpcsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region }); + }); + + it('fetches available key pairs', () => { + expect(keyPairsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region }); + }); + + it('cleans selected vpc', () => { + expect(actions.setVpc).toHaveBeenCalledWith(expect.anything(), { vpc: null }); + }); + + it('cleans selected key pair', () => { + expect(actions.setKeyPair).toHaveBeenCalledWith(expect.anything(), { keyPair: null }); + }); + + it('cleans selected subnet', () => { + expect(actions.setSubnet).toHaveBeenCalledWith(expect.anything(), { subnet: [] }); + }); + + it('cleans selected security group', () => { + expect(actions.setSecurityGroup).toHaveBeenCalledWith(expect.anything(), { + securityGroup: null, + }); + }); + }); }); it('sets isLoadingRoles to RoleDropdown loading property', () => { @@ -229,26 +245,6 @@ describe('EksClusterConfigurationForm', () => { }); }); - it('sets isLoadingRegions to RegionDropdown loading property', () => { - regionsState.isLoadingItems = true; - - return Vue.nextTick().then(() => { - expect(findRegionDropdown().props('loading')).toBe(regionsState.isLoadingItems); - }); - }); - - it('sets regions to RegionDropdown regions property', () => { - expect(findRegionDropdown().props('items')).toBe(regionsState.items); - }); - - it('sets loadingRegionsError to RegionDropdown error property', () => { - regionsState.loadingItemsError = new Error(); - - return Vue.nextTick().then(() => { - expect(findRegionDropdown().props('hasErrors')).toEqual(true); - }); - }); - it('disables KeyPairDropdown when no region is selected', () => { expect(findKeyPairDropdown().props('disabled')).toBe(true); }); @@ -394,44 +390,6 @@ describe('EksClusterConfigurationForm', () => { }); }); - describe('when region is selected', () => { - const region = { name: 'us-west-2' }; - - beforeEach(() => { - findRegionDropdown().vm.$emit('input', region); - }); - - it('dispatches setRegion action', () => { - expect(actions.setRegion).toHaveBeenCalledWith(expect.anything(), { region }); - }); - - it('fetches available vpcs', () => { - expect(vpcsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region }); - }); - - it('fetches available key pairs', () => { - expect(keyPairsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region }); - }); - - it('cleans selected vpc', () => { - expect(actions.setVpc).toHaveBeenCalledWith(expect.anything(), { vpc: null }); - }); - - it('cleans selected key pair', () => { - expect(actions.setKeyPair).toHaveBeenCalledWith(expect.anything(), { keyPair: null }); - }); - - it('cleans selected subnet', () => { - expect(actions.setSubnet).toHaveBeenCalledWith(expect.anything(), { subnet: [] }); - }); - - it('cleans selected security group', () => { - expect(actions.setSecurityGroup).toHaveBeenCalledWith(expect.anything(), { - securityGroup: null, - }); - }); - }); - it('dispatches setClusterName when cluster name input changes', () => { const clusterName = 'name'; 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 0ef09b4b87e9a..03c22c570a898 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 @@ -3,12 +3,10 @@ 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(); @@ -45,19 +43,17 @@ describe('awsServicesFacade', () => { vpc = 'vpc-2'; }); - it('setAWSConfig configures AWS SDK with provided credentials and default region', () => { + it('setAWSConfig configures AWS SDK with provided credentials', () => { const awsCredentials = { accessKeyId: 'access-key', secretAccessKey: 'secret-key', sessionToken: 'session-token', + region, }; setAWSConfig({ awsCredentials }); - expect(AWS.config).toEqual({ - ...awsCredentials, - region: DEFAULT_REGION, - }); + expect(AWS.config).toEqual(awsCredentials); }); describe('when fetchRoles succeeds', () => { @@ -79,22 +75,6 @@ describe('awsServicesFacade', () => { }); }); - 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', () => { - return expect(fetchRegions()).resolves.toEqual(regionsOutput); - }); - }); - describe('when fetchKeyPairs succeeds', () => { let keyPairs; let keyPairsOutput; 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 f929216689a4f..f12f300872ace 100644 --- a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js +++ b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js @@ -23,6 +23,7 @@ import { REQUEST_CREATE_CLUSTER, CREATE_CLUSTER_ERROR, } from '~/create_cluster/eks_cluster/store/mutation_types'; +import { DEFAULT_REGION } from '~/create_cluster/eks_cluster/constants'; import axios from '~/lib/utils/axios_utils'; import { deprecatedCreateFlash as createFlash } from '~/flash'; @@ -109,12 +110,13 @@ describe('EKS Cluster Store Actions', () => { secretAccessKey: 'secret-key-id', }; - describe('when request succeeds', () => { + describe('when request succeeds with default region', () => { beforeEach(() => { mock .onPost(state.createRolePath, { role_arn: payload.roleArn, role_external_id: payload.externalId, + region: DEFAULT_REGION, }) .reply(201, response); }); @@ -125,7 +127,51 @@ describe('EKS Cluster Store Actions', () => { payload, state, [], - [{ type: 'requestCreateRole' }, { type: 'createRoleSuccess', payload: response }], + [ + { type: 'requestCreateRole' }, + { + type: 'createRoleSuccess', + payload: { + region: DEFAULT_REGION, + ...response, + }, + }, + ], + )); + }); + + describe('when request succeeds with custom region', () => { + const customRegion = 'custom-region'; + + beforeEach(() => { + mock + .onPost(state.createRolePath, { + role_arn: payload.roleArn, + role_external_id: payload.externalId, + region: customRegion, + }) + .reply(201, response); + }); + + it('dispatches createRoleSuccess action', () => + testAction( + actions.createRole, + { + selectedRegion: customRegion, + ...payload, + }, + state, + [], + [ + { type: 'requestCreateRole' }, + { + type: 'createRoleSuccess', + payload: { + region: customRegion, + ...response, + }, + }, + ], )); }); @@ -138,6 +184,7 @@ describe('EKS Cluster Store Actions', () => { .onPost(state.createRolePath, { role_arn: payload.roleArn, role_external_id: payload.externalId, + region: DEFAULT_REGION, }) .reply(400, error); }); @@ -160,8 +207,14 @@ describe('EKS Cluster Store Actions', () => { }); describe('createRoleSuccess', () => { - it('commits createRoleSuccess mutation', () => { - testAction(actions.createRoleSuccess, null, state, [{ type: CREATE_ROLE_SUCCESS }]); + it('sets region and commits createRoleSuccess mutation', () => { + testAction( + actions.createRoleSuccess, + { region }, + state, + [{ type: CREATE_ROLE_SUCCESS }], + [{ type: 'setRegion', payload: { region } }], + ); }); }); diff --git a/spec/services/clusters/aws/authorize_role_service_spec.rb b/spec/services/clusters/aws/authorize_role_service_spec.rb index 5b47cf0ecde72..0659f92c92760 100644 --- a/spec/services/clusters/aws/authorize_role_service_spec.rb +++ b/spec/services/clusters/aws/authorize_role_service_spec.rb @@ -11,19 +11,21 @@ let(:credentials_service) { instance_double(Clusters::Aws::FetchCredentialsService, execute: credentials) } let(:role_arn) { 'arn:my-role' } + let(:region) { 'region' } let(:params) do params = ActionController::Parameters.new({ cluster: { - role_arn: role_arn + role_arn: role_arn, + region: region } }) - params.require(:cluster).permit(:role_arn) + params.require(:cluster).permit(:role_arn, :region) end before do allow(Clusters::Aws::FetchCredentialsService).to receive(:new) - .with(instance_of(Aws::Role)).and_return(credentials_service) + .with(instance_of(Aws::Role), region: region).and_return(credentials_service) end context 'role exists' do diff --git a/spec/services/clusters/aws/fetch_credentials_service_spec.rb b/spec/services/clusters/aws/fetch_credentials_service_spec.rb index a0e63d96a5cd1..1e39f63a28227 100644 --- a/spec/services/clusters/aws/fetch_credentials_service_spec.rb +++ b/spec/services/clusters/aws/fetch_credentials_service_spec.rb @@ -53,10 +53,12 @@ context 'provider is not specifed' do let(:provider) { nil } - let(:region) { Clusters::Providers::Aws::DEFAULT_REGION } + let(:region) { 'custom-region' } let(:session_name) { "gitlab-eks-autofill-user-#{user.id}" } let(:session_policy) { 'policy-document' } + subject { described_class.new(provision_role, provider: provider, region: region).execute } + before do allow(File).to receive(:read) .with(Rails.root.join('vendor', 'aws', 'iam', 'eks_cluster_read_only_policy.json')) -- GitLab