diff options
Diffstat (limited to 'app')
33 files changed, 291 insertions, 241 deletions
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js index 303d6d1dba9..48abc072675 100644 --- a/app/assets/javascripts/lib/utils/url_utility.js +++ b/app/assets/javascripts/lib/utils/url_utility.js @@ -323,7 +323,7 @@ export function isAbsolute(url) { * @param {String} url */ export function isRootRelative(url) { - return /^\//.test(url); + return /^\/(?!\/)/.test(url); } /** diff --git a/app/assets/javascripts/packages/details/components/file_sha.vue b/app/assets/javascripts/packages/details/components/file_sha.vue new file mode 100644 index 00000000000..a25839be7e1 --- /dev/null +++ b/app/assets/javascripts/packages/details/components/file_sha.vue @@ -0,0 +1,41 @@ +<script> +import { s__ } from '~/locale'; +import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; +import DetailsRow from '~/vue_shared/components/registry/details_row.vue'; + +export default { + name: 'FileSha', + components: { + DetailsRow, + ClipboardButton, + }, + props: { + sha: { + type: String, + required: true, + }, + title: { + type: String, + required: true, + }, + }, + i18n: { + copyButtonTitle: s__('PackageRegistry|Copy SHA'), + }, +}; +</script> + +<template> + <details-row dashed> + <div class="gl-px-4"> + {{ title }}: + {{ sha }} + <clipboard-button + :text="sha" + :title="$options.i18n.copyButtonTitle" + category="tertiary" + size="small" + /> + </div> + </details-row> +</template> diff --git a/app/assets/javascripts/packages/details/components/package_files.vue b/app/assets/javascripts/packages/details/components/package_files.vue index 735f5c2e5cd..3c71ac5137e 100644 --- a/app/assets/javascripts/packages/details/components/package_files.vue +++ b/app/assets/javascripts/packages/details/components/package_files.vue @@ -1,8 +1,9 @@ <script> -import { GlLink, GlTable, GlDropdownItem, GlDropdown, GlIcon } from '@gitlab/ui'; +import { GlLink, GlTable, GlDropdownItem, GlDropdown, GlIcon, GlButton } from '@gitlab/ui'; import { last } from 'lodash'; import { numberToHumanSize } from '~/lib/utils/number_utils'; import { __ } from '~/locale'; +import FileSha from '~/packages/details/components/file_sha.vue'; import Tracking from '~/tracking'; import FileIcon from '~/vue_shared/components/file_icon.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; @@ -15,8 +16,10 @@ export default { GlIcon, GlDropdown, GlDropdownItem, + GlButton, FileIcon, TimeAgoTooltip, + FileSha, }, mixins: [Tracking.mixin()], props: { @@ -76,6 +79,9 @@ export default { formatSize(size) { return numberToHumanSize(size); }, + hasDetails(item) { + return item.file_sha256 || item.file_md5 || item.file_sha1; + }, }, i18n: { deleteFile: __('Delete file'), @@ -91,7 +97,15 @@ export default { :items="filesTableRows" :tbody-tr-attr="{ 'data-testid': 'file-row' }" > - <template #cell(name)="{ item }"> + <template #cell(name)="{ item, toggleDetails, detailsShowing }"> + <gl-button + v-if="hasDetails(item)" + :icon="detailsShowing ? 'angle-up' : 'angle-down'" + :aria-label="detailsShowing ? __('Collapse') : __('Expand')" + category="tertiary" + size="small" + @click="toggleDetails" + /> <gl-link :href="item.download_path" class="gl-text-gray-500" @@ -131,6 +145,21 @@ export default { </gl-dropdown-item> </gl-dropdown> </template> + + <template #row-details="{ item }"> + <div + class="gl-display-flex gl-flex-direction-column gl-flex-fill-1 gl-bg-gray-10 gl-rounded-base gl-inset-border-1-gray-100" + > + <file-sha + v-if="item.file_sha256" + data-testid="sha-256" + title="SHA-256" + :sha="item.file_sha256" + /> + <file-sha v-if="item.file_md5" data-testid="md5" title="MD5" :sha="item.file_md5" /> + <file-sha v-if="item.file_sha1" data-testid="sha-1" title="SHA-1" :sha="item.file_sha1" /> + </div> + </template> </gl-table> </div> </template> diff --git a/app/assets/javascripts/pages/projects/forks/new/components/app.vue b/app/assets/javascripts/pages/projects/forks/new/components/app.vue index 02b357d389b..7fb41c6e7b7 100644 --- a/app/assets/javascripts/pages/projects/forks/new/components/app.vue +++ b/app/assets/javascripts/pages/projects/forks/new/components/app.vue @@ -38,6 +38,10 @@ export default { type: String, required: true, }, + restrictedVisibilityLevels: { + type: Array, + required: true, + }, }, }; </script> @@ -66,6 +70,7 @@ export default { :project-path="projectPath" :project-description="projectDescription" :project-visibility="projectVisibility" + :restricted-visibility-levels="restrictedVisibilityLevels" /> </div> </div> diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue index 96bd38ea9e2..75c3b6d564c 100644 --- a/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue +++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue @@ -95,6 +95,10 @@ export default { type: String, required: true, }, + restrictedVisibilityLevels: { + type: Array, + required: true, + }, }, data() { const form = { @@ -111,7 +115,7 @@ export default { required: false, skipValidation: true, }), - visibility: initFormField({ value: this.projectVisibility }), + visibility: initFormField({ value: this.getInitialVisibilityValue() }), }, }; return { @@ -134,13 +138,28 @@ export default { visibilityLevelCap() { return Math.min(this.projectVisibilityLevel, this.namespaceVisibilityLevel); }, + restrictedVisibilityLevelsSet() { + return new Set(this.restrictedVisibilityLevels); + }, allowedVisibilityLevels() { - return Object.entries(VISIBILITY_LEVEL).reduce((levels, [levelName, levelValue]) => { - if (levelValue <= this.visibilityLevelCap) { - levels.push(levelName); - } - return levels; - }, []); + const allowedLevels = Object.entries(VISIBILITY_LEVEL).reduce( + (levels, [levelName, levelValue]) => { + if ( + !this.restrictedVisibilityLevelsSet.has(levelValue) && + levelValue <= this.visibilityLevelCap + ) { + levels.push(levelName); + } + return levels; + }, + [], + ); + + if (!allowedLevels.length) { + return [PRIVATE_VISIBILITY]; + } + + return allowedLevels; }, visibilityLevels() { return [ @@ -173,7 +192,8 @@ export default { watch: { // eslint-disable-next-line func-names 'form.fields.namespace.value': function () { - this.form.fields.visibility.value = PRIVATE_VISIBILITY; + this.form.fields.visibility.value = + this.restrictedVisibilityLevels.length !== 0 ? null : PRIVATE_VISIBILITY; }, // eslint-disable-next-line func-names 'form.fields.name.value': function (newVal) { @@ -191,6 +211,9 @@ export default { isVisibilityLevelDisabled(visibility) { return !this.allowedVisibilityLevels.includes(visibility); }, + getInitialVisibilityValue() { + return this.restrictedVisibilityLevels.length !== 0 ? null : this.projectVisibility; + }, async onSubmit() { this.form.showValidation = true; @@ -340,6 +363,7 @@ export default { v-model="form.fields.visibility.value" data-testid="fork-visibility-radio-group" name="visibility" + :aria-label="__('visibility')" required > <gl-form-radio diff --git a/app/assets/javascripts/pages/projects/forks/new/index.js b/app/assets/javascripts/pages/projects/forks/new/index.js index 372967c8a1e..1a171252048 100644 --- a/app/assets/javascripts/pages/projects/forks/new/index.js +++ b/app/assets/javascripts/pages/projects/forks/new/index.js @@ -16,6 +16,7 @@ if (gon.features.forkProjectForm) { projectPath, projectDescription, projectVisibility, + restrictedVisibilityLevels, } = mountElement.dataset; // eslint-disable-next-line no-new @@ -38,6 +39,7 @@ if (gon.features.forkProjectForm) { projectPath, projectDescription, projectVisibility, + restrictedVisibilityLevels: JSON.parse(restrictedVisibilityLevels), }, }); }, diff --git a/app/assets/javascripts/repository/log_tree.js b/app/assets/javascripts/repository/log_tree.js index 7d9d962b6f4..ac02392d60f 100644 --- a/app/assets/javascripts/repository/log_tree.js +++ b/app/assets/javascripts/repository/log_tree.js @@ -8,6 +8,12 @@ import refQuery from './queries/ref.query.graphql'; const fetchpromises = {}; const resolvers = {}; let maxOffset; +let nextOffset; +let currentPath; + +function setNextOffset(offset) { + nextOffset = offset || null; +} export function resolveCommit(commits, path, { resolve, entry }) { const commit = commits.find( @@ -24,7 +30,17 @@ export function fetchLogsTree(client, path, offset, resolver = null, _maxOffset maxOffset = _maxOffset; } - if (Number(offset) > maxOffset) { + if (!currentPath || currentPath !== path) { + // ensures the nextOffset is reset if the user changed directories + setNextOffset(null); + } + + currentPath = path; + + const offsetNumber = Number(offset); + + if (!nextOffset && offsetNumber > maxOffset) { + setNextOffset(offsetNumber - 25); // ensures commit data is fetched for newly added rows that need data from the previous request (requests are made in batches of 25). return Promise.resolve(); } @@ -47,7 +63,7 @@ export function fetchLogsTree(client, path, offset, resolver = null, _maxOffset path.replace(/^\//, ''), )}`, { - params: { format: 'json', offset }, + params: { format: 'json', offset: nextOffset || offset }, }, ) .then(({ data: newData, headers }) => { @@ -66,10 +82,12 @@ export function fetchLogsTree(client, path, offset, resolver = null, _maxOffset delete fetchpromises[path]; if (headerLogsOffset) { + setNextOffset(null); fetchLogsTree(client, path, headerLogsOffset); } else { delete resolvers[path]; maxOffset = null; + setNextOffset(null); } }); diff --git a/app/assets/javascripts/vue_shared/components/registry/details_row.vue b/app/assets/javascripts/vue_shared/components/registry/details_row.vue index 2e245fadead..72e06b45561 100644 --- a/app/assets/javascripts/vue_shared/components/registry/details_row.vue +++ b/app/assets/javascripts/vue_shared/components/registry/details_row.vue @@ -8,7 +8,8 @@ export default { props: { icon: { type: String, - required: true, + required: false, + default: null, }, padding: { type: String, @@ -34,7 +35,7 @@ export default { class="gl-display-flex gl-align-items-center gl-font-monospace gl-font-sm gl-word-break-all" :class="[padding, borderClass]" > - <gl-icon :name="icon" class="gl-mr-4" /> + <gl-icon v-if="icon" :name="icon" class="gl-mr-4" /> <span> <slot></slot> </span> diff --git a/app/controllers/clusters/applications_controller.rb b/app/controllers/clusters/applications_controller.rb index c533fe007d7..5c1d85f4374 100644 --- a/app/controllers/clusters/applications_controller.rb +++ b/app/controllers/clusters/applications_controller.rb @@ -47,7 +47,7 @@ class Clusters::ApplicationsController < Clusters::BaseController end def cluster_application_params - params.permit(:application, :hostname, :pages_domain_id, :email, :stack, :modsecurity_enabled, :modsecurity_mode, :host, :port, :protocol, :waf_log_enabled, :cilium_log_enabled) + params.permit(:application, :hostname, :pages_domain_id, :email, :stack, :host, :port, :protocol, :cilium_log_enabled) end def cluster_application_destroy_params diff --git a/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb b/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb new file mode 100644 index 00000000000..c51a5ac7b88 --- /dev/null +++ b/app/controllers/projects/analytics/cycle_analytics/summary_controller.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class Projects::Analytics::CycleAnalytics::SummaryController < Projects::ApplicationController + include CycleAnalyticsParams + + respond_to :json + + feature_category :planning_analytics + + before_action :authorize_read_cycle_analytics! + + def show + render json: project_level.summary + end + + private + + def project_level + @project_level ||= Analytics::CycleAnalytics::ProjectLevel.new(project: @project, options: options(allowed_params)) + end + + def allowed_params + params.permit(:created_after, :created_before) + end +end + +Projects::Analytics::CycleAnalytics::SummaryController.prepend_mod_with('Projects::Analytics::CycleAnalytics::SummaryController') diff --git a/app/controllers/projects/cycle_analytics/events_controller.rb b/app/controllers/projects/cycle_analytics/events_controller.rb index 3a5dd23047c..a1da8d4e91f 100644 --- a/app/controllers/projects/cycle_analytics/events_controller.rb +++ b/app/controllers/projects/cycle_analytics/events_controller.rb @@ -53,7 +53,7 @@ module Projects end def cycle_analytics - @cycle_analytics ||= ::CycleAnalytics::ProjectLevel.new(project, options: options(cycle_analytics_project_params)) + @cycle_analytics ||= ::Analytics::CycleAnalytics::ProjectLevel.new(project: project, options: options(cycle_analytics_project_params)) end end end diff --git a/app/controllers/projects/cycle_analytics_controller.rb b/app/controllers/projects/cycle_analytics_controller.rb index 5c15a5d246c..d1d27286c68 100644 --- a/app/controllers/projects/cycle_analytics_controller.rb +++ b/app/controllers/projects/cycle_analytics_controller.rb @@ -14,7 +14,7 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController feature_category :planning_analytics def show - @cycle_analytics = ::CycleAnalytics::ProjectLevel.new(@project, options: options(cycle_analytics_project_params)) + @cycle_analytics = Analytics::CycleAnalytics::ProjectLevel.new(project: @project, options: options(cycle_analytics_project_params)) respond_to do |format| format.html do diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index f0e4cd10366..116e7970bbf 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -176,11 +176,7 @@ class Projects::PipelinesController < Projects::ApplicationController end def retry - if Gitlab::Ci::Features.background_pipeline_retry_endpoint?(@project) - ::Ci::RetryPipelineWorker.perform_async(pipeline.id, current_user.id) # rubocop:disable CodeReuse/Worker - else - pipeline.retry_failed(current_user) - end + ::Ci::RetryPipelineWorker.perform_async(pipeline.id, current_user.id) # rubocop:disable CodeReuse/Worker respond_to do |format| format.html do diff --git a/app/finders/ci/runners_finder.rb b/app/finders/ci/runners_finder.rb index 60dd977ff94..7ad51361efd 100644 --- a/app/finders/ci/runners_finder.rb +++ b/app/finders/ci/runners_finder.rb @@ -4,6 +4,9 @@ module Ci class RunnersFinder < UnionFinder include Gitlab::Allowable + ALLOWED_SORTS = %w[contacted_asc contacted_desc created_at_asc created_at_desc created_date].freeze + DEFAULT_SORT = 'created_at_desc' + def initialize(current_user:, group: nil, params:) @params = params @group = group @@ -24,11 +27,7 @@ module Ci end def sort_key - if @params[:sort] == 'contacted_asc' - 'contacted_asc' - else - 'created_date' - end + ALLOWED_SORTS.include?(@params[:sort]) ? @params[:sort] : DEFAULT_SORT end private diff --git a/app/graphql/mutations/ci/ci_cd_settings_update.rb b/app/graphql/mutations/ci/ci_cd_settings_update.rb index a484c2438a4..0973e9beae3 100644 --- a/app/graphql/mutations/ci/ci_cd_settings_update.rb +++ b/app/graphql/mutations/ci/ci_cd_settings_update.rb @@ -17,6 +17,10 @@ module Mutations required: false, description: 'Indicates if the latest artifact should be kept for this project.' + argument :job_token_scope_enabled, GraphQL::BOOLEAN_TYPE, + required: false, + description: 'Indicates CI job tokens generated in this project have restricted access to resources.' + field :ci_cd_settings, Types::Ci::CiCdSettingType, null: false, diff --git a/app/graphql/types/ci/ci_cd_setting_type.rb b/app/graphql/types/ci/ci_cd_setting_type.rb index b34a91446a2..f90c75454ba 100644 --- a/app/graphql/types/ci/ci_cd_setting_type.rb +++ b/app/graphql/types/ci/ci_cd_setting_type.rb @@ -16,6 +16,9 @@ module Types field :keep_latest_artifact, GraphQL::BOOLEAN_TYPE, null: true, description: 'Whether to keep the latest builds artifacts.', method: :keep_latest_artifacts_available? + field :job_token_scope_enabled, GraphQL::BOOLEAN_TYPE, null: true, + description: 'Indicates CI job tokens generated in this project have restricted access to resources.', + method: :job_token_scope_enabled? field :project, Types::ProjectType, null: true, description: 'Project the CI/CD settings belong to.' end diff --git a/app/graphql/types/ci/runner_sort_enum.rb b/app/graphql/types/ci/runner_sort_enum.rb index 550e870316a..95ec1867fea 100644 --- a/app/graphql/types/ci/runner_sort_enum.rb +++ b/app/graphql/types/ci/runner_sort_enum.rb @@ -7,7 +7,9 @@ module Types description 'Values for sorting runners' value 'CONTACTED_ASC', 'Ordered by contacted_at in ascending order.', value: :contacted_asc - value 'CREATED_DESC', 'Ordered by created_date in descending order.', value: :created_date + value 'CONTACTED_DESC', 'Ordered by contacted_at in descending order.', value: :contacted_desc + value 'CREATED_ASC', 'Ordered by created_at in ascending order.', value: :created_at_asc + value 'CREATED_DESC', 'Ordered by created_at in descending order.', value: :created_at_desc end end end diff --git a/app/models/analytics/cycle_analytics/project_level.rb b/app/models/analytics/cycle_analytics/project_level.rb new file mode 100644 index 00000000000..7a73bc75ed6 --- /dev/null +++ b/app/models/analytics/cycle_analytics/project_level.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Analytics + module CycleAnalytics + class ProjectLevel + attr_reader :project, :options + + def initialize(project:, options:) + @project = project + @options = options.merge(project: project) + end + + def summary + @summary ||= ::Gitlab::CycleAnalytics::StageSummary.new(project, + options: options, + current_user: options[:current_user]).data + end + + def permissions(user:) + Gitlab::CycleAnalytics::Permissions.get(user: user, project: project) + end + + def stats + @stats ||= default_stage_names.map do |stage_name| + self[stage_name].as_json + end + end + + def [](stage_name) + ::CycleAnalytics::ProjectLevelStageAdapter.new(build_stage(stage_name), options) + end + + private + + def build_stage(stage_name) + stage_params = stage_params_by_name(stage_name).merge(project: project) + Analytics::CycleAnalytics::ProjectStage.new(stage_params) + end + + def stage_params_by_name(name) + Gitlab::Analytics::CycleAnalytics::DefaultStages.find_by_name!(name) + end + + def default_stage_names + Gitlab::Analytics::CycleAnalytics::DefaultStages.symbolized_stage_names + end + end + end +end diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 14ec3a6838c..71110ef0696 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -134,6 +134,8 @@ module Ci end scope :order_contacted_at_asc, -> { order(contacted_at: :asc) } + scope :order_contacted_at_desc, -> { order(contacted_at: :desc) } + scope :order_created_at_asc, -> { order(created_at: :asc) } scope :order_created_at_desc, -> { order(created_at: :desc) } scope :with_tags, -> { preload(:tags) } @@ -190,8 +192,13 @@ module Ci end def self.order_by(order) - if order == 'contacted_asc' + case order + when 'contacted_asc' order_contacted_at_asc + when 'contacted_desc' + order_contacted_at_desc + when 'created_at_asc' + order_created_at_asc else order_created_at_desc end diff --git a/app/models/clusters/applications/fluentd.rb b/app/models/clusters/applications/fluentd.rb index 8d0bf7b6321..c5d674c1908 100644 --- a/app/models/clusters/applications/fluentd.rb +++ b/app/models/clusters/applications/fluentd.rb @@ -12,11 +12,13 @@ module Clusters include ::Clusters::Concerns::ApplicationStatus include ::Clusters::Concerns::ApplicationVersion include ::Clusters::Concerns::ApplicationData + include IgnorableColumns default_value_for :version, VERSION default_value_for :port, 514 default_value_for :protocol, :tcp - default_value_for :waf_log_enabled, false + + ignore_column :waf_log_enabled, remove_with: '14.2', remove_after: '2021-07-22' enum protocol: { tcp: 0, udp: 1 } @@ -48,9 +50,7 @@ module Clusters private def has_at_least_one_log_enabled? - if !waf_log_enabled && !cilium_log_enabled - errors.add(:base, _("At least one logging option is required to be enabled")) - end + errors.add(:base, _("At least one logging option is required to be enabled")) unless cilium_log_enabled end def content_values @@ -113,7 +113,6 @@ module Clusters def path_to_logs path = [] - path << "/var/log/containers/*#{Ingress::MODSECURITY_LOG_CONTAINER_NAME}*.log" if waf_log_enabled path << "/var/log/containers/*#{CILIUM_CONTAINER_NAME}*.log" if cilium_log_enabled path.join(',') end diff --git a/app/models/clusters/applications/ingress.rb b/app/models/clusters/applications/ingress.rb index e7d4d737b8e..3a8c314efe4 100644 --- a/app/models/clusters/applications/ingress.rb +++ b/app/models/clusters/applications/ingress.rb @@ -7,10 +7,6 @@ module Clusters class Ingress < ApplicationRecord VERSION = '1.40.2' INGRESS_CONTAINER_NAME = 'nginx-ingress-controller' - MODSECURITY_LOG_CONTAINER_NAME = 'modsecurity-log' - MODSECURITY_MODE_LOGGING = "DetectionOnly" - MODSECURITY_MODE_BLOCKING = "On" - MODSECURITY_OWASP_RULES_FILE = "/etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf" self.table_name = 'clusters_applications_ingress' @@ -20,22 +16,18 @@ module Clusters include ::Clusters::Concerns::ApplicationData include AfterCommitQueue include UsageStatistics + include IgnorableColumns default_value_for :ingress_type, :nginx - default_value_for :modsecurity_enabled, true default_value_for :version, VERSION - default_value_for :modsecurity_mode, :logging + + ignore_column :modsecurity_enabled, remove_with: '14.2', remove_after: '2021-07-22' + ignore_column :modsecurity_mode, remove_with: '14.2', remove_after: '2021-07-22' enum ingress_type: { nginx: 1 } - enum modsecurity_mode: { logging: 0, blocking: 1 } - - scope :modsecurity_not_installed, -> { where(modsecurity_enabled: nil) } - scope :modsecurity_enabled, -> { where(modsecurity_enabled: true) } - scope :modsecurity_disabled, -> { where(modsecurity_enabled: false) } - FETCH_IP_ADDRESS_DELAY = 30.seconds state_machine :status do @@ -92,96 +84,13 @@ module Clusters private - def specification - return {} unless modsecurity_enabled - - { - "controller" => { - "config" => { - "enable-modsecurity" => "true", - "enable-owasp-modsecurity-crs" => "false", - "modsecurity-snippet" => modsecurity_snippet_content, - "modsecurity.conf" => modsecurity_config_content - }, - "extraContainers" => [ - { - "name" => MODSECURITY_LOG_CONTAINER_NAME, - "image" => "busybox", - "args" => [ - "/bin/sh", - "-c", - "tail -F /var/log/modsec/audit.log" - ], - "volumeMounts" => [ - { - "name" => "modsecurity-log-volume", - "mountPath" => "/var/log/modsec", - "readOnly" => true - } - ], - "livenessProbe" => { - "exec" => { - "command" => [ - "ls", - "/var/log/modsec/audit.log" - ] - } - } - } - ], - "extraVolumeMounts" => [ - { - "name" => "modsecurity-template-volume", - "mountPath" => "/etc/nginx/modsecurity/modsecurity.conf", - "subPath" => "modsecurity.conf" - }, - { - "name" => "modsecurity-log-volume", - "mountPath" => "/var/log/modsec" - } - ], - "extraVolumes" => [ - { - "name" => "modsecurity-template-volume", - "configMap" => { - "name" => "ingress-#{INGRESS_CONTAINER_NAME}", - "items" => [ - { - "key" => "modsecurity.conf", - "path" => "modsecurity.conf" - } - ] - } - }, - { - "name" => "modsecurity-log-volume", - "emptyDir" => {} - } - ] - } - } - end - - def modsecurity_config_content - File.read(modsecurity_config_file_path) - end - - def modsecurity_config_file_path - Rails.root.join('vendor', 'ingress', 'modsecurity.conf') - end - def content_values - YAML.load_file(chart_values_file).deep_merge!(specification) + YAML.load_file(chart_values_file) end def application_jupyter_installed? cluster.application_jupyter&.installed? end - - def modsecurity_snippet_content - sec_rule_engine = logging? ? MODSECURITY_MODE_LOGGING : MODSECURITY_MODE_BLOCKING - "SecRuleEngine #{sec_rule_engine}\nInclude #{MODSECURITY_OWASP_RULES_FILE}" - end end end end diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index 257a7043ce2..aeebd2b368e 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -138,7 +138,6 @@ module Clusters scope :gcp_installed, -> { gcp_provided.joins(:provider_gcp).merge(Clusters::Providers::Gcp.with_status(:created)) } scope :aws_installed, -> { aws_provided.joins(:provider_aws).merge(Clusters::Providers::Aws.with_status(:created)) } - scope :with_enabled_modsecurity, -> { joins(:application_ingress).merge(::Clusters::Applications::Ingress.modsecurity_enabled) } scope :with_available_elasticstack, -> { joins(:application_elastic_stack).merge(::Clusters::Applications::ElasticStack.available) } scope :with_available_cilium, -> { joins(:application_cilium).merge(::Clusters::Applications::Cilium.available) } scope :distinct_with_deployed_environments, -> { joins(:environments).merge(::Deployment.success).distinct } diff --git a/app/models/cycle_analytics/project_level.rb b/app/models/cycle_analytics/project_level.rb deleted file mode 100644 index 5bd07b3f6c3..00000000000 --- a/app/models/cycle_analytics/project_level.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -module CycleAnalytics - class ProjectLevel - attr_reader :project, :options - - def initialize(project, options:) - @project = project - @options = options.merge(project: project) - end - - def summary - @summary ||= ::Gitlab::CycleAnalytics::StageSummary.new(project, - from: options[:from], - to: options[:to], - current_user: options[:current_user]).data - end - - def permissions(user:) - Gitlab::CycleAnalytics::Permissions.get(user: user, project: project) - end - - def stats - @stats ||= default_stage_names.map do |stage_name| - self[stage_name].as_json - end - end - - def [](stage_name) - CycleAnalytics::ProjectLevelStageAdapter.new(build_stage(stage_name), options) - end - - private - - def build_stage(stage_name) - stage_params = stage_params_by_name(stage_name).merge(project: project) - Analytics::CycleAnalytics::ProjectStage.new(stage_params) - end - - def stage_params_by_name(name) - Gitlab::Analytics::CycleAnalytics::DefaultStages.find_by_name!(name) - end - - def default_stage_names - Gitlab::Analytics::CycleAnalytics::DefaultStages.symbolized_stage_names - end - end -end diff --git a/app/models/members/last_group_owner_assigner.rb b/app/models/members/last_group_owner_assigner.rb index 64decb1df36..dcf0a2d0ad3 100644 --- a/app/models/members/last_group_owner_assigner.rb +++ b/app/models/members/last_group_owner_assigner.rb @@ -1,46 +1,44 @@ # frozen_string_literal: true -module Members - class LastGroupOwnerAssigner - def initialize(group, members) - @group = group - @members = members - end +class LastGroupOwnerAssigner + def initialize(group, members) + @group = group + @members = members + end - def execute - @last_blocked_owner = no_owners_in_heirarchy? && group.single_blocked_owner? - @group_single_owner = owners.size == 1 + def execute + @last_blocked_owner = no_owners_in_heirarchy? && group.single_blocked_owner? + @group_single_owner = owners.size == 1 - members.each { |member| set_last_owner(member) } - end + members.each { |member| set_last_owner(member) } + end - private + private - attr_reader :group, :members, :last_blocked_owner, :group_single_owner + attr_reader :group, :members, :last_blocked_owner, :group_single_owner - def no_owners_in_heirarchy? - owners.empty? - end + def no_owners_in_heirarchy? + owners.empty? + end - def set_last_owner(member) - member.last_owner = member.id.in?(owner_ids) && group_single_owner - member.last_blocked_owner = member.id.in?(blocked_owner_ids) && last_blocked_owner - end + def set_last_owner(member) + member.last_owner = member.id.in?(owner_ids) && group_single_owner + member.last_blocked_owner = member.id.in?(blocked_owner_ids) && last_blocked_owner + end - def owner_ids - @owner_ids ||= owners.where(id: member_ids).ids - end + def owner_ids + @owner_ids ||= owners.where(id: member_ids).ids + end - def blocked_owner_ids - @blocked_owner_ids ||= group.blocked_owners.where(id: member_ids).ids - end + def blocked_owner_ids + @blocked_owner_ids ||= group.blocked_owners.where(id: member_ids).ids + end - def member_ids - @members_ids ||= members.pluck(:id) - end + def member_ids + @members_ids ||= members.pluck(:id) + end - def owners - @owners ||= group.members_with_parents.owners.load - end + def owners + @owners ||= group.members_with_parents.owners.load end end diff --git a/app/serializers/cluster_application_entity.rb b/app/serializers/cluster_application_entity.rb index 6b9a3ce114b..fab590dbe09 100644 --- a/app/serializers/cluster_application_entity.rb +++ b/app/serializers/cluster_application_entity.rb @@ -10,15 +10,12 @@ class ClusterApplicationEntity < Grape::Entity expose :hostname, if: -> (e, _) { e.respond_to?(:hostname) } expose :email, if: -> (e, _) { e.respond_to?(:email) } expose :stack, if: -> (e, _) { e.respond_to?(:stack) } - expose :modsecurity_enabled, if: -> (e, _) { e.respond_to?(:modsecurity_enabled) } expose :update_available?, as: :update_available, if: -> (e, _) { e.respond_to?(:update_available?) } expose :can_uninstall?, as: :can_uninstall expose :available_domains, using: Serverless::DomainEntity, if: -> (e, _) { e.respond_to?(:available_domains) } expose :pages_domain, using: Serverless::DomainEntity, if: -> (e, _) { e.respond_to?(:pages_domain) } - expose :modsecurity_mode, if: -> (e, _) { e.respond_to?(:modsecurity_mode) } expose :host, if: -> (e, _) { e.respond_to?(:host) } expose :port, if: -> (e, _) { e.respond_to?(:port) } expose :protocol, if: -> (e, _) { e.respond_to?(:protocol) } - expose :waf_log_enabled, if: -> (e, _) { e.respond_to?(:waf_log_enabled) } expose :cilium_log_enabled, if: -> (e, _) { e.respond_to?(:cilium_log_enabled) } end diff --git a/app/serializers/member_serializer.rb b/app/serializers/member_serializer.rb index 462f6be5d04..ad258b0ef1e 100644 --- a/app/serializers/member_serializer.rb +++ b/app/serializers/member_serializer.rb @@ -4,7 +4,7 @@ class MemberSerializer < BaseSerializer entity MemberEntity def represent(members, opts = {}) - Members::LastGroupOwnerAssigner.new(opts[:group], members).execute unless opts[:source].is_a?(Project) + LastGroupOwnerAssigner.new(opts[:group], members).execute unless opts[:source].is_a?(Project) super(members, opts) end diff --git a/app/services/clusters/applications/base_service.rb b/app/services/clusters/applications/base_service.rb index 489360f9070..47d6fbbeda2 100644 --- a/app/services/clusters/applications/base_service.rb +++ b/app/services/clusters/applications/base_service.rb @@ -29,14 +29,6 @@ module Clusters application.stack = params[:stack] end - if application.has_attribute?(:modsecurity_enabled) - application.modsecurity_enabled = params[:modsecurity_enabled] || false - end - - if application.has_attribute?(:modsecurity_mode) - application.modsecurity_mode = params[:modsecurity_mode] || 0 - end - apply_fluentd_related_attributes(application) if application.respond_to?(:oauth_application) diff --git a/app/views/admin/application_settings/_diff_limits.html.haml b/app/views/admin/application_settings/_diff_limits.html.haml index 7286fffcaf6..ff22f6181b3 100644 --- a/app/views/admin/application_settings/_diff_limits.html.haml +++ b/app/views/admin/application_settings/_diff_limits.html.haml @@ -3,13 +3,11 @@ %fieldset .form-group - = f.label :diff_max_patch_bytes, 'Maximum diff patch size (Bytes)', class: 'label-light' + = f.label :diff_max_patch_bytes, 'Maximum diff patch size in bytes', class: 'label-light' = f.number_field :diff_max_patch_bytes, class: 'form-control gl-form-input' %span.form-text.text-muted - Diff files surpassing this limit will be presented as 'too large' - and won't be expandable. + Collapse diffs larger than this size, and show a 'too large' message instead. = link_to sprite_icon('question-o'), - help_page_path('user/admin_area/diff_limits', - anchor: 'maximum-diff-patch-size') + help_page_path('user/admin_area/diff_limits') = f.submit _('Save changes'), class: 'gl-button btn btn-confirm' diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml index 3f1c363bcb9..0fbbef02613 100644 --- a/app/views/admin/application_settings/general.html.haml +++ b/app/views/admin/application_settings/general.html.haml @@ -31,7 +31,7 @@ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Diff content limits') + = _('Set size limits for displaying diffs in the browser.') .settings-content = render 'diff_limits' diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml index 267fc3ae986..0716eda79a8 100644 --- a/app/views/projects/forks/new.html.haml +++ b/app/views/projects/forks/new.html.haml @@ -10,7 +10,8 @@ project_name: @project.name, project_path: @project.path, project_description: @project.description, - project_visibility: @project.visibility } } + project_visibility: @project.visibility, + restricted_visibility_levels: Gitlab::CurrentSettings.restricted_visibility_levels.to_json } } - else .row.gl-mt-3 .col-lg-3 diff --git a/app/views/shared/issuable/form/_branch_chooser.html.haml b/app/views/shared/issuable/form/_branch_chooser.html.haml index 70e931ac164..1f391e8a321 100644 --- a/app/views/shared/issuable/form/_branch_chooser.html.haml +++ b/app/views/shared/issuable/form/_branch_chooser.html.haml @@ -37,10 +37,12 @@ data: { placeholder: _('Select branch'), endpoint: refs_project_path(@project, sort: 'updated_desc', find: 'branches') }}) - if source_level < target_level - .gl-alert.gl-alert-warning.gl-mt-4 - = sprite_icon('warning', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') - .gl-alert-body - = visibilityMismatchString - %br - = _('Review the target project before submitting to avoid exposing %{source} changes.') % { source: source_visibility } + .gl-alert.gl-alert-warning.gl-alert-not-dismissible.gl-max-content.gl-mt-4 + .gl-alert-container + .gl-alert-content{ role: 'alert' } + = sprite_icon('warning', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') + .gl-alert-body + = visibilityMismatchString + %br + = _('Review the target project before submitting to avoid exposing %{source} changes.') % { source: source_visibility } %hr diff --git a/app/workers/ssh_keys/expired_notification_worker.rb b/app/workers/ssh_keys/expired_notification_worker.rb index e8baf0c28dd..b67849942b0 100644 --- a/app/workers/ssh_keys/expired_notification_worker.rb +++ b/app/workers/ssh_keys/expired_notification_worker.rb @@ -15,8 +15,6 @@ module SshKeys # rubocop: disable CodeReuse/ActiveRecord def perform - return unless ::Feature.enabled?(:ssh_key_expiration_email_notification, default_enabled: :yaml) - order = Gitlab::Pagination::Keyset::Order.build([ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new( attribute_name: 'expires_at_utc', diff --git a/app/workers/ssh_keys/expiring_soon_notification_worker.rb b/app/workers/ssh_keys/expiring_soon_notification_worker.rb index 1ec655b5cf5..d87e31c36a5 100644 --- a/app/workers/ssh_keys/expiring_soon_notification_worker.rb +++ b/app/workers/ssh_keys/expiring_soon_notification_worker.rb @@ -12,8 +12,6 @@ module SshKeys idempotent! def perform - return unless ::Feature.enabled?(:ssh_key_expiration_email_notification, default_enabled: :yaml) - # rubocop:disable CodeReuse/ActiveRecord User.with_ssh_key_expiring_soon.find_each(batch_size: 10_000) do |user| with_context(user: user) do |