diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-23 19:44:23 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-23 19:44:23 +0000 |
commit | 6b96d119aec0ba674cca2c380cf60f1500306612 (patch) | |
tree | f7742d802f557d04e2144b06a2b47719fbd58b82 /app | |
parent | 8b7c4494871c7d69ac7bc59839bdce6ff2937f95 (diff) | |
download | gitlab-ce-6b96d119aec0ba674cca2c380cf60f1500306612.tar.gz |
Add latest changes from gitlab-org/gitlab@13-1-stable-ee
Diffstat (limited to 'app')
10 files changed, 135 insertions, 44 deletions
diff --git a/app/assets/javascripts/monitoring/stores/utils.js b/app/assets/javascripts/monitoring/stores/utils.js index 058fab5f4fc..5795e756282 100644 --- a/app/assets/javascripts/monitoring/stores/utils.js +++ b/app/assets/javascripts/monitoring/stores/utils.js @@ -2,8 +2,8 @@ import { slugify } from '~/lib/utils/text_utility'; import createGqClient, { fetchPolicies } from '~/lib/graphql'; import { SUPPORTED_FORMATS } from '~/lib/utils/unit_format'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; -import { parseTemplatingVariables } from './variable_mapping'; import { NOT_IN_DB_PREFIX, linkTypes } from '../constants'; +import { mergeURLVariables, parseTemplatingVariables } from './variable_mapping'; import { DATETIME_RANGE_TYPES } from '~/lib/utils/constants'; import { timeRangeToParams, getRangeType } from '~/lib/utils/datetime_range'; import { isSafeURL, mergeUrlParams } from '~/lib/utils/url_utility'; @@ -289,7 +289,7 @@ export const mapToDashboardViewModel = ({ }) => { return { dashboard, - variables: parseTemplatingVariables(templating), + variables: mergeURLVariables(parseTemplatingVariables(templating)), links: links.map(mapLinksToViewModel), panelGroups: panel_groups.map(mapToPanelGroupViewModel), }; diff --git a/app/assets/javascripts/monitoring/stores/variable_mapping.js b/app/assets/javascripts/monitoring/stores/variable_mapping.js index 66b9899f673..c0a8150063b 100644 --- a/app/assets/javascripts/monitoring/stores/variable_mapping.js +++ b/app/assets/javascripts/monitoring/stores/variable_mapping.js @@ -1,4 +1,5 @@ import { isString } from 'lodash'; +import { templatingVariablesFromUrl } from '../utils'; import { VARIABLE_TYPES } from '../constants'; /** @@ -164,4 +165,39 @@ export const parseTemplatingVariables = ({ variables = {} } = {}) => return acc; }, {}); +/** + * Custom variables are defined in the dashboard yml file + * and their values can be passed through the URL. + * + * On component load, this method merges variables data + * from the yml file with URL data to store in the Vuex store. + * Not all params coming from the URL need to be stored. Only + * the ones that have a corresponding variable defined in the + * yml file. + * + * This ensures that there is always a single source of truth + * for variables + * + * This method can be improved further. See the below issue + * https://gitlab.com/gitlab-org/gitlab/-/issues/217713 + * + * @param {Object} varsFromYML template variables from yml file + * @returns {Object} + */ +export const mergeURLVariables = (varsFromYML = {}) => { + const varsFromURL = templatingVariablesFromUrl(); + const variables = {}; + Object.keys(varsFromYML).forEach(key => { + if (Object.prototype.hasOwnProperty.call(varsFromURL, key)) { + variables[key] = { + ...varsFromYML[key], + value: varsFromURL[key], + }; + } else { + variables[key] = varsFromYML[key]; + } + }); + return variables; +}; + export default {}; diff --git a/app/assets/javascripts/monitoring/utils.js b/app/assets/javascripts/monitoring/utils.js index 95d544bd6d4..4d2927a066e 100644 --- a/app/assets/javascripts/monitoring/utils.js +++ b/app/assets/javascripts/monitoring/utils.js @@ -170,11 +170,10 @@ export const convertVariablesForURL = variables => * begin with a constant prefix so that it doesn't collide with * other URL params. * - * @param {String} New URL + * @param {String} search URL * @returns {Object} The custom variables defined by the user in the URL */ - -export const getPromCustomVariablesFromUrl = (search = window.location.search) => { +export const templatingVariablesFromUrl = (search = window.location.search) => { const params = queryToObject(search); // pick the params with variable prefix const paramsWithVars = pickBy(params, (val, key) => key.startsWith(VARIABLE_PREFIX)); @@ -353,39 +352,4 @@ export const barChartsDataParser = (data = []) => {}, ); -/** - * Custom variables are defined in the dashboard yml file - * and their values can be passed through the URL. - * - * On component load, this method merges variables data - * from the yml file with URL data to store in the Vuex store. - * Not all params coming from the URL need to be stored. Only - * the ones that have a corresponding variable defined in the - * yml file. - * - * This ensures that there is always a single source of truth - * for variables - * - * This method can be improved further. See the below issue - * https://gitlab.com/gitlab-org/gitlab/-/issues/217713 - * - * @param {Object} varsFromYML template variables from yml file - * @returns {Object} - */ -export const mergeURLVariables = (varsFromYML = {}) => { - const varsFromURL = getPromCustomVariablesFromUrl(); - const variables = {}; - Object.keys(varsFromYML).forEach(key => { - if (Object.prototype.hasOwnProperty.call(varsFromURL, key)) { - variables[key] = { - ...varsFromYML[key], - value: varsFromURL[key], - }; - } else { - variables[key] = varsFromYML[key]; - } - }); - return variables; -}; - export default {}; diff --git a/app/controllers/repositories/git_http_client_controller.rb b/app/controllers/repositories/git_http_client_controller.rb index d03daa406cf..e02955433b2 100644 --- a/app/controllers/repositories/git_http_client_controller.rb +++ b/app/controllers/repositories/git_http_client_controller.rb @@ -18,8 +18,7 @@ module Repositories skip_around_action :set_session_storage skip_before_action :verify_authenticity_token - before_action :parse_repo_path - before_action :authenticate_user + prepend_before_action :authenticate_user, :parse_repo_path private diff --git a/app/services/authorized_project_update/periodic_recalculate_service.rb b/app/services/authorized_project_update/periodic_recalculate_service.rb new file mode 100644 index 00000000000..91c0f50e5e0 --- /dev/null +++ b/app/services/authorized_project_update/periodic_recalculate_service.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module AuthorizedProjectUpdate + class PeriodicRecalculateService + BATCH_SIZE = 480 + DELAY_INTERVAL = 30.seconds.to_i + + def execute + # Using this approach (instead of eg. User.each_batch) keeps the arguments + # the same for AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker + # even if the user list changes, so we can deduplicate these jobs. + (1..User.maximum(:id)).each_slice(BATCH_SIZE).with_index do |batch, index| + delay = DELAY_INTERVAL * index + AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker.perform_in(delay, *batch.minmax) + end + end + end +end diff --git a/app/services/authorized_project_update/recalculate_for_user_range_service.rb b/app/services/authorized_project_update/recalculate_for_user_range_service.rb new file mode 100644 index 00000000000..14b0f5d6117 --- /dev/null +++ b/app/services/authorized_project_update/recalculate_for_user_range_service.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module AuthorizedProjectUpdate + class RecalculateForUserRangeService + def initialize(start_user_id, end_user_id) + @start_user_id = start_user_id + @end_user_id = end_user_id + end + + def execute + User.where(id: start_user_id..end_user_id).select(:id).find_each do |user| # rubocop: disable CodeReuse/ActiveRecord + Users::RefreshAuthorizedProjectsService.new(user).execute + end + end + + private + + attr_reader :start_user_id, :end_user_id + end +end diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb index 0e7a4821bdf..621266f00e1 100644 --- a/app/services/users/refresh_authorized_projects_service.rb +++ b/app/services/users/refresh_authorized_projects_service.rb @@ -85,8 +85,6 @@ module Users # remove - The IDs of the authorization rows to remove. # add - Rows to insert in the form `[user id, project id, access level]` def update_authorizations(remove = [], add = []) - return if remove.empty? && add.empty? - User.transaction do user.remove_project_authorizations(remove) unless remove.empty? ProjectAuthorization.insert_authorizations(add) unless add.empty? diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 0699be0f4cb..3baa2166812 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -11,6 +11,14 @@ :weight: 1 :idempotent: true :tags: [] +- :name: authorized_project_update:authorized_project_update_user_refresh_over_user_range + :feature_category: :authentication_and_authorization + :has_external_dependencies: + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: true + :tags: [] - :name: authorized_project_update:authorized_project_update_user_refresh_with_low_urgency :feature_category: :authentication_and_authorization :has_external_dependencies: @@ -99,6 +107,14 @@ :weight: 1 :idempotent: :tags: [] +- :name: cronjob:authorized_project_update_periodic_recalculate + :feature_category: :source_code_management + :has_external_dependencies: + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: true + :tags: [] - :name: cronjob:ci_archive_traces_cron :feature_category: :continuous_integration :has_external_dependencies: diff --git a/app/workers/authorized_project_update/periodic_recalculate_worker.rb b/app/workers/authorized_project_update/periodic_recalculate_worker.rb new file mode 100644 index 00000000000..0d1ad67d7bb --- /dev/null +++ b/app/workers/authorized_project_update/periodic_recalculate_worker.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module AuthorizedProjectUpdate + class PeriodicRecalculateWorker + include ApplicationWorker + # This worker does not perform work scoped to a context + include CronjobQueue # rubocop:disable Scalability/CronWorkerContext + + feature_category :source_code_management + urgency :low + + idempotent! + + def perform + if ::Feature.enabled?(:periodic_project_authorization_recalculation, default_enabled: true) + AuthorizedProjectUpdate::PeriodicRecalculateService.new.execute + end + end + end +end diff --git a/app/workers/authorized_project_update/user_refresh_over_user_range_worker.rb b/app/workers/authorized_project_update/user_refresh_over_user_range_worker.rb new file mode 100644 index 00000000000..336b1c5443e --- /dev/null +++ b/app/workers/authorized_project_update/user_refresh_over_user_range_worker.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module AuthorizedProjectUpdate + class UserRefreshOverUserRangeWorker + include ApplicationWorker + + feature_category :authentication_and_authorization + urgency :low + queue_namespace :authorized_project_update + deduplicate :until_executing, including_scheduled: true + + idempotent! + + def perform(start_user_id, end_user_id) + if ::Feature.enabled?(:periodic_project_authorization_recalculation, default_enabled: true) + AuthorizedProjectUpdate::RecalculateForUserRangeService.new(start_user_id, end_user_id).execute + end + end + end +end |