From 10494b02ab177e4b09b9b72f69d6c11936ff8c27 Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Wed, 17 Apr 2019 16:02:42 +0000 Subject: [PATCH 01/12] Merge branch 'masked-variables-docs-update-docs-only' into 'master' Add Masked Variables to Variables documentation See merge request gitlab-org/gitlab-ce!27236 (cherry picked from commit d7af5ab7d49a6190d4741aac4764bdc3c6973599) 05e36790 Add Masked Variables to Variables docs --- doc/ci/variables/README.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index 592fdfd2873..2832bf80ccf 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -137,12 +137,21 @@ The output will be: ![Output custom variable](img/custom_variable_output.png) -CAUTION: **Important:** -Be aware that variables are not masked, and their values can be shown -in the job logs if explicitly asked to do so. If your project is public or -internal, you can set the pipelines private from your [project's Pipelines -settings](../../user/project/pipelines/settings.md#visibility-of-pipelines). -Follow the discussion in issue [#13784][ce-13784] for masking the variables. +### Masked Variables + +By default, variables will be created as masked variables. +This means that the value of the variable will be hidden in job logs, +though it must match certain requirements to do so: + +- The value must be a single line. +- The value must not have escape characters. +- The value must not use variables. +- The value must not have any whitespace. +- The value must be at least 8 characters long. + +If the value does not meet the requirements above, then the CI variable will fail to save. +In order to save, either alter the value to meet the masking requirements +or disable `Masked` for the variable. ### Syntax of environment variables in job scripts {: #syntax-of-variables-in-job-scripts} -- GitLab From 4fdae01a1bfecddc10490b55330fb5975ed60c9c Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 19 Apr 2019 10:03:54 +0000 Subject: [PATCH 02/12] Merge branch 'bvl-graphql-only-authorize-rendered-fields' into 'master' Only check abilities on rendered GraphQL nodes Closes #58647 and #60355 See merge request gitlab-org/gitlab-ce!27273 (cherry picked from commit 4d2bce770bdf1b12378d3c06f895cc73d46d6f9f) eca8e6f0 Only check abilities on rendered GraphQL nodes --- lib/gitlab/graphql/authorize.rb | 2 +- .../authorize/authorize_field_service.rb | 86 +++++++----- .../graphql/connections/keyset_connection.rb | 16 ++- lib/gitlab/graphql/errors.rb | 1 - spec/graphql/features/authorization_spec.rb | 77 +++++++++-- spec/graphql/gitlab_schema_spec.rb | 2 +- .../authorize/authorize_field_service_spec.rb | 130 ++++++++++-------- .../connections/keyset_connection_spec.rb | 5 + .../api/graphql/project/issues_spec.rb | 28 +++- 9 files changed, 226 insertions(+), 121 deletions(-) diff --git a/lib/gitlab/graphql/authorize.rb b/lib/gitlab/graphql/authorize.rb index f62813db82c..f8d0208e275 100644 --- a/lib/gitlab/graphql/authorize.rb +++ b/lib/gitlab/graphql/authorize.rb @@ -8,7 +8,7 @@ module Gitlab extend ActiveSupport::Concern def self.use(schema_definition) - schema_definition.instrument(:field, Instrumentation.new) + schema_definition.instrument(:field, Instrumentation.new, after_built_ins: true) end end end diff --git a/lib/gitlab/graphql/authorize/authorize_field_service.rb b/lib/gitlab/graphql/authorize/authorize_field_service.rb index 8deff79fc84..03d6aabb0e3 100644 --- a/lib/gitlab/graphql/authorize/authorize_field_service.rb +++ b/lib/gitlab/graphql/authorize/authorize_field_service.rb @@ -15,15 +15,10 @@ module Gitlab def authorized_resolve proc do |parent_typed_object, args, ctx| - resolved_obj = @old_resolve_proc.call(parent_typed_object, args, ctx) - authorizing_obj = authorize_against(parent_typed_object) - checker = build_checker(ctx[:current_user], authorizing_obj) - - if resolved_obj.respond_to?(:then) - resolved_obj.then(&checker) - else - checker.call(resolved_obj) - end + resolved_type = @old_resolve_proc.call(parent_typed_object, args, ctx) + authorizing_object = authorize_against(parent_typed_object, resolved_type) + + filter_allowed(ctx[:current_user], resolved_type, authorizing_object) end end @@ -38,7 +33,7 @@ module Gitlab type = @field.type # When the return type of @field is a collection, find the singular type - if type.get_field('edges') + if @field.connection? type = node_type_for_relay_connection(type) elsif type.list? type = node_type_for_basic_connection(type) @@ -52,43 +47,60 @@ module Gitlab Array.wrap(@field.metadata[:authorize]) end - # If it's a built-in/scalar type, authorize using its parent object. - # nil means authorize using the resolved object - def authorize_against(parent_typed_object) - parent_typed_object.object if built_in_type? && parent_typed_object.respond_to?(:object) + def authorize_against(parent_typed_object, resolved_type) + if built_in_type? + # The field is a built-in/scalar type, or a list of scalars + # authorize using the parent's object + parent_typed_object.object + elsif resolved_type.respond_to?(:object) + # The field is a type representing a single object, we'll authorize + # against the object directly + resolved_type.object + elsif @field.connection? || resolved_type.is_a?(Array) + # The field is a connection or a list of non-built-in types, we'll + # authorize each element when rendering + nil + else + # Resolved type is a single object that might not be loaded yet by + # the batchloader, we'll authorize that + resolved_type + end end - def build_checker(current_user, authorizing_obj) - lambda do |resolved_obj| - # Load the elements if they were not loaded by BatchLoader yet - resolved_obj = resolved_obj.sync if resolved_obj.respond_to?(:sync) - - check = lambda do |object| - authorizations.all? do |ability| - Ability.allowed?(current_user, ability, authorizing_obj || object) - end + def filter_allowed(current_user, resolved_type, authorizing_object) + if authorizing_object + # Authorizing fields representing scalars, or a simple field with an object + resolved_type if allowed_access?(current_user, authorizing_object) + elsif @field.connection? + # A connection with pagination, modify the visible nodes in on the + # connection type in place + resolved_type.edge_nodes.to_a.keep_if { |node| allowed_access?(current_user, node) } + resolved_type + elsif resolved_type.is_a? Array + # A simple list of rendered types each object being an object to authorize + resolved_type.select do |single_object_type| + allowed_access?(current_user, single_object_type.object) end + elsif resolved_type.nil? + # We're not rendering anything, for example when a record was not found + # no need to do anything + else + raise "Can't authorize #{@field}" + end + end - case resolved_obj - when Array, ActiveRecord::Relation - resolved_obj.select(&check) - else - resolved_obj if check.call(resolved_obj) - end + def allowed_access?(current_user, object) + object = object.sync if object.respond_to?(:sync) + + authorizations.all? do |ability| + Ability.allowed?(current_user, ability, object) end end # Returns the singular type for relay connections. # This will be the type class of edges.node def node_type_for_relay_connection(type) - type = type.get_field('edges').type.unwrap.get_field('node')&.type - - if type.nil? - raise Gitlab::Graphql::Errors::ConnectionDefinitionError, - 'Connection Type must conform to the Relay Cursor Connections Specification' - end - - type + type.unwrap.get_field('edges').type.unwrap.get_field('node').type end # Returns the singular type for basic connections, for example `[Types::ProjectType]` diff --git a/lib/gitlab/graphql/connections/keyset_connection.rb b/lib/gitlab/graphql/connections/keyset_connection.rb index 851054c0393..715963a44c1 100644 --- a/lib/gitlab/graphql/connections/keyset_connection.rb +++ b/lib/gitlab/graphql/connections/keyset_connection.rb @@ -22,8 +22,17 @@ module Gitlab end # rubocop: enable CodeReuse/ActiveRecord - # rubocop: disable CodeReuse/ActiveRecord def paged_nodes + # These are the nodes that will be loaded into memory for rendering + # So we're ok loading them into memory here as that's bound to happen + # anyway. Having them ready means we can modify the result while + # rendering the fields. + @paged_nodes ||= load_paged_nodes.to_a + end + + private + + def load_paged_nodes if first && last raise Gitlab::Graphql::Errors::ArgumentError.new("Can only provide either `first` or `last`, not both") end @@ -31,12 +40,9 @@ module Gitlab if last sliced_nodes.last(limit_value) else - sliced_nodes.limit(limit_value) + sliced_nodes.limit(limit_value) # rubocop: disable CodeReuse/ActiveRecord end end - # rubocop: enable CodeReuse/ActiveRecord - - private def before_slice if sort_direction == :asc diff --git a/lib/gitlab/graphql/errors.rb b/lib/gitlab/graphql/errors.rb index bcbba72e017..fe74549e322 100644 --- a/lib/gitlab/graphql/errors.rb +++ b/lib/gitlab/graphql/errors.rb @@ -6,7 +6,6 @@ module Gitlab BaseError = Class.new(GraphQL::ExecutionError) ArgumentError = Class.new(BaseError) ResourceNotAvailable = Class.new(BaseError) - ConnectionDefinitionError = Class.new(BaseError) end end end diff --git a/spec/graphql/features/authorization_spec.rb b/spec/graphql/features/authorization_spec.rb index 00e31568a9e..f5eb628a982 100644 --- a/spec/graphql/features/authorization_spec.rb +++ b/spec/graphql/features/authorization_spec.rb @@ -177,6 +177,7 @@ describe 'Gitlab::Graphql::Authorization' do describe 'type authorizations when applied to a relay connection' do let(:query_string) { '{ object() { edges { node { name } } } }' } + let(:second_test_object) { double(name: 'Second thing') } let(:type) do type_factory do |type| @@ -186,22 +187,41 @@ describe 'Gitlab::Graphql::Authorization' do let(:query_type) do query_factory do |query| - query.field :object, type.connection_type, null: true, resolve: ->(obj, args, ctx) { [test_object] } + query.field :object, type.connection_type, null: true, resolve: ->(obj, args, ctx) { [test_object, second_test_object] } end end subject { result.dig('object', 'edges') } - it 'returns the protected field when user has permission' do + it 'returns only the elements visible to the user' do permit(permission_single) - expect(subject).not_to be_empty + expect(subject.size).to eq 1 expect(subject.first['node']).to eq('name' => test_object.name) end it 'returns nil when user is not authorized' do expect(subject).to be_empty end + + describe 'limiting connections with multiple objects' do + let(:query_type) do + query_factory do |query| + query.field :object, type.connection_type, null: true, resolve: ->(obj, args, ctx) do + [test_object, second_test_object] + end + end + end + + let(:query_string) { '{ object(first: 1) { edges { node { name } } } }' } + + it 'only checks permissions for the first object' do + expect(Ability).to receive(:allowed?).with(user, permission_single, test_object) { true } + expect(Ability).not_to receive(:allowed?).with(user, permission_single, second_test_object) + + expect(subject.size).to eq(1) + end + end end describe 'type authorizations when applied to a basic connection' do @@ -222,28 +242,53 @@ describe 'Gitlab::Graphql::Authorization' do include_examples 'authorization with a single permission' end - describe 'when connections do not follow the correct specification' do - let(:query_string) { '{ object() { edges { node { name }} } }' } + describe 'Authorizations on active record relations' do + let!(:visible_project) { create(:project, :private) } + let!(:other_project) { create(:project, :private) } + let!(:visible_issues) { create_list(:issue, 2, project: visible_project) } + let!(:other_issues) { create_list(:issue, 2, project: other_project) } + let!(:user) { visible_project.owner } - let(:type) do - bad_node = type_factory do |type| - type.graphql_name 'BadNode' - type.field :bad_node, GraphQL::STRING_TYPE, null: true + let(:issue_type) do + type_factory do |type| + type.graphql_name 'FakeIssueType' + type.authorize :read_issue + type.field :id, GraphQL::ID_TYPE, null: false end - + end + let(:project_type) do |type| type_factory do |type| - type.field :edges, [bad_node], null: true + type.graphql_name 'FakeProjectType' + type.field :test_issues, issue_type.connection_type, null: false, resolve: -> (_, _, _) { Issue.where(project: [visible_project, other_project]) } end end - let(:query_type) do query_factory do |query| - query.field :object, type, null: true + query.field :test_project, project_type, null: false, resolve: -> (_, _, _) { visible_project } end end + let(:query_string) do + <<~QRY + { testProject { testIssues(first: 3) { edges { node { id } } } } } + QRY + end + + before do + allow(Ability).to receive(:allowed?).and_call_original + end + + it 'renders the issues the user has access to' do + issue_edges = result['testProject']['testIssues']['edges'] + issue_ids = issue_edges.map { |issue_edge| issue_edge['node']&.fetch('id') } + + expect(issue_edges.size).to eq(visible_issues.size) + expect(issue_ids).to eq(visible_issues.map { |i| i.id.to_s }) + end + + it 'does not check access on fields that will not be rendered' do + expect(Ability).not_to receive(:allowed?).with(user, :read_issue, other_issues.last) - it 'throws an error' do - expect { result }.to raise_error(Gitlab::Graphql::Errors::ConnectionDefinitionError) + result end end @@ -276,6 +321,8 @@ describe 'Gitlab::Graphql::Authorization' do def execute_query(query_type) schema = Class.new(GraphQL::Schema) do use Gitlab::Graphql::Authorize + use Gitlab::Graphql::Connections + query(query_type) end diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb index 74e93b2c4df..05f10fb40f0 100644 --- a/spec/graphql/gitlab_schema_spec.rb +++ b/spec/graphql/gitlab_schema_spec.rb @@ -74,6 +74,6 @@ describe GitlabSchema do end def field_instrumenters - described_class.instrumenters[:field] + described_class.instrumenters[:field] + described_class.instrumenters[:field_after_built_ins] end end diff --git a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb index 6114aca0616..95a4eb296fb 100644 --- a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb +++ b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb @@ -5,92 +5,104 @@ require 'spec_helper' # Also see spec/graphql/features/authorization_spec.rb for # integration tests of AuthorizeFieldService describe Gitlab::Graphql::Authorize::AuthorizeFieldService do - describe '#build_checker' do - let(:current_user) { double(:current_user) } - let(:abilities) { [double(:first_ability), double(:last_ability)] } - - context 'when authorizing against the object' do - let(:checker) do - service = described_class.new(double(resolve_proc: proc {})) - allow(service).to receive(:authorizations).and_return(abilities) - service.__send__(:build_checker, current_user, nil) - end + def type(type_authorizations = []) + Class.new(Types::BaseObject) do + graphql_name "TestType" - it 'returns a checker which checks for a single object' do - object = double(:object) + authorize type_authorizations + end + end - abilities.each do |ability| - spy_ability_check_for(ability, object, passed: true) - end + def type_with_field(field_type, field_authorizations = [], resolved_value = "Resolved value") + Class.new(Types::BaseObject) do + graphql_name "TestTypeWithField" + field :test_field, field_type, null: true, authorize: field_authorizations, resolve: -> (_, _, _) { resolved_value} + end + end - expect(checker.call(object)).to eq(object) - end + let(:current_user) { double(:current_user) } + subject(:service) { described_class.new(field) } - it 'returns a checker which checks for all objects' do - objects = [double(:first), double(:last)] + describe "#authorized_resolve" do + let(:presented_object) { double("presented object") } + let(:presented_type) { double("parent type", object: presented_object) } + subject(:resolved) { service.authorized_resolve.call(presented_type, {}, { current_user: current_user }) } - abilities.each do |ability| - objects.each do |object| - spy_ability_check_for(ability, object, passed: true) + context "scalar types" do + shared_examples "checking permissions on the presented object" do + it "checks the abilities on the object being presented and returns the value" do + expected_permissions.each do |permission| + spy_ability_check_for(permission, presented_object, passed: true) end + + expect(resolved).to eq("Resolved value") end - expect(checker.call(objects)).to eq(objects) + it "returns nil if the value wasn't authorized" do + allow(Ability).to receive(:allowed?).and_return false + + expect(resolved).to be_nil + end end - context 'when some objects would not pass the check' do - it 'returns nil when it is single object' do - disallowed = double(:object) + context "when the field is a scalar type" do + let(:field) { type_with_field(GraphQL::STRING_TYPE, :read_field).fields["testField"].to_graphql } + let(:expected_permissions) { [:read_field] } - spy_ability_check_for(abilities.first, disallowed, passed: false) + it_behaves_like "checking permissions on the presented object" + end - expect(checker.call(disallowed)).to be_nil - end + context "when the field is a list of scalar types" do + let(:field) { type_with_field([GraphQL::STRING_TYPE], :read_field).fields["testField"].to_graphql } + let(:expected_permissions) { [:read_field] } - it 'returns only objects which passed when there are more than one' do - allowed = double(:allowed) - disallowed = double(:disallowed) + it_behaves_like "checking permissions on the presented object" + end + end - spy_ability_check_for(abilities.first, disallowed, passed: false) + context "when the field is a specific type" do + let(:custom_type) { type(:read_type) } + let(:object_in_field) { double("presented in field") } + let(:field) { type_with_field(custom_type, :read_field, object_in_field).fields["testField"].to_graphql } - abilities.each do |ability| - spy_ability_check_for(ability, allowed, passed: true) - end + it "checks both field & type permissions" do + spy_ability_check_for(:read_field, object_in_field, passed: true) + spy_ability_check_for(:read_type, object_in_field, passed: true) - expect(checker.call([disallowed, allowed])).to contain_exactly(allowed) - end + expect(resolved).to eq(object_in_field) end - end - context 'when authorizing against another object' do - let(:authorizing_obj) { double(:object) } + it "returns nil if viewing was not allowed" do + spy_ability_check_for(:read_field, object_in_field, passed: false) + spy_ability_check_for(:read_type, object_in_field, passed: true) - let(:checker) do - service = described_class.new(double(resolve_proc: proc {})) - allow(service).to receive(:authorizations).and_return(abilities) - service.__send__(:build_checker, current_user, authorizing_obj) + expect(resolved).to be_nil end - it 'returns a checker which checks for a single object' do - object = double(:object) + context "when the field is a list" do + let(:object_1) { double("presented in field 1") } + let(:object_2) { double("presented in field 2") } + let(:presented_types) { [double(object: object_1), double(object: object_2)] } + let(:field) { type_with_field([custom_type], :read_field, presented_types).fields["testField"].to_graphql } - abilities.each do |ability| - spy_ability_check_for(ability, authorizing_obj, passed: true) + it "checks all permissions" do + allow(Ability).to receive(:allowed?) { true } + + spy_ability_check_for(:read_field, object_1, passed: true) + spy_ability_check_for(:read_type, object_1, passed: true) + spy_ability_check_for(:read_field, object_2, passed: true) + spy_ability_check_for(:read_type, object_2, passed: true) + + expect(resolved).to eq(presented_types) end - expect(checker.call(object)).to eq(object) - end + it "filters out objects that the user cannot see" do + allow(Ability).to receive(:allowed?) { true } - it 'returns a checker which checks for all objects' do - objects = [double(:first), double(:last)] + spy_ability_check_for(:read_type, object_1, passed: false) - abilities.each do |ability| - objects.each do |object| - spy_ability_check_for(ability, authorizing_obj, passed: true) - end + expect(resolved.map(&:object)).to contain_exactly(object_2) end - - expect(checker.call(objects)).to eq(objects) end end end diff --git a/spec/lib/gitlab/graphql/connections/keyset_connection_spec.rb b/spec/lib/gitlab/graphql/connections/keyset_connection_spec.rb index 9bcc1e78a78..fefa2881b18 100644 --- a/spec/lib/gitlab/graphql/connections/keyset_connection_spec.rb +++ b/spec/lib/gitlab/graphql/connections/keyset_connection_spec.rb @@ -85,6 +85,11 @@ describe Gitlab::Graphql::Connections::KeysetConnection do expect(subject.paged_nodes.size).to eq(3) end + it 'is a loaded memoized array' do + expect(subject.paged_nodes).to be_an(Array) + expect(subject.paged_nodes.object_id).to eq(subject.paged_nodes.object_id) + end + context 'when `first` is passed' do let(:arguments) { { first: 2 } } diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb index c2934430821..4f9f916f22e 100644 --- a/spec/requests/api/graphql/project/issues_spec.rb +++ b/spec/requests/api/graphql/project/issues_spec.rb @@ -7,8 +7,8 @@ describe 'getting an issue list for a project' do let(:current_user) { create(:user) } let(:issues_data) { graphql_data['project']['issues']['edges'] } let!(:issues) do - create(:issue, project: project, discussion_locked: true) - create(:issue, project: project) + [create(:issue, project: project, discussion_locked: true), + create(:issue, project: project)] end let(:fields) do <<~QUERY @@ -47,6 +47,30 @@ describe 'getting an issue list for a project' do expect(issues_data[1]['node']['discussionLocked']).to eq true end + context 'when limiting the number of results' do + let(:query) do + graphql_query_for( + 'project', + { 'fullPath' => project.full_path }, + "issues(first: 1) { #{fields} }" + ) + end + + it_behaves_like 'a working graphql query' do + before do + post_graphql(query, current_user: current_user) + end + end + + it "is expected to check permissions on the first issue only" do + allow(Ability).to receive(:allowed?).and_call_original + # Newest first, we only want to see the newest checked + expect(Ability).not_to receive(:allowed?).with(current_user, :read_issue, issues.first) + + post_graphql(query, current_user: current_user) + end + end + context 'when the user does not have access to the issue' do it 'returns nil' do project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE) -- GitLab From 4adcfd43dac92e0028c7d9d762b6d93994cb6782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Wed, 17 Apr 2019 18:41:15 +0000 Subject: [PATCH 03/12] Merge branch '60500-disable-jit-kubernetes-resource-creation-for-project-level-clusters' into 'master' Disable JIT Kubernetes resource creation for project level clusters Closes #60500 See merge request gitlab-org/gitlab-ce!27352 (cherry picked from commit a6a1afe070ffe4fa66b5ace9d35ca8c6ee481986) e33ecfde Disable JIT resource creation for project clusters --- app/services/clusters/refresh_service.rb | 6 +- app/workers/cluster_configure_worker.rb | 6 +- .../cluster_project_configure_worker.rb | 2 - ...ce-creation-for-project-level-clusters.yml | 5 ++ doc/user/project/clusters/index.md | 4 +- .../prerequisite/kubernetes_namespace.rb | 4 +- .../prerequisite/kubernetes_namespace_spec.rb | 10 ++- .../services/clusters/refresh_service_spec.rb | 26 +++++-- spec/workers/cluster_configure_worker_spec.rb | 67 +++++++++---------- .../cluster_project_configure_worker_spec.rb | 15 ++--- 10 files changed, 83 insertions(+), 62 deletions(-) create mode 100644 changelogs/unreleased/60500-disable-jit-kubernetes-resource-creation-for-project-level-clusters.yml diff --git a/app/services/clusters/refresh_service.rb b/app/services/clusters/refresh_service.rb index 7c82b98a33f..76ad8dd0fb0 100644 --- a/app/services/clusters/refresh_service.rb +++ b/app/services/clusters/refresh_service.rb @@ -21,7 +21,11 @@ module Clusters private_class_method :projects_with_missing_kubernetes_namespaces_for_cluster def self.clusters_with_missing_kubernetes_namespaces_for_project(project) - project.all_clusters.missing_kubernetes_namespace(project.kubernetes_namespaces) + if Feature.enabled?(:ci_preparing_state, default_enabled: true) + project.clusters.missing_kubernetes_namespace(project.kubernetes_namespaces) + else + project.all_clusters.missing_kubernetes_namespace(project.kubernetes_namespaces) + end end private_class_method :clusters_with_missing_kubernetes_namespaces_for_project diff --git a/app/workers/cluster_configure_worker.rb b/app/workers/cluster_configure_worker.rb index b984dee5b21..22681157b62 100644 --- a/app/workers/cluster_configure_worker.rb +++ b/app/workers/cluster_configure_worker.rb @@ -5,10 +5,10 @@ class ClusterConfigureWorker include ClusterQueue def perform(cluster_id) - return if Feature.enabled?(:ci_preparing_state, default_enabled: true) - Clusters::Cluster.find_by_id(cluster_id).try do |cluster| - Clusters::RefreshService.create_or_update_namespaces_for_cluster(cluster) + if cluster.project_type? || Feature.disabled?(:ci_preparing_state, default_enabled: true) + Clusters::RefreshService.create_or_update_namespaces_for_cluster(cluster) + end end end end diff --git a/app/workers/cluster_project_configure_worker.rb b/app/workers/cluster_project_configure_worker.rb index d7bea69a01c..497e57c0d0b 100644 --- a/app/workers/cluster_project_configure_worker.rb +++ b/app/workers/cluster_project_configure_worker.rb @@ -5,8 +5,6 @@ class ClusterProjectConfigureWorker include ClusterQueue def perform(project_id) - return if Feature.enabled?(:ci_preparing_state, default_enabled: true) - project = Project.find(project_id) ::Clusters::RefreshService.create_or_update_namespaces_for_project(project) diff --git a/changelogs/unreleased/60500-disable-jit-kubernetes-resource-creation-for-project-level-clusters.yml b/changelogs/unreleased/60500-disable-jit-kubernetes-resource-creation-for-project-level-clusters.yml new file mode 100644 index 00000000000..df6e6ea4be3 --- /dev/null +++ b/changelogs/unreleased/60500-disable-jit-kubernetes-resource-creation-for-project-level-clusters.yml @@ -0,0 +1,5 @@ +--- +title: Disable just-in-time Kubernetes resource creation for project level clusters +merge_request: 27352 +author: +type: changed diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md index 878d30dddaa..3f673ebb35a 100644 --- a/doc/user/project/clusters/index.md +++ b/doc/user/project/clusters/index.md @@ -565,7 +565,9 @@ service account of the cluster integration. ### Troubleshooting failed deployment jobs GitLab will create a namespace and service account specifically for your -deployment jobs, immediately before the jobs starts. +deployment jobs. On project level clusters, this happens when the cluster +is created. On group level clusters, resources are created immediately +before the deployment job starts. However, sometimes GitLab can not create them. In such instances, your job will fail with the message: diff --git a/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb b/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb index 41135ae62bb..bb2b209e793 100644 --- a/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb +++ b/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb @@ -6,7 +6,9 @@ module Gitlab module Prerequisite class KubernetesNamespace < Base def unmet? - deployment_cluster.present? && kubernetes_namespace.new_record? + deployment_cluster.present? && + !deployment_cluster.project_type? && + kubernetes_namespace.new_record? end def complete! diff --git a/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb b/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb index 62dcd80fad7..e8332b14627 100644 --- a/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb +++ b/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb @@ -20,7 +20,7 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do let!(:deployment) { create(:deployment, deployable: build) } context 'and a cluster to deploy to' do - let(:cluster) { create(:cluster, projects: [build.project]) } + let(:cluster) { create(:cluster, :group) } before do allow(build.deployment).to receive(:cluster).and_return(cluster) @@ -33,6 +33,12 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do it { is_expected.to be_falsey } end + + context 'and cluster is project type' do + let(:cluster) { create(:cluster, :project) } + + it { is_expected.to be_falsey } + end end context 'and no cluster to deploy to' do @@ -52,7 +58,7 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do subject { described_class.new(build).complete! } context 'completion is required' do - let(:cluster) { create(:cluster, projects: [build.project]) } + let(:cluster) { create(:cluster, :group) } before do allow(build.deployment).to receive(:cluster).and_return(cluster) diff --git a/spec/services/clusters/refresh_service_spec.rb b/spec/services/clusters/refresh_service_spec.rb index 58ab3c3cf73..9e442ebf4e9 100644 --- a/spec/services/clusters/refresh_service_spec.rb +++ b/spec/services/clusters/refresh_service_spec.rb @@ -93,14 +93,32 @@ describe Clusters::RefreshService do let(:group) { cluster.group } let(:project) { create(:project, group: group) } - include_examples 'creates a kubernetes namespace' + context 'when ci_preparing_state feature flag is enabled' do + include_examples 'does not create a kubernetes namespace' - context 'when project already has kubernetes namespace' do + context 'when project already has kubernetes namespace' do + before do + create(:cluster_kubernetes_namespace, project: project, cluster: cluster) + end + + include_examples 'does not create a kubernetes namespace' + end + end + + context 'when ci_preparing_state feature flag is disabled' do before do - create(:cluster_kubernetes_namespace, project: project, cluster: cluster) + stub_feature_flags(ci_preparing_state: false) end - include_examples 'does not create a kubernetes namespace' + include_examples 'creates a kubernetes namespace' + + context 'when project already has kubernetes namespace' do + before do + create(:cluster_kubernetes_namespace, project: project, cluster: cluster) + end + + include_examples 'does not create a kubernetes namespace' + end end end end diff --git a/spec/workers/cluster_configure_worker_spec.rb b/spec/workers/cluster_configure_worker_spec.rb index 83f76809435..bdb8e0e9c84 100644 --- a/spec/workers/cluster_configure_worker_spec.rb +++ b/spec/workers/cluster_configure_worker_spec.rb @@ -10,25 +10,35 @@ describe ClusterConfigureWorker, '#perform' do stub_feature_flags(ci_preparing_state: ci_preparing_state_enabled) end - context 'when group cluster' do - let(:cluster) { create(:cluster, :group, :provided_by_gcp) } - let(:group) { cluster.group } + shared_examples 'configured cluster' do + it 'creates a namespace' do + expect(Clusters::RefreshService).to receive(:create_or_update_namespaces_for_cluster).with(cluster).once - context 'when group has no projects' do - it 'does not create a namespace' do - expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).not_to receive(:execute) + worker.perform(cluster.id) + end + end - worker.perform(cluster.id) - end + shared_examples 'unconfigured cluster' do + it 'does not create a namespace' do + expect(Clusters::RefreshService).not_to receive(:create_or_update_namespaces_for_cluster) + + worker.perform(cluster.id) end + end + + context 'group cluster' do + let(:cluster) { create(:cluster, :group, :provided_by_gcp) } + let(:group) { cluster.group } context 'when group has a project' do let!(:project) { create(:project, group: group) } - it 'creates a namespace for the project' do - expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute).once + it_behaves_like 'configured cluster' + + context 'ci_preparing_state feature is enabled' do + let(:ci_preparing_state_enabled) { true } - worker.perform(cluster.id) + it_behaves_like 'unconfigured cluster' end end @@ -36,32 +46,26 @@ describe ClusterConfigureWorker, '#perform' do let!(:subgroup) { create(:group, parent: group) } let!(:project) { create(:project, group: subgroup) } - it 'creates a namespace for the project' do - expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute).once + it_behaves_like 'configured cluster' - worker.perform(cluster.id) + context 'ci_preparing_state feature is enabled' do + let(:ci_preparing_state_enabled) { true } + + it_behaves_like 'unconfigured cluster' end end end context 'when provider type is gcp' do - let(:cluster) { create(:cluster, :project, :provided_by_gcp) } - - it 'configures kubernetes platform' do - expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute) + let!(:cluster) { create(:cluster, :project, :provided_by_gcp) } - described_class.new.perform(cluster.id) - end + it_behaves_like 'configured cluster' end context 'when provider type is user' do - let(:cluster) { create(:cluster, :project, :provided_by_user) } + let!(:cluster) { create(:cluster, :project, :provided_by_user) } - it 'configures kubernetes platform' do - expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute) - - described_class.new.perform(cluster.id) - end + it_behaves_like 'configured cluster' end context 'when cluster does not exist' do @@ -71,15 +75,4 @@ describe ClusterConfigureWorker, '#perform' do described_class.new.perform(123) end end - - context 'ci_preparing_state feature is enabled' do - let(:cluster) { create(:cluster) } - let(:ci_preparing_state_enabled) { true } - - it 'does not configure the cluster' do - expect(Clusters::RefreshService).not_to receive(:create_or_update_namespaces_for_cluster) - - described_class.new.perform(cluster.id) - end - end end diff --git a/spec/workers/cluster_project_configure_worker_spec.rb b/spec/workers/cluster_project_configure_worker_spec.rb index afdea55adf4..2ac9d0f61b4 100644 --- a/spec/workers/cluster_project_configure_worker_spec.rb +++ b/spec/workers/cluster_project_configure_worker_spec.rb @@ -4,18 +4,11 @@ require 'spec_helper' describe ClusterProjectConfigureWorker, '#perform' do let(:worker) { described_class.new } + let(:cluster) { create(:cluster, :project) } - context 'ci_preparing_state feature is enabled' do - let(:cluster) { create(:cluster) } + it 'configures the cluster' do + expect(Clusters::RefreshService).to receive(:create_or_update_namespaces_for_project) - before do - stub_feature_flags(ci_preparing_state: true) - end - - it 'does not configure the cluster' do - expect(Clusters::RefreshService).not_to receive(:create_or_update_namespaces_for_project) - - described_class.new.perform(cluster.id) - end + described_class.new.perform(cluster.projects.first.id) end end -- GitLab From 550a8e235880d15a88c379da13a7361d16d76773 Mon Sep 17 00:00:00 2001 From: Fatih Acet Date: Wed, 17 Apr 2019 23:08:26 +0000 Subject: [PATCH 04/12] Merge branch 'jivl-add-feature-flag-gon-ee' into 'master' make the monitoring bundle reusable See merge request gitlab-org/gitlab-ce!27402 (cherry picked from commit ce02daea08c4cc7bc5e65e56f9b3d744a2e1faa6) 761fa974 Make the monitoring bundle reusable --- app/assets/javascripts/monitoring/monitoring_bundle.js | 3 ++- app/controllers/clusters/clusters_controller.rb | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/monitoring/monitoring_bundle.js b/app/assets/javascripts/monitoring/monitoring_bundle.js index 2b4ddd7afbc..ed794779ff2 100644 --- a/app/assets/javascripts/monitoring/monitoring_bundle.js +++ b/app/assets/javascripts/monitoring/monitoring_bundle.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import { parseBoolean } from '~/lib/utils/common_utils'; import Dashboard from './components/dashboard.vue'; -export default () => { +export default (props = {}) => { const el = document.getElementById('prometheus-graphs'); if (el && el.dataset) { @@ -15,6 +15,7 @@ export default () => { ...el.dataset, hasMetrics: parseBoolean(el.dataset.hasMetrics), showTimeWindowDropdown: gon.features.metricsTimeWindow, + ...props, }, }); }, diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb index e82756e4643..edaf07063ec 100644 --- a/app/controllers/clusters/clusters_controller.rb +++ b/app/controllers/clusters/clusters_controller.rb @@ -12,6 +12,9 @@ class Clusters::ClustersController < Clusters::BaseController before_action :authorize_update_cluster!, only: [:update] before_action :authorize_admin_cluster!, only: [:destroy] before_action :update_applications_status, only: [:cluster_status] + before_action only: [:show] do + push_frontend_feature_flag(:metrics_time_window) + end helper_method :token_in_session -- GitLab From 15801c5e159ce751dadeb5d7a61993ce9c693970 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Thu, 18 Apr 2019 13:09:09 +0000 Subject: [PATCH 05/12] Merge branch 'if-57131-move_do' into 'master' Move external authorization doc to CE See merge request gitlab-org/gitlab-ce!27421 (cherry picked from commit 3b483ed3f78ab759bde17c692246b20a41444d51) b8af0075 Move external authorization doc to CE --- .../settings/external_authorization.md | 112 ++++++++++++++++++ .../classification_label_on_project_page.png | Bin 0 -> 19568 bytes ...xternal_authorization_service_settings.png | Bin 0 -> 74753 bytes 3 files changed, 112 insertions(+) create mode 100644 doc/user/admin_area/settings/external_authorization.md create mode 100644 doc/user/admin_area/settings/img/classification_label_on_project_page.png create mode 100644 doc/user/admin_area/settings/img/external_authorization_service_settings.png diff --git a/doc/user/admin_area/settings/external_authorization.md b/doc/user/admin_area/settings/external_authorization.md new file mode 100644 index 00000000000..72e76ac2a84 --- /dev/null +++ b/doc/user/admin_area/settings/external_authorization.md @@ -0,0 +1,112 @@ +# External authorization control + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/4216) in +> [GitLab Premium](https://about.gitlab.com/pricing) 10.6. +> [Moved](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/27056) to +> [GitLab Core](https://about.gitlab.com/pricing/) in 11.10. + +In highly controlled environments, it may be necessary for access policy to be +controlled by an external service that permits access based on project +classification and user access. GitLab provides a way to check project +authorization with your own defined service. + +## Overview + +Once the external service is configured and enabled, when a project is accessed, +a request is made to the external service with the user information and project +classification label assigned to the project. When the service replies with a +known response, the result is cached for 6 hours. + +If the external authorization is enabled, GitLab will further block pages and +functionality that render cross-project data. That includes: + +- most pages under Dashboard (Activity, Milestones, Snippets, Assigned merge + requests, Assigned issues, Todos) +- under a specific group (Activity, Contribution analytics, Issues, Issue boards, + Labels, Milestones, Merge requests) +- Global and Group search will be disabled + +This is to prevent performing to many requests at once to the external +authorization service. + +Whenever access is granted or denied this is logged in a logfile called +`external-policy-access-control.log`. +Read more about logs GitLab keeps in the [omnibus documentation][omnibus-log-docs]. + +## Configuration + +The external authorization service can be enabled by an admin on the GitLab's +admin area under the settings page: + +![Enable external authorization service](img/external_authorization_service_settings.png) + +The available required properties are: + +- **Service URL**: The URL to make authorization requests to. When leaving the + URL blank, cross project features will remain available while still being able + to specify classification labels for projects. +- **External authorization request timeout**: The timeout after which an + authorization request is aborted. When a request times out, access is denied + to the user. +- **Client authentication certificate**: The certificate to use to authenticate + with the external authorization service. +- **Client authentication key**: Private key for the certificate when + authentication is required for the external authorization service, this is + encrypted when stored. +- **Client authentication key password**: Passphrase to use for the private key when authenticating with the external service this is encrypted when stored. +- **Default classification label**: The classification label to use when + requesting authorization if no specific label is defined on the project + +When using TLS Authentication with a self signed certificate, the CA certificate +needs to be trused by the openssl installation. When using GitLab installed using +Omnibus, learn to install a custom CA in the +[omnibus documentation][omnibus-ssl-docs]. Alternatively learn where to install +custom certificates using `openssl version -d`. + +## How it works + +When GitLab requests access, it will send a JSON POST request to the external +service with this body: + +```json +{ + "user_identifier": "jane@acme.org", + "project_classification_label": "project-label", + "user_ldap_dn": "CN=Jane Doe,CN=admin,DC=acme" +} +``` + +The `user_ldap_dn` is optional and is only sent when the user is logged in +through LDAP. + +When the external authorization service responds with a status code 200, the +user is granted access. When the external service responds with a status code +401 or 403, the user is denied access. In any case, the request is cached for 6 hours. + +When denying access, a `reason` can be optionally specified in the JSON body: + +```json +{ + "reason": "You are not allowed access to this project." +} +``` + +Any other status code than 200, 401 or 403 will also deny access to the user, but the +response will not be cached. + +If the service times out (after 500ms), a message "External Policy Server did +not respond" will be displayed. + +## Classification labels + +You can use your own classification label in the project's +**Settings > General > General project settings** page in the "Classification +label" box. When no classification label is specified on a project, the default +label defined in the [global settings](#configuration) will be used. + +The label will be shown on all project pages in the upper right corner. + +![classification label on project page](img/classification_label_on_project_page.png) + +[omnibus-ssl-docs]: https://docs.gitlab.com/omnibus/settings/ssl.html +[omnibus-log-docs]: https://docs.gitlab.com/omnibus/settings/logs.html diff --git a/doc/user/admin_area/settings/img/classification_label_on_project_page.png b/doc/user/admin_area/settings/img/classification_label_on_project_page.png new file mode 100644 index 0000000000000000000000000000000000000000..4aedb332cec96f4feed2d71b72fd3f42b339b708 GIT binary patch literal 19568 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 g=g*8)Sl|zrOXX&UXqXMn%CAcf^|~VC{6H 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 z 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 Ae*gdg literal 0 HcmV?d00001 -- GitLab From 79024a57719c98ce0cca4f05cb7e8ab527346797 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 17 Apr 2019 13:16:51 +0000 Subject: [PATCH 06/12] Merge branch 'sh-backport-list-commits-by-oid-rugged' into 'master' Bring back Rugged implementation of ListCommitsByOid See merge request gitlab-org/gitlab-ce!27441 (cherry picked from commit 6a72ab22c824c17e311492888fc99473a5c89192) 2fc4de6a Bring back Rugged implementation of ListCommitsByOid --- ...sh-backport-list-commits-by-oid-rugged.yml | 5 +++ doc/development/gitaly.md | 2 + lib/gitlab/git/rugged_impl/commit.rb | 20 ++++++++++ lib/gitlab/git/rugged_impl/repository.rb | 2 +- spec/lib/gitlab/git/commit_spec.rb | 37 ++++++++++++++++++- 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 changelogs/unreleased/sh-backport-list-commits-by-oid-rugged.yml diff --git a/changelogs/unreleased/sh-backport-list-commits-by-oid-rugged.yml b/changelogs/unreleased/sh-backport-list-commits-by-oid-rugged.yml new file mode 100644 index 00000000000..eb8774d652f --- /dev/null +++ b/changelogs/unreleased/sh-backport-list-commits-by-oid-rugged.yml @@ -0,0 +1,5 @@ +--- +title: Bring back Rugged implementation of ListCommitsByOid +merge_request: 27441 +author: +type: performance diff --git a/doc/development/gitaly.md b/doc/development/gitaly.md index 27b69ba8278..94d0c9b69a6 100644 --- a/doc/development/gitaly.md +++ b/doc/development/gitaly.md @@ -80,6 +80,8 @@ most commonly-used RPCs can be enabled via feature flags: * `rugged_get_tree_entries` * `rugged_tree_entry` * `rugged_commit_is_ancestor` +* `rugged_commit_tree_entry` +* `rugged_list_commits_by_oid` A convenience Rake task can be used to enable or disable these flags all together. To enable: diff --git a/lib/gitlab/git/rugged_impl/commit.rb b/lib/gitlab/git/rugged_impl/commit.rb index f6777dfa0c3..bce4fa14fb4 100644 --- a/lib/gitlab/git/rugged_impl/commit.rb +++ b/lib/gitlab/git/rugged_impl/commit.rb @@ -21,6 +21,17 @@ module Gitlab nil end + # This needs to return an array of Gitlab::Git:Commit objects + # instead of Rugged::Commit objects to ensure upstream models + # operate on a consistent interface. Unlike + # Gitlab::Git::Commit.find, Gitlab::Git::Commit.batch_by_oid + # doesn't attempt to decorate the result. + def rugged_batch_by_oid(repo, oids) + oids.map { |oid| rugged_find(repo, oid) } + .compact + .map { |commit| decorate(repo, commit) } + end + override :find_commit def find_commit(repo, commit_id) if Feature.enabled?(:rugged_find_commit) @@ -29,6 +40,15 @@ module Gitlab super end end + + override :batch_by_oid + def batch_by_oid(repo, oids) + if Feature.enabled?(:rugged_list_commits_by_oid) + rugged_batch_by_oid(repo, oids) + else + super + end + end end extend ::Gitlab::Utils::Override diff --git a/lib/gitlab/git/rugged_impl/repository.rb b/lib/gitlab/git/rugged_impl/repository.rb index c0a91f59ab9..e91b0ddcd31 100644 --- a/lib/gitlab/git/rugged_impl/repository.rb +++ b/lib/gitlab/git/rugged_impl/repository.rb @@ -12,7 +12,7 @@ module Gitlab module Repository extend ::Gitlab::Utils::Override - FEATURE_FLAGS = %i(rugged_find_commit rugged_tree_entries rugged_tree_entry rugged_commit_is_ancestor rugged_commit_tree_entry).freeze + FEATURE_FLAGS = %i(rugged_find_commit rugged_tree_entries rugged_tree_entry rugged_commit_is_ancestor rugged_commit_tree_entry rugged_list_commits_by_oid).freeze def alternate_object_directories relative_object_directories.map { |d| File.join(path, d) } diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb index 507bf222810..25052a79916 100644 --- a/spec/lib/gitlab/git/commit_spec.rb +++ b/spec/lib/gitlab/git/commit_spec.rb @@ -380,7 +380,32 @@ describe Gitlab::Git::Commit, :seed_helper do end end - describe '#batch_by_oid' do + shared_examples '.batch_by_oid' do + context 'with multiple OIDs' do + let(:oids) { [SeedRepo::Commit::ID, SeedRepo::FirstCommit::ID] } + + it 'returns multiple commits' do + commits = described_class.batch_by_oid(repository, oids) + + expect(commits.count).to eq(2) + expect(commits).to all( be_a(Gitlab::Git::Commit) ) + expect(commits.first.sha).to eq(SeedRepo::Commit::ID) + expect(commits.second.sha).to eq(SeedRepo::FirstCommit::ID) + end + end + + context 'when oids is empty' do + it 'returns empty commits' do + commits = described_class.batch_by_oid(repository, []) + + expect(commits.count).to eq(0) + end + end + end + + describe '.batch_by_oid with Gitaly enabled' do + it_should_behave_like '.batch_by_oid' + context 'when oids is empty' do it 'makes no Gitaly request' do expect(Gitlab::GitalyClient).not_to receive(:call) @@ -390,6 +415,16 @@ describe Gitlab::Git::Commit, :seed_helper do end end + describe '.batch_by_oid with Rugged enabled', :enable_rugged do + it_should_behave_like '.batch_by_oid' + + it 'calls out to the Rugged implementation' do + allow_any_instance_of(Rugged).to receive(:rev_parse).with(SeedRepo::Commit::ID).and_call_original + + described_class.batch_by_oid(repository, [SeedRepo::Commit::ID]) + end + end + shared_examples 'extracting commit signature' do context 'when the commit is signed' do let(:commit_id) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' } -- GitLab From 057684708510cf70d44083f7fd8065d8a428dd64 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Thu, 18 Apr 2019 23:09:16 +0000 Subject: [PATCH 07/12] Merge branch 'adriel-fix-cluster-metrics-regression' into 'master' Resolve cluster metrics regression Closes gitlab-ee#11168 See merge request gitlab-org/gitlab-ce!27442 (cherry picked from commit a82f553b15d9ac488def6a70b9bfe3215e9ae66f) 087c69a8 Resolve cluster metrics regression --- .../monitoring/stores/monitoring_store.js | 7 +++--- .../monitoring/monitoring_store_spec.js | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/monitoring/stores/monitoring_store.js b/app/assets/javascripts/monitoring/stores/monitoring_store.js index 9761fe168be..013fb0d4540 100644 --- a/app/assets/javascripts/monitoring/stores/monitoring_store.js +++ b/app/assets/javascripts/monitoring/stores/monitoring_store.js @@ -45,14 +45,13 @@ function removeTimeSeriesNoData(queries) { // ] function groupQueriesByChartInfo(metrics) { const metricsByChart = metrics.reduce((accumulator, metric) => { - const { id, queries, ...chart } = metric; + const { queries, ...chart } = metric; + const metricId = chart.id ? chart.id.toString() : null; const chartKey = `${chart.title}|${chart.y_label}`; accumulator[chartKey] = accumulator[chartKey] || { ...chart, queries: [] }; - queries.forEach(queryAttrs => - accumulator[chartKey].queries.push({ metricId: id.toString(), ...queryAttrs }), - ); + queries.forEach(queryAttrs => accumulator[chartKey].queries.push({ metricId, ...queryAttrs })); return accumulator; }, {}); diff --git a/spec/javascripts/monitoring/monitoring_store_spec.js b/spec/javascripts/monitoring/monitoring_store_spec.js index d8a980c874d..5bf6937c92e 100644 --- a/spec/javascripts/monitoring/monitoring_store_spec.js +++ b/spec/javascripts/monitoring/monitoring_store_spec.js @@ -32,4 +32,28 @@ describe('MonitoringStore', () => { it('removes the data if all the values from a query are not defined', () => { expect(store.groups[1].metrics[0].queries[0].result.length).toEqual(0); }); + + it('assigns queries a metric id', () => { + expect(store.groups[1].metrics[0].queries[0].metricId).toEqual('100'); + }); + + it('assigns metric id of null if metric has no id', () => { + const noId = MonitoringMock.data.map(group => ({ + ...group, + ...{ + metrics: group.metrics.map(metric => { + const { id, ...metricWithoutId } = metric; + + return metricWithoutId; + }), + }, + })); + store.storeMetrics(noId); + + store.groups.forEach(group => { + group.metrics.forEach(metric => { + expect(metric.queries.every(query => query.metricId === null)).toBe(true); + }); + }); + }); }); -- GitLab From 57777a3260cffd5bbfe37c5336f183836df6214f Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Thu, 18 Apr 2019 09:04:59 +0000 Subject: [PATCH 08/12] Merge branch 'docs-fixes-for-rp-11-10' into 'master' Doc fixes for the release post 11.10 See merge request gitlab-org/gitlab-ce!27450 (cherry picked from commit 42c99d9e36895c221d47bd961cca6a06097cbe85) 6dad16df Fixes "introduced in" note --- doc/ci/merge_request_pipelines/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ci/merge_request_pipelines/index.md b/doc/ci/merge_request_pipelines/index.md index 2de751c9e62..6a03ab910fc 100644 --- a/doc/ci/merge_request_pipelines/index.md +++ b/doc/ci/merge_request_pipelines/index.md @@ -69,7 +69,7 @@ when a merge request was created or updated. For example: ## Combined ref pipelines **[PREMIUM]** -> [GitLab Premium](https://about.gitlab.com/pricing/) 11.10. +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/7380) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10. It's possible for your source and target branches to diverge, which can result in the scenario that source branch's pipeline was green, the target's pipeline was green, -- GitLab From 3d194de8c1ca20a8959761d80a651e634dd2c155 Mon Sep 17 00:00:00 2001 From: Fatih Acet Date: Thu, 18 Apr 2019 09:38:46 +0000 Subject: [PATCH 09/12] Merge branch 'sh-fix-related-merge-request-api-paths' into 'master' Fix related merge requests not working with relative URL root See merge request gitlab-org/gitlab-ce!27475 (cherry picked from commit 2bbad757c9d16abe045fa1f3529c81e5c6c9d3e7) 31b4e54e Fix related merge requests not working with relative URL root --- app/views/projects/issues/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 2c95ac6dbb3..4bf1d8702af 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -77,7 +77,7 @@ = edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue-edited-ago js-issue-edited-ago') - #js-related-merge-requests{ data: { endpoint: api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: @issue.iid), project_namespace: @project.namespace.path, project_path: @project.path } } + #js-related-merge-requests{ data: { endpoint: expose_url(api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: @issue.iid)), project_namespace: @project.namespace.path, project_path: @project.path } } - if can?(current_user, :download_code, @project) #related-branches{ data: { url: related_branches_project_issue_path(@project, @issue) } } -- GitLab From 23e5f212bce488fa2006dba405a05a9bc18af3a7 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 18 Apr 2019 18:05:25 +0000 Subject: [PATCH 10/12] Merge branch 'jc-upgrade-gitaly-1.34.0' into 'master' Upgrade Gitaly to 1.34.0 See merge request gitlab-org/gitlab-ce!27494 (cherry picked from commit 63e41ba61b3ae0fba19500d01bfe041109590d14) 400d1369 Upgrade Gitaly to 1.34.0 --- GITALY_SERVER_VERSION | 2 +- changelogs/unreleased/jc-upgrade-gitaly-1-34-0.yml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/jc-upgrade-gitaly-1-34-0.yml diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 7aa332e4163..2b17ffd5042 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -1.33.0 +1.34.0 diff --git a/changelogs/unreleased/jc-upgrade-gitaly-1-34-0.yml b/changelogs/unreleased/jc-upgrade-gitaly-1-34-0.yml new file mode 100644 index 00000000000..c1669a484aa --- /dev/null +++ b/changelogs/unreleased/jc-upgrade-gitaly-1-34-0.yml @@ -0,0 +1,5 @@ +--- +title: Upgrade Gitaly to 1.34.0 +merge_request: 27494 +author: +type: fixed -- GitLab From 8760874620a931295fd788a86371a31443562360 Mon Sep 17 00:00:00 2001 From: Michael Kozono Date: Thu, 18 Apr 2019 18:23:55 +0000 Subject: [PATCH 11/12] Merge branch 'sh-bump-ruby-required-version-check' into 'master' Bump required Ruby version check to 2.5.3 Closes #60704 See merge request gitlab-org/gitlab-ce!27495 (cherry picked from commit e9bf3672dff56cf845114856a17ea72328215bcf) 0ca790af Bump required Ruby version check to 2.5.3 --- .../unreleased/sh-bump-ruby-required-version-check.yml | 5 +++++ lib/system_check/app/ruby_version_check.rb | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/sh-bump-ruby-required-version-check.yml diff --git a/changelogs/unreleased/sh-bump-ruby-required-version-check.yml b/changelogs/unreleased/sh-bump-ruby-required-version-check.yml new file mode 100644 index 00000000000..b5b6eb87650 --- /dev/null +++ b/changelogs/unreleased/sh-bump-ruby-required-version-check.yml @@ -0,0 +1,5 @@ +--- +title: Bump required Ruby version check to 2.5.3 +merge_request: 27495 +author: +type: other diff --git a/lib/system_check/app/ruby_version_check.rb b/lib/system_check/app/ruby_version_check.rb index 60e07718338..53da62df176 100644 --- a/lib/system_check/app/ruby_version_check.rb +++ b/lib/system_check/app/ruby_version_check.rb @@ -7,7 +7,7 @@ module SystemCheck set_check_pass -> { "yes (#{self.current_version})" } def self.required_version - @required_version ||= Gitlab::VersionInfo.new(2, 3, 5) + @required_version ||= Gitlab::VersionInfo.new(2, 5, 3) end def self.current_version -- GitLab From 46eed98e81ec4c7e6058d916e703a2d749d66436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Tue, 23 Apr 2019 10:21:25 +0000 Subject: [PATCH 12/12] Merge branch '60569-timeline-entry-label-link-is-not-applying-the-filter-on-issues' into 'master' Adds `label_name` back as a scalar param in `IssuableFinder` Closes #60569 See merge request gitlab-org/gitlab-ce!27507 (cherry picked from commit 5b154dafdf661cd2c7143de7e51e87d2bac4130b) ff627511 Add label_name as scalar param of IssuableFinder --- app/finders/issuable_finder.rb | 1 + ...k-is-not-applying-the-filter-on-issues.yml | 5 + .../concerns/issuable_collections_spec.rb | 110 +++++++++++------- 3 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 changelogs/unreleased/60569-timeline-entry-label-link-is-not-applying-the-filter-on-issues.yml diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 64c88505a16..fa9dda2ab31 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -53,6 +53,7 @@ class IssuableFinder assignee_username author_id author_username + label_name milestone_title my_reaction_emoji search diff --git a/changelogs/unreleased/60569-timeline-entry-label-link-is-not-applying-the-filter-on-issues.yml b/changelogs/unreleased/60569-timeline-entry-label-link-is-not-applying-the-filter-on-issues.yml new file mode 100644 index 00000000000..5319373ec4b --- /dev/null +++ b/changelogs/unreleased/60569-timeline-entry-label-link-is-not-applying-the-filter-on-issues.yml @@ -0,0 +1,5 @@ +--- +title: Fix filtering of labels from system note link +merge_request: 27507 +author: +type: fixed diff --git a/spec/controllers/concerns/issuable_collections_spec.rb b/spec/controllers/concerns/issuable_collections_spec.rb index a82b66361ca..f098ec2e167 100644 --- a/spec/controllers/concerns/issuable_collections_spec.rb +++ b/spec/controllers/concerns/issuable_collections_spec.rb @@ -106,51 +106,77 @@ describe IssuableCollections do end describe '#finder_options' do - let(:params) do - { - assignee_id: '1', - assignee_username: 'user1', - author_id: '2', - author_username: 'user2', - authorized_only: 'yes', - confidential: true, - due_date: '2017-01-01', - group_id: '3', - iids: '4', - label_name: ['foo'], - milestone_title: 'bar', - my_reaction_emoji: 'thumbsup', - non_archived: 'true', - project_id: '5', - scope: 'all', - search: 'baz', - sort: 'priority', - state: 'opened', - invalid_param: 'invalid_param' - } - end - - it 'only allows whitelisted params' do + before do allow(controller).to receive(:cookies).and_return({}) allow(controller).to receive(:current_user).and_return(nil) + end + + subject { controller.send(:finder_options).to_h } + + context 'scalar params' do + let(:params) do + { + assignee_id: '1', + assignee_username: 'user1', + author_id: '2', + author_username: 'user2', + authorized_only: 'yes', + confidential: true, + due_date: '2017-01-01', + group_id: '3', + iids: '4', + label_name: 'foo', + milestone_title: 'bar', + my_reaction_emoji: 'thumbsup', + non_archived: 'true', + project_id: '5', + scope: 'all', + search: 'baz', + sort: 'priority', + state: 'opened', + invalid_param: 'invalid_param' + } + end + + it 'only allows whitelisted params' do + is_expected.to include({ + 'assignee_id' => '1', + 'assignee_username' => 'user1', + 'author_id' => '2', + 'author_username' => 'user2', + 'confidential' => true, + 'label_name' => 'foo', + 'milestone_title' => 'bar', + 'my_reaction_emoji' => 'thumbsup', + 'due_date' => '2017-01-01', + 'scope' => 'all', + 'search' => 'baz', + 'sort' => 'priority', + 'state' => 'opened' + }) + + is_expected.not_to include('invalid_param') + end + end + + context 'array params' do + let(:params) do + { + assignee_username: %w[user1 user2], + label_name: %w[label1 label2], + invalid_param: 'invalid_param', + invalid_array: ['param'] + } + end + + it 'only allows whitelisted params' do + is_expected.to include({ + 'label_name' => %w[label1 label2], + 'assignee_username' => %w[user1 user2] + }) - finder_options = controller.send(:finder_options) - - expect(finder_options).to eq(ActionController::Parameters.new({ - 'assignee_id' => '1', - 'assignee_username' => 'user1', - 'author_id' => '2', - 'author_username' => 'user2', - 'confidential' => true, - 'label_name' => ['foo'], - 'milestone_title' => 'bar', - 'my_reaction_emoji' => 'thumbsup', - 'due_date' => '2017-01-01', - 'scope' => 'all', - 'search' => 'baz', - 'sort' => 'priority', - 'state' => 'opened' - }).permit!) + is_expected.not_to include('invalid_param', 'invalid_array') + end end end end -- GitLab