diff options
30 files changed, 252 insertions, 347 deletions
diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 4b7dda3a2ff..7f0d10ae4ac 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -573,6 +573,7 @@ img.emoji { .gl-font-size-large { font-size: $gl-font-size-large; } .gl-line-height-24 { line-height: $gl-line-height-24; } +.gl-line-height-14 { line-height: $gl-line-height-14; } .gl-font-size-12 { font-size: $gl-font-size-12; } .gl-font-size-14 { font-size: $gl-font-size-14; } diff --git a/app/controllers/concerns/sourcegraph_gon.rb b/app/controllers/concerns/sourcegraph_decorator.rb index 01925cf9d4d..5ef09b9221f 100644 --- a/app/controllers/concerns/sourcegraph_gon.rb +++ b/app/controllers/concerns/sourcegraph_decorator.rb @@ -1,10 +1,19 @@ # frozen_string_literal: true -module SourcegraphGon +module SourcegraphDecorator extend ActiveSupport::Concern included do before_action :push_sourcegraph_gon, if: :html_request? + + content_security_policy do |p| + next if p.directives.blank? + next unless Gitlab::CurrentSettings.sourcegraph_enabled + + default_connect_src = p.directives['connect-src'] || p.directives['default-src'] + connect_src_values = Array.wrap(default_connect_src) | [Gitlab::CurrentSettings.sourcegraph_url] + p.connect_src(*connect_src_values) + end end private diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index acd3ddf2d05..3cd14cf845f 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -8,7 +8,7 @@ class Projects::BlobController < Projects::ApplicationController include NotesHelper include ActionView::Helpers::SanitizeHelper include RedirectsForMissingPathOnTree - include SourcegraphGon + include SourcegraphDecorator prepend_before_action :authenticate_user!, only: [:edit] diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 5c5bdb867bd..3f2dc9b09fa 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -8,7 +8,7 @@ class Projects::CommitController < Projects::ApplicationController include CreatesCommit include DiffForPath include DiffHelper - include SourcegraphGon + include SourcegraphDecorator # Authorize before_action :require_non_empty_project diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 94b5f29eff7..5af0c835385 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -9,7 +9,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo include ToggleAwardEmoji include IssuableCollections include RecordUserLastActivity - include SourcegraphGon + include SourcegraphDecorator skip_before_action :merge_request, only: [:index, :bulk_update] before_action :whitelist_query_limiting, only: [:assign_related_issues, :update] diff --git a/app/finders/clusters/knative_serving_namespace_finder.rb b/app/finders/clusters/knative_serving_namespace_finder.rb deleted file mode 100644 index b6cf84beb79..00000000000 --- a/app/finders/clusters/knative_serving_namespace_finder.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module Clusters - class KnativeServingNamespaceFinder - attr_reader :cluster - - def initialize(cluster) - @cluster = cluster - end - - def execute - cluster.kubeclient&.get_namespace(Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE) - rescue Kubeclient::ResourceNotFoundError - nil - rescue Kubeclient::HttpError => e - # If the kubernetes auth engine is enabled, it will return 403 - if e.error_code == 403 - Gitlab::ErrorTracking.track_exception(e) - nil - else - raise - end - end - end -end diff --git a/app/finders/clusters/knative_version_role_binding_finder.rb b/app/finders/clusters/knative_version_role_binding_finder.rb deleted file mode 100644 index 26f5492840a..00000000000 --- a/app/finders/clusters/knative_version_role_binding_finder.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Clusters - class KnativeVersionRoleBindingFinder - attr_reader :cluster - - def initialize(cluster) - @cluster = cluster - end - - def execute - cluster.kubeclient&.get_cluster_role_binding(Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME) - rescue Kubeclient::ResourceNotFoundError - nil - end - end -end diff --git a/app/services/clusters/kubernetes.rb b/app/services/clusters/kubernetes.rb index 59cb1c4b3a9..d29519999b2 100644 --- a/app/services/clusters/kubernetes.rb +++ b/app/services/clusters/kubernetes.rb @@ -12,8 +12,5 @@ module Clusters GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME = 'gitlab-knative-serving-rolebinding' GITLAB_CROSSPLANE_DATABASE_ROLE_NAME = 'gitlab-crossplane-database-role' GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME = 'gitlab-crossplane-database-rolebinding' - GITLAB_KNATIVE_VERSION_ROLE_NAME = 'gitlab-knative-version-role' - GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME = 'gitlab-knative-version-rolebinding' - KNATIVE_SERVING_NAMESPACE = 'knative-serving' end end diff --git a/app/services/clusters/kubernetes/create_or_update_service_account_service.rb b/app/services/clusters/kubernetes/create_or_update_service_account_service.rb index 046046bf5a3..d798dcdcfd3 100644 --- a/app/services/clusters/kubernetes/create_or_update_service_account_service.rb +++ b/app/services/clusters/kubernetes/create_or_update_service_account_service.rb @@ -49,14 +49,8 @@ module Clusters create_or_update_knative_serving_role create_or_update_knative_serving_role_binding - create_or_update_crossplane_database_role create_or_update_crossplane_database_role_binding - - return unless knative_serving_namespace - - create_or_update_knative_version_role - create_or_update_knative_version_role_binding end private @@ -70,12 +64,6 @@ module Clusters ).ensure_exists! end - def knative_serving_namespace - kubeclient.get_namespace(Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE) - rescue Kubeclient::ResourceNotFoundError - nil - end - def create_role_or_cluster_role_binding if namespace_creator kubeclient.create_or_update_role_binding(role_binding_resource) @@ -100,14 +88,6 @@ module Clusters kubeclient.update_role_binding(crossplane_database_role_binding_resource) end - def create_or_update_knative_version_role - kubeclient.update_cluster_role(knative_version_role_resource) - end - - def create_or_update_knative_version_role_binding - kubeclient.update_cluster_role_binding(knative_version_role_binding_resource) - end - def service_account_resource Gitlab::Kubernetes::ServiceAccount.new( service_account_name, @@ -186,27 +166,6 @@ module Clusters service_account_name: service_account_name ).generate end - - def knative_version_role_resource - Gitlab::Kubernetes::ClusterRole.new( - name: Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_NAME, - rules: [{ - apiGroups: %w(apps), - resources: %w(deployments), - verbs: %w(list get) - }] - ).generate - end - - def knative_version_role_binding_resource - subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: service_account_namespace }] - - Gitlab::Kubernetes::ClusterRoleBinding.new( - Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME, - Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_NAME, - subjects - ).generate - end end end end diff --git a/changelogs/unreleased/revert-knative-version-prerequisite.yml b/changelogs/unreleased/revert-knative-version-prerequisite.yml new file mode 100644 index 00000000000..bc0bb1e25f3 --- /dev/null +++ b/changelogs/unreleased/revert-knative-version-prerequisite.yml @@ -0,0 +1,5 @@ +--- +title: Reverts Add RBAC permissions for getting knative version +merge_request: 22560 +author: +type: fixed diff --git a/changelogs/unreleased/sh-fix-unique-ips-limiter.yml b/changelogs/unreleased/sh-fix-unique-ips-limiter.yml new file mode 100644 index 00000000000..d124137e768 --- /dev/null +++ b/changelogs/unreleased/sh-fix-unique-ips-limiter.yml @@ -0,0 +1,5 @@ +--- +title: Fix deploy tokens erroneously triggering unique IP limits +merge_request: 22445 +author: +type: fixed diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index e4c45d37e6d..3fc9f75808f 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -2313,6 +2313,23 @@ This example creates three paths of execution: - Related to the above, stages must be explicitly defined for all jobs that have the keyword `needs:` or are referred to by one. +##### Changing the `needs:` job limit + +The maximum number of jobs that can be defined within `needs:` defaults to 10, but +can be changed to 50 via a feature flag. To change the limit to 50, +[start a Rails console session](https://docs.gitlab.com/omnibus/maintenance/#starting-a-rails-console-session) +and run: + +```ruby +Feature::disable(:ci_dag_limit_needs) +``` + +To set it back to 10, run the opposite command: + +```ruby +Feature::enable(:ci_dag_limit_needs) +``` + #### Artifact downloads with `needs` > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/14311) in GitLab v12.6. diff --git a/doc/user/project/clusters/serverless/index.md b/doc/user/project/clusters/serverless/index.md index 77981e5bd87..1dc543c3b83 100644 --- a/doc/user/project/clusters/serverless/index.md +++ b/doc/user/project/clusters/serverless/index.md @@ -118,8 +118,7 @@ You must do the following: 1. Ensure GitLab can manage Knative: - For a non-GitLab managed cluster, ensure that the service account for the token - provided can manage resources in the `serving.knative.dev` API group. It will also - need list access to the deployments in the `knative-serving` namespace. + provided can manage resources in the `serving.knative.dev` API group. - For a GitLab managed cluster, if you added the cluster in [GitLab 12.1 or later](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/30235), then GitLab will already have the required access and you can proceed to the next step. @@ -156,19 +155,6 @@ You must do the following: - delete - patch - watch - --- - apiVersion: rbac.authorization.k8s.io/v1 - kind: ClusterRole - metadata: - name: gitlab-knative-version-role - rules: - - apiGroups: - - apps - resources: - - deployments - verbs: - - list - - get ``` Then run the following command: diff --git a/lib/api/remote_mirrors.rb b/lib/api/remote_mirrors.rb index 8a085517ce9..95313966133 100644 --- a/lib/api/remote_mirrors.rb +++ b/lib/api/remote_mirrors.rb @@ -7,6 +7,8 @@ module API before do # TODO: Remove flag: https://gitlab.com/gitlab-org/gitlab/issues/38121 not_found! unless Feature.enabled?(:remote_mirrors_api, user_project) + + unauthorized! unless can?(current_user, :admin_remote_mirror, user_project) end params do @@ -20,11 +22,35 @@ module API use :pagination end get ':id/remote_mirrors' do - unauthorized! unless can?(current_user, :admin_remote_mirror, user_project) - present paginate(user_project.remote_mirrors), with: Entities::RemoteMirror end + + desc 'Update the attributes of a single remote mirror' do + success Entities::RemoteMirror + end + params do + requires :mirror_id, type: String, desc: 'The ID of a remote mirror' + optional :enabled, type: Boolean, desc: 'Determines if the mirror is enabled' + optional :only_protected_branches, type: Boolean, desc: 'Determines if only protected branches are mirrored' + end + put ':id/remote_mirrors/:mirror_id' do + mirror = user_project.remote_mirrors.find(params[:mirror_id]) + + mirror_params = declared_params(include_missing: false) + mirror_params[:id] = mirror_params.delete(:mirror_id) + update_params = { remote_mirrors_attributes: mirror_params } + + result = ::Projects::UpdateService + .new(user_project, current_user, update_params) + .execute + + if result[:status] == :success + present mirror.reset, with: Entities::RemoteMirror + else + render_api_error!(result[:message], result[:http_status]) + end + end end end end diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index dfdba617cb6..821c68dbedc 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -54,7 +54,7 @@ module Gitlab Gitlab::Auth::Result.new rate_limit!(rate_limiter, success: result.success?, login: login) - Gitlab::Auth::UniqueIpsLimiter.limit_user!(result.actor) + look_to_limit_user(result.actor) return result if result.success? || authenticate_using_internal_or_ldap_password? @@ -129,6 +129,10 @@ module Gitlab ::Ci::Build::CI_REGISTRY_USER == login end + def look_to_limit_user(actor) + Gitlab::Auth::UniqueIpsLimiter.limit_user!(actor) if actor.is_a?(User) + end + def authenticate_using_internal_or_ldap_password? Gitlab::CurrentSettings.password_authentication_enabled_for_git? || Gitlab::Auth::LDAP::Config.enabled? end diff --git a/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb b/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb index 465877871ea..b64990d6a7a 100644 --- a/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb +++ b/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb @@ -8,7 +8,7 @@ module Gitlab def unmet? deployment_cluster.present? && deployment_cluster.managed? && - (missing_namespace? || need_knative_version_role_binding?) + missing_namespace? end def complete! @@ -23,10 +23,6 @@ module Gitlab kubernetes_namespace.nil? || kubernetes_namespace.service_account_token.blank? end - def need_knative_version_role_binding? - !knative_serving_namespace.nil? && knative_version_role_binding.nil? - end - def deployment_cluster build.deployment&.cluster end @@ -35,22 +31,6 @@ module Gitlab build.deployment.environment end - def knative_serving_namespace - strong_memoize(:knative_serving_namespace) do - Clusters::KnativeServingNamespaceFinder.new( - deployment_cluster - ).execute - end - end - - def knative_version_role_binding - strong_memoize(:knative_version_role_binding) do - Clusters::KnativeVersionRoleBindingFinder.new( - deployment_cluster - ).execute - end - end - def kubernetes_namespace strong_memoize(:kubernetes_namespace) do Clusters::KubernetesNamespaceFinder.new( diff --git a/lib/gitlab/kubernetes/cluster_role.rb b/lib/gitlab/kubernetes/cluster_role.rb deleted file mode 100644 index 4d40736a0b5..00000000000 --- a/lib/gitlab/kubernetes/cluster_role.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module Kubernetes - class ClusterRole - attr_reader :name, :rules - - def initialize(name:, rules:) - @name = name - @rules = rules - end - - def generate - ::Kubeclient::Resource.new( - metadata: metadata, - rules: rules - ) - end - - private - - def metadata - { - name: name - } - end - end - end -end diff --git a/lib/gitlab/kubernetes/kube_client.rb b/lib/gitlab/kubernetes/kube_client.rb index 21d5c9b0eee..7cb7f46a623 100644 --- a/lib/gitlab/kubernetes/kube_client.rb +++ b/lib/gitlab/kubernetes/kube_client.rb @@ -57,7 +57,6 @@ module Gitlab # group client delegate :create_cluster_role_binding, :get_cluster_role_binding, - :get_cluster_role_bindings, :update_cluster_role_binding, to: :rbac_client @@ -70,13 +69,6 @@ module Gitlab # RBAC methods delegates to the apis/rbac.authorization.k8s.io api # group client - delegate :create_cluster_role, - :get_cluster_role, - :update_cluster_role, - to: :rbac_client - - # RBAC methods delegates to the apis/rbac.authorization.k8s.io api - # group client delegate :create_role_binding, :get_role_binding, :update_role_binding, diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 7cefd08d38c..02aa7a7933e 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -10365,9 +10365,6 @@ msgstr "" msgid "Label" msgstr "" -msgid "Label List" -msgstr "" - msgid "Label actions dropdown" msgstr "" @@ -10791,6 +10788,9 @@ msgstr "" msgid "List" msgstr "" +msgid "List Label" +msgstr "" + msgid "List Settings" msgstr "" @@ -16882,6 +16882,9 @@ msgstr "" msgid "Something went wrong while stopping this environment. Please try again." msgstr "" +msgid "Something went wrong while updating your list settings" +msgstr "" + msgid "Something went wrong, unable to add %{project} to dashboard" msgstr "" @@ -20653,6 +20656,9 @@ msgstr "" msgid "Withdraw Access Request" msgstr "" +msgid "Work in Progress Limit" +msgstr "" + msgid "Workflow Help" msgstr "" diff --git a/scripts/trigger-build b/scripts/trigger-build index b7b805b826f..6e50d8907d8 100755 --- a/scripts/trigger-build +++ b/scripts/trigger-build @@ -18,11 +18,16 @@ module Trigger class Base def invoke!(post_comment: false, downstream_job_name: nil) + pipeline_variables = variables + + puts "Triggering downstream pipeline on #{downstream_project_path}" + puts "with variables #{pipeline_variables}" + pipeline = Gitlab.run_trigger( downstream_project_path, trigger_token, ref, - variables) + pipeline_variables) puts "Triggered downstream pipeline: #{pipeline.web_url}\n" puts "Waiting for downstream pipeline status" diff --git a/spec/controllers/concerns/sourcegraph_gon_spec.rb b/spec/controllers/concerns/sourcegraph_decorator_spec.rb index d9273987871..f1f3f0489c6 100644 --- a/spec/controllers/concerns/sourcegraph_gon_spec.rb +++ b/spec/controllers/concerns/sourcegraph_decorator_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe SourcegraphGon do +describe SourcegraphDecorator do let_it_be(:enabled_user) { create(:user, sourcegraph_enabled: true) } let_it_be(:disabled_user) { create(:user, sourcegraph_enabled: false) } let_it_be(:public_project) { create(:project, :public) } @@ -17,7 +17,7 @@ describe SourcegraphGon do let(:project) { internal_project } controller(ApplicationController) do - include SourcegraphGon + include SourcegraphDecorator def index head :ok diff --git a/spec/features/projects/sourcegraph_csp_spec.rb b/spec/features/projects/sourcegraph_csp_spec.rb new file mode 100644 index 00000000000..57d1e8e3034 --- /dev/null +++ b/spec/features/projects/sourcegraph_csp_spec.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Sourcegraph Content Security Policy' do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :repository, namespace: user.namespace) } + let_it_be(:default_csp_values) { "'self' https://some-cdn.test" } + let_it_be(:sourcegraph_url) { 'https://sourcegraph.test' } + let(:sourcegraph_enabled) { true } + + subject do + visit project_blob_path(project, File.join('master', 'README.md')) + + response_headers['Content-Security-Policy'] + end + + before do + allow(Gitlab::CurrentSettings).to receive(:sourcegraph_url).and_return(sourcegraph_url) + allow(Gitlab::CurrentSettings).to receive(:sourcegraph_enabled).and_return(sourcegraph_enabled) + + sign_in(user) + end + + shared_context 'csp config' do |csp_rule| + before do + csp = ActionDispatch::ContentSecurityPolicy.new do |p| + p.send(csp_rule, default_csp_values) if csp_rule + end + + expect_next_instance_of(Projects::BlobController) do |controller| + expect(controller).to receive(:current_content_security_policy).and_return(csp) + end + end + end + + context 'when no CSP config' do + include_context 'csp config', nil + + it 'does not add CSP directives' do + is_expected.to be_blank + end + end + + describe 'when a CSP config exists for connect-src' do + include_context 'csp config', :connect_src + + context 'when sourcegraph enabled' do + it 'appends to connect-src' do + is_expected.to eql("connect-src #{default_csp_values} #{sourcegraph_url}") + end + end + + context 'when sourcegraph disabled' do + let(:sourcegraph_enabled) { false } + + it 'keeps original connect-src' do + is_expected.to eql("connect-src #{default_csp_values}") + end + end + end + + describe 'when a CSP config exists for default-src but not connect-src' do + include_context 'csp config', :default_src + + context 'when sourcegraph enabled' do + it 'uses default-src values in connect-src' do + is_expected.to eql("default-src #{default_csp_values}; connect-src #{default_csp_values} #{sourcegraph_url}") + end + end + + context 'when sourcegraph disabled' do + let(:sourcegraph_enabled) { false } + + it 'does not add connect-src' do + is_expected.to eql("default-src #{default_csp_values}") + end + end + end + + describe 'when a CSP config exists for font-src but not connect-src' do + include_context 'csp config', :font_src + + context 'when sourcegraph enabled' do + it 'uses default-src values in connect-src' do + is_expected.to eql("font-src #{default_csp_values}; connect-src #{sourcegraph_url}") + end + end + + context 'when sourcegraph disabled' do + let(:sourcegraph_enabled) { false } + + it 'does not add connect-src' do + is_expected.to eql("font-src #{default_csp_values}") + end + end + end +end diff --git a/spec/finders/clusters/knative_serving_namespace_finder_spec.rb b/spec/finders/clusters/knative_serving_namespace_finder_spec.rb deleted file mode 100644 index eceae75c444..00000000000 --- a/spec/finders/clusters/knative_serving_namespace_finder_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Clusters::KnativeServingNamespaceFinder do - include KubernetesHelpers - let(:cluster) { create(:cluster, :project, :provided_by_gcp) } - let(:service) { environment.deployment_platform } - let(:project) { cluster.cluster_project.project } - let(:environment) { create(:environment, project: project) } - - subject { Clusters::KnativeServingNamespaceFinder.new(cluster) } - - before do - stub_kubeclient_discover(service.api_url) - end - - it 'finds the namespace in a cluster where it exists' do - stub_kubeclient_get_namespace(service.api_url, namespace: Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE) - expect(subject.execute).to be_a Kubeclient::Resource - end - - it 'returns nil in a cluster where it does not' do - stub_kubeclient_get_namespace( - service.api_url, - namespace: Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE, - response: { - status: [404, "Resource Not Found"] - } - ) - expect(subject.execute).to be nil - end - - it 'returns nil in a cluster where the lookup results in a 403 as it will in some versions of kubernetes' do - stub_kubeclient_get_namespace( - service.api_url, - namespace: Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE, - response: { - status: [403, "Resource Not Found"] - } - ) - expect(subject.execute).to be nil - end - - it 'raises an error if error code is not 404 or 403' do - stub_kubeclient_get_namespace( - service.api_url, - namespace: Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE, - response: { - status: [500, "Internal Server Error"] - } - ) - expect { subject.execute }.to raise_error(Kubeclient::HttpError) - end -end diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index 311cbd4dd7e..1f943bebbec 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -130,6 +130,15 @@ describe Gitlab::Auth, :use_clean_rails_memory_store_caching do gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip') end + it 'rate limits a user by unique IPs' do + expect_next_instance_of(Gitlab::Auth::IpRateLimiter) do |rate_limiter| + expect(rate_limiter).to receive(:reset!) + end + expect(Gitlab::Auth::UniqueIpsLimiter).to receive(:limit_user!).twice.and_call_original + + gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip') + end + it 'registers failure for failed auth' do expect_next_instance_of(Gitlab::Auth::IpRateLimiter) do |rate_limiter| expect(rate_limiter).to receive(:register_fail!) @@ -415,6 +424,12 @@ describe Gitlab::Auth, :use_clean_rails_memory_store_caching do .to eq(auth_success) end + it 'does not attempt to rate limit unique IPs for a deploy token' do + expect(Gitlab::Auth::UniqueIpsLimiter).not_to receive(:limit_user!) + + gl_auth.find_for_git_client(login, deploy_token.token, project: project, ip: 'ip') + end + it 'fails when login is not valid' do expect(gl_auth.find_for_git_client('random_login', deploy_token.token, project: project, ip: 'ip')) .to eq(auth_failure) 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 2493855f851..66240380edd 100644 --- a/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb +++ b/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb @@ -38,44 +38,12 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do .and_return(double(execute: kubernetes_namespace)) end - context 'and the knative-serving namespace is missing' do - before do - allow(Clusters::KnativeServingNamespaceFinder).to receive(:new) - .and_return(double(execute: false)) - end - - it { is_expected.to be_truthy } - end - - context 'and the knative-serving namespace exists' do - before do - allow(Clusters::KnativeServingNamespaceFinder).to receive(:new) - .and_return(double(execute: true)) - end - - context 'and the knative version role binding is missing' do - before do - allow(Clusters::KnativeVersionRoleBindingFinder).to receive(:new) - .and_return(double(execute: nil)) - end - - it { is_expected.to be_truthy } - end - - context 'and the knative version role binding already exists' do - before do - allow(Clusters::KnativeVersionRoleBindingFinder).to receive(:new) - .and_return(double(execute: true)) - end - - it { is_expected.to be_falsey } + it { is_expected.to be_falsey } - context 'and the service_account_token is blank' do - let(:kubernetes_namespace) { instance_double(Clusters::KubernetesNamespace, service_account_token: nil) } + context 'and the service_account_token is blank' do + let(:kubernetes_namespace) { instance_double(Clusters::KubernetesNamespace, service_account_token: nil) } - it { is_expected.to be_truthy } - end - end + it { is_expected.to be_truthy } end end end @@ -188,24 +156,6 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do subject end end - - context 'knative version role binding is missing' do - before do - allow(Clusters::KubernetesNamespaceFinder).to receive(:new) - .and_return(double(execute: kubernetes_namespace)) - allow(Clusters::KnativeVersionRoleBindingFinder).to receive(:new) - .and_return(double(execute: nil)) - end - - it 'creates the knative version role binding' do - expect(Clusters::Kubernetes::CreateOrUpdateNamespaceService) - .to receive(:new) - .with(cluster: cluster, kubernetes_namespace: kubernetes_namespace) - .and_return(service) - - subject - end - end end context 'completion is not required' do diff --git a/spec/requests/api/remote_mirrors_spec.rb b/spec/requests/api/remote_mirrors_spec.rb index c5ba9bd223e..065d9c7ca5b 100644 --- a/spec/requests/api/remote_mirrors_spec.rb +++ b/spec/requests/api/remote_mirrors_spec.rb @@ -5,14 +5,13 @@ require 'spec_helper' describe API::RemoteMirrors do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, :repository, :remote_mirror) } + let_it_be(:developer) { create(:user) { |u| project.add_developer(u) } } describe 'GET /projects/:id/remote_mirrors' do let(:route) { "/projects/#{project.id}/remote_mirrors" } it 'requires `admin_remote_mirror` permission' do - project.add_developer(user) - - get api(route, user) + get api(route, developer) expect(response).to have_gitlab_http_status(:unauthorized) end @@ -26,6 +25,7 @@ describe API::RemoteMirrors do expect(response).to match_response_schema('remote_mirrors') end + # TODO: Remove flag: https://gitlab.com/gitlab-org/gitlab/issues/38121 context 'with the `remote_mirrors_api` feature disabled' do before do stub_feature_flags(remote_mirrors_api: false) @@ -38,4 +38,41 @@ describe API::RemoteMirrors do end end end + + describe 'PUT /projects/:id/remote_mirrors/:mirror_id' do + let(:route) { ->(id) { "/projects/#{project.id}/remote_mirrors/#{id}" } } + let(:mirror) { project.remote_mirrors.first } + + it 'requires `admin_remote_mirror` permission' do + put api(route[mirror.id], developer) + + expect(response).to have_gitlab_http_status(:unauthorized) + end + + it 'updates a remote mirror' do + project.add_maintainer(user) + + put api(route[mirror.id], user), params: { + enabled: '0', + only_protected_branches: 'true' + } + + expect(response).to have_gitlab_http_status(:success) + expect(json_response['enabled']).to eq(false) + expect(json_response['only_protected_branches']).to eq(true) + end + + # TODO: Remove flag: https://gitlab.com/gitlab-org/gitlab/issues/38121 + context 'with the `remote_mirrors_api` feature disabled' do + before do + stub_feature_flags(remote_mirrors_api: false) + end + + it 'responds with `not_found`' do + put api(route[mirror.id], user) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end end diff --git a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb index 5dc4a1dc0b3..bd1a90996a8 100644 --- a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb +++ b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb @@ -22,6 +22,7 @@ describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do before do stub_kubeclient_discover(api_url) + stub_kubeclient_get_namespace(api_url) stub_kubeclient_get_service_account_error(api_url, 'gitlab') stub_kubeclient_create_service_account(api_url) stub_kubeclient_get_secret_error(api_url, 'gitlab-token') @@ -30,7 +31,6 @@ describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do stub_kubeclient_get_role_binding(api_url, "gitlab-#{namespace}", namespace: namespace) stub_kubeclient_put_role_binding(api_url, "gitlab-#{namespace}", namespace: namespace) stub_kubeclient_get_namespace(api_url, namespace: namespace) - stub_kubeclient_get_namespace(api_url, namespace: Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE) stub_kubeclient_get_service_account_error(api_url, "#{namespace}-service-account", namespace: namespace) stub_kubeclient_create_service_account(api_url, namespace: namespace) stub_kubeclient_create_secret(api_url, namespace: namespace) @@ -39,8 +39,6 @@ describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME, namespace: namespace) stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME, namespace: namespace) stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME, namespace: namespace) - stub_kubeclient_put_cluster_role(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_NAME) - stub_kubeclient_put_cluster_role_binding(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME) stub_kubeclient_get_secret( api_url, diff --git a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb index 1ca3c50c46c..4df73fcc2ae 100644 --- a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb +++ b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb @@ -141,15 +141,12 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do before do cluster.platform_kubernetes.rbac! - stub_kubeclient_get_namespace(api_url, namespace: Clusters::Kubernetes::KNATIVE_SERVING_NAMESPACE) stub_kubeclient_get_role_binding_error(api_url, role_binding_name, namespace: namespace) stub_kubeclient_create_role_binding(api_url, namespace: namespace) stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, namespace: namespace) stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME, namespace: namespace) stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME, namespace: namespace) stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME, namespace: namespace) - stub_kubeclient_put_cluster_role(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_NAME) - stub_kubeclient_put_cluster_role_binding(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME) end it_behaves_like 'creates service account and token' @@ -237,30 +234,6 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do ) ) end - - it 'creates a role and role binding granting the ability to get the version of deployments in knative-serving namespace' do - subject - - expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/#{Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME}").with( - body: hash_including( - metadata: { - name: Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME - }, - roleRef: { - apiGroup: "rbac.authorization.k8s.io", - kind: "ClusterRole", - name: Clusters::Kubernetes::GITLAB_KNATIVE_VERSION_ROLE_NAME - }, - subjects: [ - { - kind: "ServiceAccount", - name: service_account_name, - namespace: namespace - } - ] - ) - ) - end end end end diff --git a/spec/services/clusters/kubernetes_spec.rb b/spec/services/clusters/kubernetes_spec.rb index 7f2c5e0461d..09cc304debe 100644 --- a/spec/services/clusters/kubernetes_spec.rb +++ b/spec/services/clusters/kubernetes_spec.rb @@ -13,7 +13,4 @@ describe Clusters::Kubernetes do it { is_expected.to be_const_defined(:GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME) } it { is_expected.to be_const_defined(:GITLAB_CROSSPLANE_DATABASE_ROLE_NAME) } it { is_expected.to be_const_defined(:GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME) } - it { is_expected.to be_const_defined(:GITLAB_KNATIVE_VERSION_ROLE_NAME) } - it { is_expected.to be_const_defined(:GITLAB_KNATIVE_VERSION_ROLE_BINDING_NAME) } - it { is_expected.to be_const_defined(:KNATIVE_SERVING_NAMESPACE) } end diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb index 2fabfb94928..89360b55de2 100644 --- a/spec/support/helpers/kubernetes_helpers.rb +++ b/spec/support/helpers/kubernetes_helpers.rb @@ -202,11 +202,6 @@ module KubernetesHelpers .to_return(kube_response({})) end - def stub_kubeclient_put_cluster_role_binding(api_url, name) - WebMock.stub_request(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/#{name}") - .to_return(kube_response({})) - end - def stub_kubeclient_get_role_binding(api_url, name, namespace: 'default') WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}") .to_return(kube_response({})) @@ -232,18 +227,8 @@ module KubernetesHelpers .to_return(kube_response({})) end - def stub_kubeclient_get_namespaces(api_url) - WebMock.stub_request(:get, api_url + '/api/v1/namespaces') - .to_return(kube_response(kube_v1_namespace_list_body)) - end - - def stub_kubeclient_get_namespace(api_url, namespace: 'default', response: kube_response({})) + def stub_kubeclient_get_namespace(api_url, namespace: 'default') WebMock.stub_request(:get, api_url + "/api/v1/namespaces/#{namespace}") - .to_return(response) - end - - def stub_kubeclient_put_cluster_role(api_url, name) - WebMock.stub_request(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/clusterroles/#{name}") .to_return(kube_response({})) end @@ -290,20 +275,6 @@ module KubernetesHelpers } end - def kube_v1_namespace_list_body - { - "kind" => "NamespaceList", - "apiVersion" => "v1", - "items" => [ - { - "metadata" => { - "name" => "knative-serving" - } - } - ] - } - end - def kube_v1beta1_discovery_body { "kind" => "APIResourceList", |