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
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-23 03:08:30 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-23 03:08:30 +0300
commite6dd804c902b030e2178be0c9ec5c38b58bd2b14 (patch)
tree9cabaea51989befe4d8c2e65ebac11afdd5dc493
parente5356e229f5a1181d1a49091d6dc611db68bfffb (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue61
-rw-r--r--app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue40
-rw-r--r--app/assets/javascripts/create_cluster/eks_cluster/constants.js2
-rw-r--r--app/assets/javascripts/create_cluster/eks_cluster/services/aws_services_facade.js21
-rw-r--r--app/assets/javascripts/create_cluster/eks_cluster/store/actions.js16
-rw-r--r--app/assets/javascripts/create_cluster/eks_cluster/store/index.js5
-rw-r--r--app/controllers/clusters/clusters_controller.rb2
-rw-r--r--app/services/bulk_create_integration_service.rb14
-rw-r--r--app/services/clusters/aws/authorize_role_service.rb9
-rw-r--r--app/services/clusters/aws/fetch_credentials_service.rb9
-rw-r--r--changelogs/unreleased/216974-optional-input-field.yml5
-rw-r--r--changelogs/unreleased/268133-fix-propagate-integrations-for-project-callback.yml5
-rw-r--r--changelogs/unreleased/jh-migration_mvc_gmau.yml6
-rw-r--r--doc/administration/object_storage.md5
-rw-r--r--doc/development/changelog.md3
-rw-r--r--doc/operations/metrics/dashboards/img/metrics_settings_button_v13_3.pngbin3903 -> 0 bytes
-rw-r--r--doc/operations/metrics/dashboards/index.md11
-rw-r--r--doc/operations/metrics/dashboards/settings.md8
-rw-r--r--doc/user/permissions.md2
-rw-r--r--lib/gitlab/experimentation.rb2
-rw-r--r--lib/gitlab/usage_data.rb3
-rw-r--r--locale/gitlab.pot30
-rw-r--r--spec/factories/projects.rb4
-rw-r--r--spec/factories/services.rb7
-rw-r--r--spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js112
-rw-r--r--spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js26
-rw-r--r--spec/frontend/create_cluster/eks_cluster/store/actions_spec.js61
-rw-r--r--spec/lib/gitlab/experimentation_spec.rb8
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb8
-rw-r--r--spec/requests/api/projects_spec.rb4
-rw-r--r--spec/services/bulk_create_integration_service_spec.rb43
-rw-r--r--spec/services/clusters/aws/authorize_role_service_spec.rb8
-rw-r--r--spec/services/clusters/aws/fetch_credentials_service_spec.rb4
-rwxr-xr-x[-rw-r--r--]vendor/gitignore/C++.gitignore0
-rwxr-xr-x[-rw-r--r--]vendor/gitignore/Java.gitignore0
35 files changed, 290 insertions, 254 deletions
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 d403f370f9d..2858561e033 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 5c13cbb2775..a3f76241bf2 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 471d6e1f0aa..0f0db2090c1 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 601ff6f9adc..58568b5dedb 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 48c85ff627f..f3950a3343a 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 8dc55506dc2..262bbb3167a 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 52719e90e04..9800d94964d 100644
--- a/app/controllers/clusters/clusters_controller.rb
+++ b/app/controllers/clusters/clusters_controller.rb
@@ -272,7 +272,7 @@ class Clusters::ClustersController < Clusters::BaseController
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/bulk_create_integration_service.rb b/app/services/bulk_create_integration_service.rb
index 23b89b0d8a9..2cec7e71989 100644
--- a/app/services/bulk_create_integration_service.rb
+++ b/app/services/bulk_create_integration_service.rb
@@ -11,6 +11,8 @@ class BulkCreateIntegrationService
service_list = ServiceList.new(batch, service_hash, association).to_array
Service.transaction do
+ run_callbacks(batch) if association == 'project'
+
results = bulk_insert(*service_list)
if integration.data_fields_present?
@@ -18,8 +20,6 @@ class BulkCreateIntegrationService
bulk_insert(*data_list)
end
-
- run_callbacks(batch) if association == 'project'
end
end
@@ -33,17 +33,15 @@ class BulkCreateIntegrationService
klass.insert_all(items_to_insert, returning: [:id])
end
- # rubocop: disable CodeReuse/ActiveRecord
def run_callbacks(batch)
- if integration.issue_tracker?
- Project.where(id: batch.select(:id)).update_all(has_external_issue_tracker: true)
+ if integration.issue_tracker? && integration.active?
+ batch.update_all(has_external_issue_tracker: true)
end
- if integration.type == 'ExternalWikiService'
- Project.where(id: batch.select(:id)).update_all(has_external_wiki: true)
+ if integration.type == 'ExternalWikiService' && integration.active?
+ batch.update_all(has_external_wiki: true)
end
end
- # rubocop: enable CodeReuse/ActiveRecord
def service_hash
if integration.template?
diff --git a/app/services/clusters/aws/authorize_role_service.rb b/app/services/clusters/aws/authorize_role_service.rb
index 2712a4b05bb..1f6f350bcc8 100644
--- a/app/services/clusters/aws/authorize_role_service.rb
+++ b/app/services/clusters/aws/authorize_role_service.rb
@@ -17,7 +17,8 @@ module Clusters
def initialize(user, params:)
@user = user
- @params = params
+ @role_arn = params[:role_arn]
+ @region = params[:region]
end
def execute
@@ -33,18 +34,18 @@ module Clusters
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 33efc4cc120..f94d8d8c66d 100644
--- a/app/services/clusters/aws/fetch_credentials_service.rb
+++ b/app/services/clusters/aws/fetch_credentials_service.rb
@@ -7,9 +7,10 @@ module Clusters
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 @@ module Clusters
private
- attr_reader :provider
+ attr_reader :provider, :region
def client
::Aws::STS::Client.new(credentials: gitlab_credentials, region: region)
@@ -44,10 +45,6 @@ module Clusters
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 00000000000..1816b6202bf
--- /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/changelogs/unreleased/268133-fix-propagate-integrations-for-project-callback.yml b/changelogs/unreleased/268133-fix-propagate-integrations-for-project-callback.yml
new file mode 100644
index 00000000000..6af3e240d16
--- /dev/null
+++ b/changelogs/unreleased/268133-fix-propagate-integrations-for-project-callback.yml
@@ -0,0 +1,5 @@
+---
+title: Fix project callbacks when propagating integrations
+merge_request: 45781
+author:
+type: fixed
diff --git a/changelogs/unreleased/jh-migration_mvc_gmau.yml b/changelogs/unreleased/jh-migration_mvc_gmau.yml
new file mode 100644
index 00000000000..5d3e2b95749
--- /dev/null
+++ b/changelogs/unreleased/jh-migration_mvc_gmau.yml
@@ -0,0 +1,6 @@
+---
+title: Add usage ping for unique users importing groups and projects via the group
+ migration tool
+merge_request: 45536
+author:
+type: changed
diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md
index 8b788e6d91d..5bfd38312df 100644
--- a/doc/administration/object_storage.md
+++ b/doc/administration/object_storage.md
@@ -288,6 +288,11 @@ Although Azure uses the word `container` to denote a collection of
blobs, GitLab standardizes on the term `bucket`. Be sure to configure
Azure container names in the `bucket` settings.
+Azure Blob storage can only be used with the [consolidated form](#consolidated-object-storage-configuration)
+because a single set of credentials are used to access multiple
+containers. The [storage-specific form](#storage-specific-configuration)
+is not supported. For more details, see [how to transition to consolidated form](#transition-to-consolidated-form).
+
The following are the valid connection parameters for Azure. Read the
[Azure Blob storage documentation](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction)
to learn more.
diff --git a/doc/development/changelog.md b/doc/development/changelog.md
index 922c4814d91..a633ab6919e 100644
--- a/doc/development/changelog.md
+++ b/doc/development/changelog.md
@@ -38,7 +38,8 @@ the `author` field. GitLab team members **should not**.
- [Security fixes](https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md)
**must** have a changelog entry, without `merge_request` value
and with `type` set to `security`.
-- Any user-facing change **should** have a changelog entry. This includes both visual changes (regardless of how minor), and changes to the rendered DOM which impact how a screen reader may announce the content.
+- Any user-facing change **must** have a changelog entry. This includes both visual changes (regardless of how minor), and changes to the rendered DOM which impact how a screen reader may announce the content.
+- Any client-facing change to our REST and GraphQL APIs **must** have a changelog entry.
- Performance improvements **should** have a changelog entry.
- Changes that need to be documented in the Product Analytics [Event Dictionary](product_analytics/event_dictionary.md)
also require a changelog entry.
diff --git a/doc/operations/metrics/dashboards/img/metrics_settings_button_v13_3.png b/doc/operations/metrics/dashboards/img/metrics_settings_button_v13_3.png
deleted file mode 100644
index 9c0eac12a3f..00000000000
--- a/doc/operations/metrics/dashboards/img/metrics_settings_button_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/metrics/dashboards/index.md b/doc/operations/metrics/dashboards/index.md
index 970bca70aff..ea7b987e7bb 100644
--- a/doc/operations/metrics/dashboards/index.md
+++ b/doc/operations/metrics/dashboards/index.md
@@ -116,14 +116,9 @@ Your custom dashboard is available at `https://example.com/project/-/metrics/cus
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/223204) in GitLab 13.2.
-To manage the settings for your metrics dashboard:
-
-1. Sign in as a user with project Maintainer or Administrator
- [permissions](../../../user/permissions.md#project-members-permissions).
-1. Navigate to your dashboard at **Operations > Metrics**.
-1. In the top-right corner of your dashboard, click **Metrics Settings**:
-
- ![Monitoring Dashboard actions menu with create new item](img/metrics_settings_button_v13_3.png)
+Users with project Maintainer or Administrator
+[permissions](../../../user/permissions.md#project-members-permissions)
+can manage [the settings](settings.md) for your metrics dashboard.
## Chart Context Menu
diff --git a/doc/operations/metrics/dashboards/settings.md b/doc/operations/metrics/dashboards/settings.md
index aa0b9a81771..6052b0778da 100644
--- a/doc/operations/metrics/dashboards/settings.md
+++ b/doc/operations/metrics/dashboards/settings.md
@@ -21,8 +21,8 @@ time zone, but you can display dates and times in UTC format. To change the
time zone:
1. Sign in as a user with Manage Project Operations [permissions](../../../user/permissions.md).
-1. Navigate to **Settings > Operations**, and scroll to
- **Metrics Dashboard**.
+1. Navigate to **Settings > Operations**.
+1. Scroll to **Metrics Dashboard** and click **Expand**.
1. In the **Dashboard timezone** select box, select *User's local timezone*
or *UTC*:
@@ -37,8 +37,8 @@ You can add a button on your monitoring dashboard that links directly to your
existing external dashboards:
1. Sign in as a user with Manage Project Operations [permissions](../../../user/permissions.md).
-1. Navigate to **Settings > Operations**, and scroll to
- **Metrics Dashboard**.
+1. Navigate to **Settings > Operations**.
+1. Scroll to **Metrics Dashboard** and click **Expand**.
1. In **External dashboard URL**, provide the URL to your external dashboard:
![External Dashboard Setting](img/dashboard_external_link_v13_1.png)
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index 2e9f36360c6..565bae99d50 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -391,7 +391,7 @@ with the permissions described on the documentation on [auditor users permission
[Read more about Auditor users.](../administration/auditor_users.md)
-## Users with minimal access **(PREMIUM ONLY)**
+## Users with minimal access **(PREMIUM)**
>[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40942) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.4.
diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb
index 1ce3ffe4c86..d5da260406f 100644
--- a/lib/gitlab/experimentation.rb
+++ b/lib/gitlab/experimentation.rb
@@ -201,7 +201,7 @@ module Gitlab
return false unless EXPERIMENTS.key?(experiment_key)
experiment = experiment(experiment_key)
- experiment.enabled? && experiment.enabled_for_environment?
+ experiment.enabled_for_environment? && experiment.enabled?
end
def enabled_for_attribute?(experiment_key, attribute)
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index e7e1ee949e6..030d50815a6 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -585,6 +585,9 @@ module Gitlab
users_created: count(::User.where(time_period), start: user_minimum_id, finish: user_maximum_id),
omniauth_providers: filtered_omniauth_provider_names.reject { |name| name == 'group_saml' },
user_auth_by_provider: distinct_count_user_auth_by_provider(time_period),
+ bulk_imports: {
+ gitlab: distinct_count(::BulkImport.where(time_period, source_type: :gitlab), :user_id)
+ },
projects_imported: {
gitlab_project: projects_imported_count('gitlab_project', time_period),
gitlab: projects_imported_count('gitlab', time_period),
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 0e61fbeb119..4f41df0e22b 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/factories/projects.rb b/spec/factories/projects.rb
index 87e4a8e355d..639fff06cec 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -10,8 +10,10 @@ FactoryBot.define do
factory :project, class: 'Project' do
sequence(:name) { |n| "project#{n}" }
path { name.downcase.gsub(/\s/, '_') }
- # Behaves differently to nil due to cache_has_external_issue_tracker
+
+ # Behaves differently to nil due to cache_has_external_* methods.
has_external_issue_tracker { false }
+ has_external_wiki { false }
# Associations
namespace
diff --git a/spec/factories/services.rb b/spec/factories/services.rb
index 13997080817..f4b73b6ed70 100644
--- a/spec/factories/services.rb
+++ b/spec/factories/services.rb
@@ -139,6 +139,13 @@ FactoryBot.define do
end
end
+ factory :external_wiki_service do
+ project
+ type { ExternalWikiService }
+ active { true }
+ external_wiki_url { 'http://external-wiki-url.com' }
+ end
+
factory :open_project_service do
project
active { true }
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 2600415fc9f..f9984091df0 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 0ef09b4b87e..03c22c570a8 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 f929216689a..f12f300872a 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/lib/gitlab/experimentation_spec.rb b/spec/lib/gitlab/experimentation_spec.rb
index e93593d348f..24f8db3a1c8 100644
--- a/spec/lib/gitlab/experimentation_spec.rb
+++ b/spec/lib/gitlab/experimentation_spec.rb
@@ -442,6 +442,14 @@ RSpec.describe Gitlab::Experimentation, :snowplow do
let(:environment) { ::Gitlab.com? }
it { is_expected.to be_falsey }
+
+ it 'ensures the typically less expensive environment is checked before the more expensive call to database for Feature' do
+ expect_next_instance_of(described_class::Experiment) do |experiment|
+ expect(experiment).not_to receive(:enabled?)
+ end
+
+ subject
+ end
end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 7f5d41e71a2..ada1feb2632 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -203,6 +203,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
for_defined_days_back do
user = create(:user)
+ create(:bulk_import, user: user)
+
%w(gitlab_project gitlab github bitbucket bitbucket_server gitea git manifest fogbugz phabricator).each do |type|
create(:project, import_type: type, creator_id: user.id)
end
@@ -215,6 +217,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(described_class.usage_activity_by_stage_manage({})).to include(
{
+ bulk_imports: {
+ gitlab: 2
+ },
projects_imported: {
gitlab_project: 2,
gitlab: 2,
@@ -235,6 +240,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
)
expect(described_class.usage_activity_by_stage_manage(described_class.last_28_days_time_period)).to include(
{
+ bulk_imports: {
+ gitlab: 1
+ },
projects_imported: {
gitlab_project: 1,
gitlab: 1,
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 2abcb39a1c8..306478774c1 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -890,7 +890,7 @@ RSpec.describe API::Projects do
expect(response).to have_gitlab_http_status(:created)
project.each_pair do |k, v|
- next if %i[has_external_issue_tracker issues_enabled merge_requests_enabled wiki_enabled storage_version].include?(k)
+ next if %i[has_external_issue_tracker has_external_wiki issues_enabled merge_requests_enabled wiki_enabled storage_version].include?(k)
expect(json_response[k.to_s]).to eq(v)
end
@@ -1309,7 +1309,7 @@ RSpec.describe API::Projects do
expect(response).to have_gitlab_http_status(:created)
project.each_pair do |k, v|
- next if %i[has_external_issue_tracker path storage_version].include?(k)
+ next if %i[has_external_issue_tracker has_external_wiki path storage_version].include?(k)
expect(json_response[k.to_s]).to eq(v)
end
diff --git a/spec/services/bulk_create_integration_service_spec.rb b/spec/services/bulk_create_integration_service_spec.rb
index 5d896f78b35..140b7a84d40 100644
--- a/spec/services/bulk_create_integration_service_spec.rb
+++ b/spec/services/bulk_create_integration_service_spec.rb
@@ -41,7 +41,7 @@ RSpec.describe BulkCreateIntegrationService do
end
end
- shared_examples 'runs project callbacks' do
+ shared_examples 'updates project callbacks' do
it 'updates projects#has_external_issue_tracker for issue tracker services' do
described_class.new(integration, batch, association).execute
@@ -49,14 +49,7 @@ RSpec.describe BulkCreateIntegrationService do
end
context 'with an external wiki integration' do
- let(:integration) do
- ExternalWikiService.create!(
- instance: true,
- active: true,
- push_events: false,
- external_wiki_url: 'http://external-wiki-url.com'
- )
- end
+ let(:integration) { create(:external_wiki_service, :instance) }
it 'updates projects#has_external_wiki for external wiki services' do
described_class.new(integration, batch, association).execute
@@ -66,18 +59,44 @@ RSpec.describe BulkCreateIntegrationService do
end
end
+ shared_examples 'does not update project callbacks' do
+ it 'does not update projects#has_external_issue_tracker for issue tracker services' do
+ described_class.new(integration, batch, association).execute
+
+ expect(project.reload.has_external_issue_tracker).to eq(false)
+ end
+
+ context 'with an inactive external wiki integration' do
+ let(:integration) { create(:external_wiki_service, :instance, active: false) }
+
+ it 'does not update projects#has_external_wiki for external wiki services' do
+ described_class.new(integration, batch, association).execute
+
+ expect(project.reload.has_external_wiki).to eq(false)
+ end
+ end
+ end
+
context 'with an instance-level integration' do
let(:integration) { instance_integration }
context 'with a project association' do
let!(:project) { create(:project) }
let(:created_integration) { project.jira_service }
- let(:batch) { Project.all }
+ let(:batch) { Project.without_integration(integration) }
let(:association) { 'project' }
it_behaves_like 'creates integration from batch ids'
it_behaves_like 'updates inherit_from_id'
- it_behaves_like 'runs project callbacks'
+ it_behaves_like 'updates project callbacks'
+
+ context 'when integration is not active' do
+ before do
+ integration.update!(active: false)
+ end
+
+ it_behaves_like 'does not update project callbacks'
+ end
end
context 'with a group association' do
@@ -101,7 +120,7 @@ RSpec.describe BulkCreateIntegrationService do
let(:association) { 'project' }
it_behaves_like 'creates integration from batch ids'
- it_behaves_like 'runs project callbacks'
+ it_behaves_like 'updates project callbacks'
end
end
end
diff --git a/spec/services/clusters/aws/authorize_role_service_spec.rb b/spec/services/clusters/aws/authorize_role_service_spec.rb
index 5b47cf0ecde..0659f92c927 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 @@ RSpec.describe Clusters::Aws::AuthorizeRoleService do
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 a0e63d96a5c..1e39f63a282 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 @@ RSpec.describe Clusters::Aws::FetchCredentialsService do
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'))
diff --git a/vendor/gitignore/C++.gitignore b/vendor/gitignore/C++.gitignore
index 259148fa18f..259148fa18f 100644..100755
--- a/vendor/gitignore/C++.gitignore
+++ b/vendor/gitignore/C++.gitignore
diff --git a/vendor/gitignore/Java.gitignore b/vendor/gitignore/Java.gitignore
index a1c2a238a96..a1c2a238a96 100644..100755
--- a/vendor/gitignore/Java.gitignore
+++ b/vendor/gitignore/Java.gitignore