Commit 224830d8 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 0f6cbe50 ec87f32f
No related merge requests found
......@@ -15,7 +15,7 @@ module Security
attr_reader :pipeline
def self.allowed_job_types
# Example return: [:sast, :dast, :dependency_scanning, :container_scanning, :license_management, :coverage_fuzzing]
# Example return: [:sast, :dast, :dependency_scanning, :container_scanning, :license_scanning, :coverage_fuzzing]
raise NotImplementedError, 'allowed_job_types must be overwritten to return an array of job types'
end
......
......@@ -40,7 +40,9 @@ module AuthorizedProjectUpdate
private
def use_primary_database
# no-op in CE, overriden in EE
if ::Gitlab::Database::LoadBalancing.enable?
::Gitlab::Database::LoadBalancing::Session.current.use_primary!
end
end
def project_authorizations_needs_refresh?(user)
......@@ -54,5 +56,3 @@ module AuthorizedProjectUpdate
end
end
end
AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker.prepend_mod_with('AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker')
# frozen_string_literal: true
class RemoveSegmentSelectionsTable < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
def up
drop_table :analytics_devops_adoption_segment_selections
end
def down
create_table :analytics_devops_adoption_segment_selections do |t|
t.references :segment, index: { name: 'index_on_segment_selections_segment_id' }, null: false, foreign_key: { to_table: :analytics_devops_adoption_segments, on_delete: :cascade }
t.bigint :group_id
t.bigint :project_id
t.index [:group_id, :segment_id], unique: true, name: 'index_on_segment_selections_group_id_segment_id'
t.index [:project_id, :segment_id], unique: true, name: 'index_on_segment_selections_project_id_segment_id'
t.timestamps_with_timezone
end
add_concurrent_foreign_key(:analytics_devops_adoption_segment_selections, :projects, column: :project_id, on_delete: :cascade)
add_concurrent_foreign_key(:analytics_devops_adoption_segment_selections, :namespaces, column: :group_id, on_delete: :cascade)
add_check_constraint :analytics_devops_adoption_segment_selections, '(project_id != NULL AND group_id IS NULL) OR (group_id != NULL AND project_id IS NULL)', 'segment_selection_project_id_or_group_id_required'
end
end
ee76ee2e2515c06b09fca23a77bdfb9532fa5d80fc3d5aba44a80d123b74cfa9
\ No newline at end of file
......@@ -9110,25 +9110,6 @@ CREATE SEQUENCE analytics_cycle_analytics_project_value_streams_id_seq
ALTER SEQUENCE analytics_cycle_analytics_project_value_streams_id_seq OWNED BY analytics_cycle_analytics_project_value_streams.id;
CREATE TABLE analytics_devops_adoption_segment_selections (
id bigint NOT NULL,
segment_id bigint NOT NULL,
group_id bigint,
project_id bigint,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
CONSTRAINT segment_selection_project_id_or_group_id_required CHECK ((((project_id <> NULL::bigint) AND (group_id IS NULL)) OR ((group_id <> NULL::bigint) AND (project_id IS NULL))))
);
CREATE SEQUENCE analytics_devops_adoption_segment_selections_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE analytics_devops_adoption_segment_selections_id_seq OWNED BY analytics_devops_adoption_segment_selections.id;
CREATE TABLE analytics_devops_adoption_segments (
id bigint NOT NULL,
last_recorded_at timestamp with time zone,
......@@ -19520,8 +19501,6 @@ ALTER TABLE ONLY analytics_cycle_analytics_project_stages ALTER COLUMN id SET DE
ALTER TABLE ONLY analytics_cycle_analytics_project_value_streams ALTER COLUMN id SET DEFAULT nextval('analytics_cycle_analytics_project_value_streams_id_seq'::regclass);
ALTER TABLE ONLY analytics_devops_adoption_segment_selections ALTER COLUMN id SET DEFAULT nextval('analytics_devops_adoption_segment_selections_id_seq'::regclass);
ALTER TABLE ONLY analytics_devops_adoption_segments ALTER COLUMN id SET DEFAULT nextval('analytics_devops_adoption_segments_id_seq'::regclass);
ALTER TABLE ONLY analytics_devops_adoption_snapshots ALTER COLUMN id SET DEFAULT nextval('analytics_devops_adoption_snapshots_id_seq'::regclass);
......@@ -20611,9 +20590,6 @@ ALTER TABLE ONLY analytics_cycle_analytics_project_stages
ALTER TABLE ONLY analytics_cycle_analytics_project_value_streams
ADD CONSTRAINT analytics_cycle_analytics_project_value_streams_pkey PRIMARY KEY (id);
ALTER TABLE ONLY analytics_devops_adoption_segment_selections
ADD CONSTRAINT analytics_devops_adoption_segment_selections_pkey PRIMARY KEY (id);
ALTER TABLE ONLY analytics_devops_adoption_segments
ADD CONSTRAINT analytics_devops_adoption_segments_pkey PRIMARY KEY (id);
......@@ -23899,12 +23875,6 @@ CREATE INDEX index_on_projects_lower_path ON projects USING btree (lower((path):
CREATE INDEX index_on_routes_lower_path ON routes USING btree (lower((path)::text));
CREATE UNIQUE INDEX index_on_segment_selections_group_id_segment_id ON analytics_devops_adoption_segment_selections USING btree (group_id, segment_id);
CREATE UNIQUE INDEX index_on_segment_selections_project_id_segment_id ON analytics_devops_adoption_segment_selections USING btree (project_id, segment_id);
CREATE INDEX index_on_segment_selections_segment_id ON analytics_devops_adoption_segment_selections USING btree (segment_id);
CREATE INDEX index_on_snapshots_segment_id_end_time ON analytics_devops_adoption_snapshots USING btree (segment_id, end_time);
CREATE INDEX index_on_snapshots_segment_id_recorded_at ON analytics_devops_adoption_snapshots USING btree (segment_id, recorded_at);
......@@ -25957,9 +25927,6 @@ ALTER TABLE ONLY project_group_links
ALTER TABLE ONLY epics
ADD CONSTRAINT fk_dccd3f98fc FOREIGN KEY (assignee_id) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE ONLY analytics_devops_adoption_segment_selections
ADD CONSTRAINT fk_ded7fe0344 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY issues
ADD CONSTRAINT fk_df75a7c8b8 FOREIGN KEY (promoted_to_epic_id) REFERENCES epics(id) ON DELETE SET NULL;
......@@ -26029,9 +25996,6 @@ ALTER TABLE ONLY vulnerability_external_issue_links
ALTER TABLE ONLY epics
ADD CONSTRAINT fk_f081aa4489 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY analytics_devops_adoption_segment_selections
ADD CONSTRAINT fk_f1472b95f3 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY boards
ADD CONSTRAINT fk_f15266b5f9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
......@@ -26122,9 +26086,6 @@ ALTER TABLE ONLY ip_restrictions
ALTER TABLE ONLY terraform_state_versions
ADD CONSTRAINT fk_rails_04f176e239 FOREIGN KEY (terraform_state_id) REFERENCES terraform_states(id) ON DELETE CASCADE;
ALTER TABLE ONLY analytics_devops_adoption_segment_selections
ADD CONSTRAINT fk_rails_053f00a9da FOREIGN KEY (segment_id) REFERENCES analytics_devops_adoption_segments(id) ON DELETE CASCADE;
ALTER TABLE ONLY ci_build_report_results
ADD CONSTRAINT fk_rails_056d298d48 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
......@@ -131,6 +131,9 @@ list.
```shell
sudo gitlab-ctl reconfigure
# Needed when enabling or disabling for the first time but not for password changes.
# See https://gitlab.com/gitlab-org/gitlab-foss/-/issues/23560#note_61966788
sudo gitlab-ctl restart
```
......
......@@ -21,7 +21,7 @@ The following are the requirements for providing your own Redis instance:
[requirements page](../../install/requirements.md).
- Standalone Redis or Redis high availability with Sentinel are supported. Redis
Cluster is not supported.
- Managed Redis from cloud providers such as AWS ElastiCache will work. If these
- Managed Redis from cloud providers such as AWS ElastiCache works fine. If these
services support high availability, be sure it is **not** the Redis Cluster type.
Note the Redis node's IP address or hostname, port, and password (if required).
......@@ -53,7 +53,7 @@ Note the Redis node's IP address or hostname, port, and password (if required).
This is the documentation for configuring a scalable Redis setup when
you have installed Redis all by yourself and not using the bundled one that
comes with the Omnibus packages, although using the Omnibus GitLab packages is
highly recommend as we optimize them specifically for GitLab, and we will take
highly recommend as we optimize them specifically for GitLab, and we take
care of upgrading Redis to the latest supported version.
Note also that you may elect to override all references to
......@@ -76,7 +76,7 @@ requirements:
(e.g., one from an internal network).
- Since Redis 3.2, you must define a password to receive external connections
(`requirepass`).
- If you are using Redis with Sentinel, you will also need to define the same
- If you are using Redis with Sentinel, you also need to define the same
password for the replica password definition (`masterauth`) in the same instance.
In addition, read the prerequisites as described in the
......@@ -176,7 +176,7 @@ primary with IP `10.0.0.1` (some settings might overlap with the primary):
sentinel monitor gitlab-redis 10.0.0.1 6379 2
## Define with `sentinel down-after-milliseconds` the time in `ms`
## that an unresponsive server will be considered down.
## that an unresponsive server is considered down.
sentinel down-after-milliseconds gitlab-redis 10000
## Define a value for `sentinel failover_timeout` in `ms`. This has multiple
......@@ -197,7 +197,7 @@ primary with IP `10.0.0.1` (some settings might overlap with the primary):
##
## * The maximum time a failover in progress waits for all the replicas to be
## reconfigured as replicas of the new primary. However even after this time
## the replicas will be reconfigured by the Sentinels anyway, but not with
## the replicas are reconfigured by the Sentinels anyway, but not with
## the exact parallel-syncs progression as specified.
sentinel failover_timeout 30000
```
......@@ -249,7 +249,7 @@ In a real world usage, you would also set up firewall rules to prevent
unauthorized access from other machines, and block traffic from the
outside ([Internet](https://gitlab.com/gitlab-org/gitlab-foss/uploads/c4cc8cd353604bd80315f9384035ff9e/The_Internet_IT_Crowd.png)).
For this example, **Sentinel 1** will be configured in the same machine as the
For this example, **Sentinel 1** is configured in the same machine as the
**Redis Primary**, **Sentinel 2** and **Sentinel 3** in the same machines as the
**Replica 1** and **Replica 2** respectively.
......@@ -261,11 +261,11 @@ Here is a list and description of each **machine** and the assigned **IP**:
- `10.0.0.4`: GitLab application
Please note that after the initial configuration, if a failover is initiated
by the Sentinel nodes, the Redis nodes will be reconfigured and the **Primary**
will change permanently (including in `redis.conf`) from one node to the other,
by the Sentinel nodes, the Redis nodes are reconfigured and the **Primary**
changes permanently (including in `redis.conf`) from one node to the other,
until a new failover is initiated again.
The same thing will happen with `sentinel.conf` that will be overridden after the
The same thing happens with `sentinel.conf` that is overridden after the
initial execution, after any new sentinel node starts watching the **Primary**,
or a failover promotes a different **Primary** node.
......
......@@ -6,6 +6,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Create an A/B test with `Experimentation Module`
NOTE:
We recommend using [GLEX](gitlab_experiment.md) for new experiments.
## Implement the experiment
1. Add the experiment to the `Gitlab::Experimentation::EXPERIMENTS` hash in
......
......@@ -46,16 +46,10 @@ One is built into GitLab directly and has been around for a while (this is calle
to as `Gitlab::Experiment` -- GLEX for short.
Both approaches use [experiment](../feature_flags/index.md#experiment-type)
feature flags, and there is currently no strong suggestion to use one over the other.
feature flags. We recommend using GLEX rather than `Experimentation Module` for new experiments.
| Feature | `Experimentation Module` | GLEX |
| -------------------- |------------------------- | ---- |
| Record user grouping | Yes | No |
| Uses feature flags | Yes | Yes |
| Multivariate (A/B/n) | No | Yes |
- [Implementing an A/B experiment using `Experimentation Module`](experimentation.md)
- [Implementing an A/B/n experiment using GLEX](gitlab_experiment.md)
- [Implementing an A/B experiment using `Experimentation Module`](experimentation.md)
Historical Context: `Experimentation Module` was built iteratively with the needs that
appeared while implementing Growth sub-department experiments, while GLEX was built
......
......@@ -2,11 +2,12 @@
module Types
module Vulnerability
# rubocop: disable Graphql/AuthorizeTypes
class IssueLinkType < BaseObject
graphql_name 'VulnerabilityIssueLink'
description 'Represents an issue link of a vulnerability'
authorize :read_issue_link
field :id, GraphQL::ID_TYPE, null: false,
description: 'GraphQL ID of the vulnerability.'
......@@ -16,6 +17,5 @@ module Types
field :issue, ::Types::IssueType, null: false,
description: 'The issue attached to issue link.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
end
......@@ -3,5 +3,9 @@
module Vulnerabilities
class IssueLinkPolicy < BasePolicy
delegate { @subject.vulnerability&.project }
condition(:issue_readable?) { Ability.allowed?(@user, :read_issue, @subject.issue) }
rule { ~issue_readable? }.prevent :read_issue_link
end
end
......@@ -9,7 +9,7 @@ module Security
end
def execute
sync_license_management_rules
sync_license_scanning_rules
sync_vulnerability_rules
success
rescue StandardError => error
......@@ -27,7 +27,7 @@ module Security
attr_reader :pipeline
def sync_license_management_rules
def sync_license_scanning_rules
project = pipeline.project
report = pipeline.license_scanning_report
return if report.empty? && !pipeline.complete?
......
# frozen_string_literal: true
module EE
module AuthorizedProjectUpdate
module UserRefreshOverUserRangeWorker # rubocop:disable Scalability/IdempotentWorker
extend ::Gitlab::Utils::Override
private
override :use_primary_database
def use_primary_database
if ::Gitlab::Database::LoadBalancing.enable?
::Gitlab::Database::LoadBalancing::Session.current.use_primary!
end
end
end
end
end
......@@ -52,7 +52,6 @@ RSpec.describe GitlabSchema.types['Project'] do
create(:ci_build, :success, :sast, pipeline: pipeline)
create(:ci_build, :success, :dast, pipeline: pipeline)
create(:ci_build, :success, :license_scanning, pipeline: pipeline)
create(:ci_build, :success, :license_management, pipeline: pipeline)
create(:ci_build, :pending, :secret_detection, pipeline: pipeline)
end
......
......@@ -8,4 +8,5 @@ RSpec.describe GitlabSchema.types['VulnerabilityIssueLink'] do
subject { described_class }
it { is_expected.to have_graphql_fields(expected_fields) }
it { is_expected.to require_graphql_authorizations(:read_issue_link) }
end
......@@ -3,16 +3,16 @@
require 'spec_helper'
RSpec.describe Vulnerabilities::IssueLinkPolicy do
let(:vulnerability_issue_link) { build(:vulnerabilities_issue_link, vulnerability: vulnerability, issue: issue) }
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, namespace: user.namespace) }
let(:vulnerability) { create(:vulnerability, project: project) }
let(:issue) { create(:issue, project: project) }
let(:vulnerability_issue_link) { build(:vulnerabilities_issue_link, vulnerability: vulnerability, issue: issue) }
let_it_be(:vulnerability) { create(:vulnerability, project: project) }
let_it_be(:issue) { create(:issue, project: project) }
subject { described_class.new(user, vulnerability_issue_link) }
context 'with a user authorized to admin vulnerability-issue links' do
describe ':admin_vulnerability_issue_link' do
before do
stub_licensed_features(security_dashboard: true)
......@@ -20,8 +20,8 @@ RSpec.describe Vulnerabilities::IssueLinkPolicy do
end
context 'with missing vulnerability' do
let(:vulnerability) { nil }
let(:issue) { create(:issue) }
let_it_be(:vulnerability) { nil }
let_it_be(:issue) { create(:issue) }
it { is_expected.to be_disallowed(:admin_vulnerability_issue_link) }
end
......@@ -31,9 +31,27 @@ RSpec.describe Vulnerabilities::IssueLinkPolicy do
end
context "when issue and link don't belong to the same project" do
let(:issue) { create(:issue) }
let_it_be(:issue) { create(:issue) }
it { is_expected.to be_allowed(:admin_vulnerability_issue_link) }
end
end
describe ':read_issue_link' do
before do
allow(Ability).to receive(:allowed?).with(user, :read_issue, issue).and_return(allowed?)
end
context 'when the associated issue can not be read by the user' do
let(:allowed?) { false }
it { is_expected.to be_disallowed(:read_issue_link) }
end
context 'when the associated issue can be read by the user' do
let(:allowed?) { true }
it { is_expected.to be_allowed(:read_issue_link) }
end
end
end
......@@ -8,11 +8,14 @@ RSpec.describe 'Query.vulnerabilities.issueLinks' do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user, security_dashboard_projects: [project]) }
let_it_be(:vulnerability) { create(:vulnerability, project: project) }
let_it_be(:related_issue) { create(:vulnerabilities_issue_link, :related, vulnerability: vulnerability) }
let_it_be(:created_issue) { create(:vulnerabilities_issue_link, :created, vulnerability: vulnerability) }
let_it_be(:created_issue) { create(:issue, project: project) }
let_it_be(:related_issue) { create(:issue, project: project) }
let_it_be(:related_issue_link) { create(:vulnerabilities_issue_link, :related, vulnerability: vulnerability, issue: related_issue) }
let_it_be(:created_issue_link) { create(:vulnerabilities_issue_link, :created, vulnerability: vulnerability, issue: created_issue) }
before do
project.add_developer(user)
stub_licensed_features(security_dashboard: true)
end
......@@ -46,13 +49,13 @@ RSpec.describe 'Query.vulnerabilities.issueLinks' do
it 'returns a list of VulnerabilityIssueLink with `CREATED` linkType' do
query_issue_links('CREATED')
expect_issue_links_response(created_issue)
expect_issue_links_response(created_issue_link)
end
it 'returns a list of VulnerabilityIssueLink with `RELATED` linkType' do
query_issue_links('RELATED')
expect_issue_links_response(related_issue)
expect_issue_links_response(related_issue_link)
end
end
......@@ -60,7 +63,7 @@ RSpec.describe 'Query.vulnerabilities.issueLinks' do
it 'returns a list of all VulnerabilityIssueLink' do
query_issue_links
expect_issue_links_response(related_issue, created_issue)
expect_issue_links_response(related_issue_link, created_issue_link)
end
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker do
let_it_be(:project) { create(:project) }
let(:user) { project.namespace.owner }
let(:start_user_id) { user.id }
let(:end_user_id) { start_user_id }
let(:execute_worker) { subject.perform(start_user_id, end_user_id) }
describe '#perform' do
context 'when the feature flag `periodic_project_authorization_update_via_replica` is disabled' do
before do
stub_feature_flags(periodic_project_authorization_update_via_replica: false)
end
context 'when load balancing is enabled' do
before do
allow(Gitlab::Database::LoadBalancing).to receive(:enable?).and_return(true)
end
it 'reads from the primary database' do
expect(Gitlab::Database::LoadBalancing::Session.current)
.to receive(:use_primary!)
execute_worker
end
end
end
end
end
......@@ -77,7 +77,7 @@ module Gitlab
end
def set_section_duration(duration)
@section_duration = Time.at(duration.to_i).strftime('%M:%S')
@section_duration = Time.at(duration.to_i).utc.strftime('%M:%S')
end
def flush_current_segment!
......
......@@ -28,19 +28,19 @@ RSpec.describe Security::SecurityJobsFinder do
end
end
context 'with combination of security jobs and license management jobs' do
context 'with combination of security jobs and license scanning jobs' do
let!(:sast_build) { create(:ci_build, :sast, pipeline: pipeline) }
let!(:container_scanning_build) { create(:ci_build, :container_scanning, pipeline: pipeline) }
let!(:dast_build) { create(:ci_build, :dast, pipeline: pipeline) }
let!(:secret_detection_build) { create(:ci_build, :secret_detection, pipeline: pipeline) }
let!(:license_management_build) { create(:ci_build, :license_management, pipeline: pipeline) }
let!(:license_scanning_build) { create(:ci_build, :license_scanning, pipeline: pipeline) }
it 'returns only the security jobs' do
is_expected.to include(sast_build)
is_expected.to include(container_scanning_build)
is_expected.to include(dast_build)
is_expected.to include(secret_detection_build)
is_expected.not_to include(license_management_build)
is_expected.not_to include(license_scanning_build)
end
end
end
......
......@@ -66,14 +66,16 @@ RSpec.describe Mutations::Ci::Runner::Update do
context 'with valid arguments' do
it 'updates runner with correct values' do
expected_attributes = mutation_params.except(:id)
expected_attributes = mutation_params.except(:id, :tag_list)
subject
expect(subject[:errors]).to be_empty
expect(subject[:runner]).to be_an_instance_of(Ci::Runner)
expect(subject[:runner]).to have_attributes(expected_attributes)
expect(subject[:runner].tag_list).to contain_exactly(*mutation_params[:tag_list])
expect(runner.reload).to have_attributes(expected_attributes)
expect(runner.tag_list).to contain_exactly(*mutation_params[:tag_list])
end
end
......
......@@ -76,10 +76,30 @@ RSpec.describe Gitlab::Ci::Ansi2json::Line do
end
describe '#set_section_duration' do
it 'sets and formats the section_duration' do
subject.set_section_duration(75)
shared_examples 'set_section_duration' do
it 'sets and formats the section_duration' do
subject.set_section_duration(75)
expect(subject.section_duration).to eq('01:15')
expect(subject.section_duration).to eq('01:15')
end
end
context 'with default timezone' do
it_behaves_like 'set_section_duration'
end
context 'with a timezone carrying minutes offset' do
before do
# The actual call by does use Time.at(...).utc that the following
# rubocop rule (Rails/TimeZone) suggests, but for this specific
# test's purposes we needed to mock at the Time.at call point.
# rubocop:disable Rails/TimeZone
allow(Time).to receive(:at).with(75).and_return(Time.at(75, in: '+05:30'))
# rubocop:enable Rails/TimeZone
end
it_behaves_like 'set_section_duration'
end
end
......
......@@ -3,7 +3,8 @@
require 'spec_helper'
RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker do
let(:project) { create(:project) }
let_it_be(:project) { create(:project) }
let(:user) { project.namespace.owner }
let(:start_user_id) { user.id }
let(:end_user_id) { start_user_id }
......@@ -64,6 +65,18 @@ RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker do
execute_worker
end
context 'when load balancing is enabled' do
before do
allow(Gitlab::Database::LoadBalancing).to receive(:enable?).and_return(true)
end
it 'reads from the primary database' do
expect(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_primary!)
execute_worker
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment