diff options
73 files changed, 529 insertions, 475 deletions
diff --git a/.gitlab/ci/docs.gitlab-ci.yml b/.gitlab/ci/docs.gitlab-ci.yml index e77c773824f..3f29adddf73 100644 --- a/.gitlab/ci/docs.gitlab-ci.yml +++ b/.gitlab/ci/docs.gitlab-ci.yml @@ -74,7 +74,7 @@ docs lint: script: - scripts/lint-doc.sh # Lint Markdown - - markdownlint --config .markdownlint.json doc/**/*.md + - markdownlint --config .markdownlint.json 'doc/**/*.md' # Prepare docs for build - mv doc/ /tmp/gitlab-docs/content/$DOCS_GITLAB_REPO_SUFFIX - cd /tmp/gitlab-docs diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index af6644b8fcc..2f7ac41781a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -47,8 +47,8 @@ class ApplicationController < ActionController::Base # Adds `no-store` to the DEFAULT_CACHE_CONTROL, to prevent security # concerns due to caching private data. - DEFAULT_GITLAB_CACHE_CONTROL = "#{ActionDispatch::Http::Cache::Response::DEFAULT_CACHE_CONTROL}, no-store".freeze - DEFAULT_GITLAB_CONTROL_NO_CACHE = "#{DEFAULT_GITLAB_CACHE_CONTROL}, no-cache".freeze + DEFAULT_GITLAB_CACHE_CONTROL = "#{ActionDispatch::Http::Cache::Response::DEFAULT_CACHE_CONTROL}, no-store" + DEFAULT_GITLAB_CONTROL_NO_CACHE = "#{DEFAULT_GITLAB_CACHE_CONTROL}, no-cache" rescue_from Encoding::CompatibilityError do |exception| log_exception(exception) @@ -143,7 +143,7 @@ class ApplicationController < ActionController::Base payload[:username] = logged_user.try(:username) end - if response.status == 422 && response.body.present? && response.content_type == 'application/json'.freeze + if response.status == 422 && response.body.present? && response.content_type == 'application/json' payload[:response] = response.body end diff --git a/app/controllers/concerns/lfs_request.rb b/app/controllers/concerns/lfs_request.rb index f7137a04437..bff0715f192 100644 --- a/app/controllers/concerns/lfs_request.rb +++ b/app/controllers/concerns/lfs_request.rb @@ -12,7 +12,7 @@ module LfsRequest extend ActiveSupport::Concern - CONTENT_TYPE = 'application/vnd.git-lfs+json'.freeze + CONTENT_TYPE = 'application/vnd.git-lfs+json' included do before_action :require_lfs_enabled! diff --git a/app/controllers/projects/lfs_api_controller.rb b/app/controllers/projects/lfs_api_controller.rb index 42c415757f9..c16736a756a 100644 --- a/app/controllers/projects/lfs_api_controller.rb +++ b/app/controllers/projects/lfs_api_controller.rb @@ -3,7 +3,7 @@ class Projects::LfsApiController < Projects::GitHttpClientController include LfsRequest - LFS_TRANSFER_CONTENT_TYPE = 'application/octet-stream'.freeze + LFS_TRANSFER_CONTENT_TYPE = 'application/octet-stream' skip_before_action :lfs_check_access!, only: [:deprecated] before_action :lfs_check_batch_operation!, only: [:batch] diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 7b682cc0cc5..a6dd811ab8b 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -40,7 +40,7 @@ class SessionsController < Devise::SessionsController # token mismatch. protect_from_forgery with: :exception, prepend: true - CAPTCHA_HEADER = 'X-GitLab-Show-Login-Captcha'.freeze + CAPTCHA_HEADER = 'X-GitLab-Show-Login-Captcha' MAX_FAILED_LOGIN_ATTEMPTS = 5 def new @@ -111,14 +111,14 @@ class SessionsController < Devise::SessionsController def increment_failed_login_captcha_counter Gitlab::Metrics.counter( :failed_login_captcha_total, - 'Number of failed CAPTCHA attempts for logins'.freeze + 'Number of failed CAPTCHA attempts for logins' ).increment end def increment_successful_login_captcha_counter Gitlab::Metrics.counter( :successful_login_captcha_total, - 'Number of successful CAPTCHA attempts for logins'.freeze + 'Number of successful CAPTCHA attempts for logins' ).increment end diff --git a/app/models/award_emoji.rb b/app/models/award_emoji.rb index 0ab302a0f3e..24fcb97db6e 100644 --- a/app/models/award_emoji.rb +++ b/app/models/award_emoji.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true class AwardEmoji < ApplicationRecord - DOWNVOTE_NAME = "thumbsdown".freeze - UPVOTE_NAME = "thumbsup".freeze + DOWNVOTE_NAME = "thumbsdown" + UPVOTE_NAME = "thumbsup" include Participable include GhostUser diff --git a/app/models/blob_viewer/base.rb b/app/models/blob_viewer/base.rb index df6b9bb2f0b..1c3a6599f36 100644 --- a/app/models/blob_viewer/base.rb +++ b/app/models/blob_viewer/base.rb @@ -2,7 +2,7 @@ module BlobViewer class Base - PARTIAL_PATH_PREFIX = 'projects/blob/viewers'.freeze + PARTIAL_PATH_PREFIX = 'projects/blob/viewers' class_attribute :partial_name, :loading_partial_name, :type, :extensions, :file_types, :load_async, :binary, :switcher_icon, :switcher_title, :collapse_limit, :size_limit diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb index da4584228ce..1338a585c9e 100644 --- a/app/models/broadcast_message.rb +++ b/app/models/broadcast_message.rb @@ -16,7 +16,7 @@ class BroadcastMessage < ApplicationRecord default_value_for :color, '#E75E40' default_value_for :font, '#FFFFFF' - CACHE_KEY = 'broadcast_message_current_json'.freeze + CACHE_KEY = 'broadcast_message_current_json' after_commit :flush_redis_cache diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 79a2d5e6e9d..d558f66154e 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -445,7 +445,7 @@ module Ci end end - CI_REGISTRY_USER = 'gitlab-ci-token'.freeze + CI_REGISTRY_USER = 'gitlab-ci-token' def persisted_variables Gitlab::Ci::Variables::Collection.new.tap do |variables| diff --git a/app/models/ci/build_runner_session.rb b/app/models/ci/build_runner_session.rb index 997bf298025..8075c15bbaf 100644 --- a/app/models/ci/build_runner_session.rb +++ b/app/models/ci/build_runner_session.rb @@ -6,7 +6,7 @@ module Ci class BuildRunnerSession < ApplicationRecord extend Gitlab::Ci::Model - TERMINAL_SUBPROTOCOL = 'terminal.gitlab.com'.freeze + TERMINAL_SUBPROTOCOL = 'terminal.gitlab.com' self.table_name = 'ci_builds_runner_session' diff --git a/app/models/clusters/applications/ingress.rb b/app/models/clusters/applications/ingress.rb index 1430b82c2f2..50def3ba38c 100644 --- a/app/models/clusters/applications/ingress.rb +++ b/app/models/clusters/applications/ingress.rb @@ -3,7 +3,7 @@ module Clusters module Applications class Ingress < ApplicationRecord - VERSION = '1.1.2'.freeze + VERSION = '1.1.2' self.table_name = 'clusters_applications_ingress' diff --git a/app/models/clusters/applications/jupyter.rb b/app/models/clusters/applications/jupyter.rb index 9ede0615fa3..fb74d96efe3 100644 --- a/app/models/clusters/applications/jupyter.rb +++ b/app/models/clusters/applications/jupyter.rb @@ -5,7 +5,7 @@ require 'securerandom' module Clusters module Applications class Jupyter < ApplicationRecord - VERSION = '0.9-174bbd5'.freeze + VERSION = '0.9-174bbd5' self.table_name = 'clusters_applications_jupyter' diff --git a/app/models/clusters/applications/knative.rb b/app/models/clusters/applications/knative.rb index 244fe738396..a9b9374622d 100644 --- a/app/models/clusters/applications/knative.rb +++ b/app/models/clusters/applications/knative.rb @@ -3,9 +3,9 @@ module Clusters module Applications class Knative < ApplicationRecord - VERSION = '0.6.0'.freeze - REPOSITORY = 'https://storage.googleapis.com/triggermesh-charts'.freeze - METRICS_CONFIG = 'https://storage.googleapis.com/triggermesh-charts/istio-metrics.yaml'.freeze + VERSION = '0.6.0' + REPOSITORY = 'https://storage.googleapis.com/triggermesh-charts' + METRICS_CONFIG = 'https://storage.googleapis.com/triggermesh-charts/istio-metrics.yaml' FETCH_IP_ADDRESS_DELAY = 30.seconds API_RESOURCES_PATH = 'config/knative/api_resources.yml' diff --git a/app/models/clusters/applications/runner.rb b/app/models/clusters/applications/runner.rb index 329250255fd..2d6af8f4f0b 100644 --- a/app/models/clusters/applications/runner.rb +++ b/app/models/clusters/applications/runner.rb @@ -3,7 +3,7 @@ module Clusters module Applications class Runner < ApplicationRecord - VERSION = '0.8.0'.freeze + VERSION = '0.8.0' self.table_name = 'clusters_applications_runners' diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index 97d39491b73..444e1a82c97 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -20,8 +20,8 @@ module Clusters Applications::Runner.application_name => Applications::Runner, Applications::Prometheus.application_name => Applications::Prometheus }.merge(PROJECT_ONLY_APPLICATIONS).freeze - DEFAULT_ENVIRONMENT = '*'.freeze - KUBE_INGRESS_BASE_DOMAIN = 'KUBE_INGRESS_BASE_DOMAIN'.freeze + DEFAULT_ENVIRONMENT = '*' + KUBE_INGRESS_BASE_DOMAIN = 'KUBE_INGRESS_BASE_DOMAIN' belongs_to :user diff --git a/app/models/concerns/cacheable_attributes.rb b/app/models/concerns/cacheable_attributes.rb index 0c800621a55..d459af23a2f 100644 --- a/app/models/concerns/cacheable_attributes.rb +++ b/app/models/concerns/cacheable_attributes.rb @@ -11,7 +11,7 @@ module CacheableAttributes class_methods do def cache_key - "#{name}:#{Gitlab::VERSION}:#{Rails.version}".freeze + "#{name}:#{Gitlab::VERSION}:#{Rails.version}" end # Can be overridden diff --git a/app/models/concerns/has_status.rb b/app/models/concerns/has_status.rb index 71ebb586c13..cf88076ac74 100644 --- a/app/models/concerns/has_status.rb +++ b/app/models/concerns/has_status.rb @@ -3,7 +3,7 @@ module HasStatus extend ActiveSupport::Concern - DEFAULT_STATUS = 'created'.freeze + DEFAULT_STATUS = 'created' BLOCKED_STATUS = %w[manual scheduled].freeze AVAILABLE_STATUSES = %w[created preparing pending running success failed canceled skipped manual scheduled].freeze STARTED_STATUSES = %w[running success failed skipped manual scheduled].freeze diff --git a/app/models/concerns/protected_ref_access.rb b/app/models/concerns/protected_ref_access.rb index 583751ea6ac..208937f2aff 100644 --- a/app/models/concerns/protected_ref_access.rb +++ b/app/models/concerns/protected_ref_access.rb @@ -4,9 +4,9 @@ module ProtectedRefAccess extend ActiveSupport::Concern HUMAN_ACCESS_LEVELS = { - Gitlab::Access::MAINTAINER => "Maintainers".freeze, - Gitlab::Access::DEVELOPER => "Developers + Maintainers".freeze, - Gitlab::Access::NO_ACCESS => "No one".freeze + Gitlab::Access::MAINTAINER => "Maintainers", + Gitlab::Access::DEVELOPER => "Developers + Maintainers", + Gitlab::Access::NO_ACCESS => "No one" }.freeze class_methods do diff --git a/app/models/concerns/taskable.rb b/app/models/concerns/taskable.rb index 8b536a123fc..98842242eb6 100644 --- a/app/models/concerns/taskable.rb +++ b/app/models/concerns/taskable.rb @@ -9,8 +9,8 @@ require 'task_list/filter' # # Used by MergeRequest and Issue module Taskable - COMPLETED = 'completed'.freeze - INCOMPLETE = 'incomplete'.freeze + COMPLETED = 'completed' + INCOMPLETE = 'incomplete' COMPLETE_PATTERN = /(\[[xX]\])/.freeze INCOMPLETE_PATTERN = /(\[[\s]\])/.freeze ITEM_PATTERN = %r{ diff --git a/app/models/deploy_token.rb b/app/models/deploy_token.rb index 85f5a2040c0..20e1d802178 100644 --- a/app/models/deploy_token.rb +++ b/app/models/deploy_token.rb @@ -8,7 +8,7 @@ class DeployToken < ApplicationRecord add_authentication_token_field :token, encrypted: :optional AVAILABLE_SCOPES = %i(read_repository read_registry).freeze - GITLAB_DEPLOY_TOKEN_NAME = 'gitlab-deploy-token'.freeze + GITLAB_DEPLOY_TOKEN_NAME = 'gitlab-deploy-token' default_value_for(:expires_at) { Forever.date } diff --git a/app/models/diff_viewer/base.rb b/app/models/diff_viewer/base.rb index 527ee33b83b..22c8fe73563 100644 --- a/app/models/diff_viewer/base.rb +++ b/app/models/diff_viewer/base.rb @@ -2,7 +2,7 @@ module DiffViewer class Base - PARTIAL_PATH_PREFIX = 'projects/diffs/viewers'.freeze + PARTIAL_PATH_PREFIX = 'projects/diffs/viewers' class_attribute :partial_name, :type, :extensions, :file_types, :binary, :switcher_icon, :switcher_title diff --git a/app/models/gpg_key.rb b/app/models/gpg_key.rb index 116beac5c2a..995baf8565c 100644 --- a/app/models/gpg_key.rb +++ b/app/models/gpg_key.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true class GpgKey < ApplicationRecord - KEY_PREFIX = '-----BEGIN PGP PUBLIC KEY BLOCK-----'.freeze - KEY_SUFFIX = '-----END PGP PUBLIC KEY BLOCK-----'.freeze + KEY_PREFIX = '-----BEGIN PGP PUBLIC KEY BLOCK-----' + KEY_SUFFIX = '-----END PGP PUBLIC KEY BLOCK-----' include ShaAttribute diff --git a/app/models/instance_configuration.rb b/app/models/instance_configuration.rb index a9b1962f24c..f401c23e453 100644 --- a/app/models/instance_configuration.rb +++ b/app/models/instance_configuration.rb @@ -4,8 +4,8 @@ require 'resolv' class InstanceConfiguration SSH_ALGORITHMS = %w(DSA ECDSA ED25519 RSA).freeze - SSH_ALGORITHMS_PATH = '/etc/ssh/'.freeze - CACHE_KEY = 'instance_configuration'.freeze + SSH_ALGORITHMS_PATH = '/etc/ssh/' + CACHE_KEY = 'instance_configuration' EXPIRATION_TIME = 24.hours def settings diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb index 3d6f397e599..ed5832ff989 100644 --- a/app/models/members/group_member.rb +++ b/app/models/members/group_member.rb @@ -3,7 +3,7 @@ class GroupMember < Member include FromUnion - SOURCE_TYPE = 'Namespace'.freeze + SOURCE_TYPE = 'Namespace' belongs_to :group, foreign_key: 'source_id' diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb index c64e2669b6a..2bb5806cd21 100644 --- a/app/models/members/project_member.rb +++ b/app/models/members/project_member.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class ProjectMember < Member - SOURCE_TYPE = 'Project'.freeze + SOURCE_TYPE = 'Project' belongs_to :project, foreign_key: 'source_id' diff --git a/app/models/namespace/aggregation_schedule.rb b/app/models/namespace/aggregation_schedule.rb index 61a7eb4b576..ed61c807519 100644 --- a/app/models/namespace/aggregation_schedule.rb +++ b/app/models/namespace/aggregation_schedule.rb @@ -7,7 +7,7 @@ class Namespace::AggregationSchedule < ApplicationRecord self.primary_key = :namespace_id DEFAULT_LEASE_TIMEOUT = 1.5.hours.to_i - REDIS_SHARED_KEY = 'gitlab:update_namespace_statistics_delay'.freeze + REDIS_SHARED_KEY = 'gitlab:update_namespace_statistics_delay' belongs_to :namespace diff --git a/app/models/notification_reason.rb b/app/models/notification_reason.rb index 0a13487574f..6856d397413 100644 --- a/app/models/notification_reason.rb +++ b/app/models/notification_reason.rb @@ -3,9 +3,9 @@ # Holds reasons for a notification to have been sent as well as a priority list to select which reason to use # above the rest class NotificationReason - OWN_ACTIVITY = 'own_activity'.freeze - ASSIGNED = 'assigned'.freeze - MENTIONED = 'mentioned'.freeze + OWN_ACTIVITY = 'own_activity' + ASSIGNED = 'assigned' + MENTIONED = 'mentioned' # Priority list for selecting which reason to return in the notification REASON_PRIORITY = [ diff --git a/app/models/pages_domain.rb b/app/models/pages_domain.rb index 27c122d3559..12ce717efd7 100644 --- a/app/models/pages_domain.rb +++ b/app/models/pages_domain.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class PagesDomain < ApplicationRecord - VERIFICATION_KEY = 'gitlab-pages-verification-code'.freeze + VERIFICATION_KEY = 'gitlab-pages-verification-code' VERIFICATION_THRESHOLD = 3.days.freeze SSL_RENEWAL_THRESHOLD = 30.days.freeze diff --git a/app/models/project.rb b/app/models/project.rb index a6d203f1e72..17b52d0578e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -37,8 +37,8 @@ class Project < ApplicationRecord BoardLimitExceeded = Class.new(StandardError) - STATISTICS_ATTRIBUTE = 'repositories_count'.freeze - UNKNOWN_IMPORT_URL = 'http://unknown.git'.freeze + STATISTICS_ATTRIBUTE = 'repositories_count' + UNKNOWN_IMPORT_URL = 'http://unknown.git' # Hashed Storage versions handle rolling out new storage to project and dependents models: # nil: legacy # 1: repository diff --git a/app/models/project_services/buildkite_service.rb b/app/models/project_services/buildkite_service.rb index 43edfde851c..d058904dd9e 100644 --- a/app/models/project_services/buildkite_service.rb +++ b/app/models/project_services/buildkite_service.rb @@ -5,7 +5,7 @@ require "addressable/uri" class BuildkiteService < CiService include ReactiveService - ENDPOINT = "https://buildkite.com".freeze + ENDPOINT = "https://buildkite.com" prop_accessor :project_url, :token boolean_accessor :enable_ssl_verification diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb index c15993bdc06..d3fff100964 100644 --- a/app/models/project_services/pivotaltracker_service.rb +++ b/app/models/project_services/pivotaltracker_service.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class PivotaltrackerService < Service - API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits'.freeze + API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits' prop_accessor :token, :restrict_to_branch validates :token, presence: true, if: :activated? diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb index 0d35bab7f80..7324890551c 100644 --- a/app/models/project_services/pushover_service.rb +++ b/app/models/project_services/pushover_service.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class PushoverService < Service - BASE_URI = 'https://api.pushover.net/1'.freeze + BASE_URI = 'https://api.pushover.net/1' prop_accessor :api_key, :user_key, :device, :priority, :sound validates :api_key, :user_key, :priority, presence: true, if: :activated? diff --git a/app/models/project_services/slash_commands_service.rb b/app/models/project_services/slash_commands_service.rb index cb16ad75d14..5bfd06476f0 100644 --- a/app/models/project_services/slash_commands_service.rb +++ b/app/models/project_services/slash_commands_service.rb @@ -35,7 +35,9 @@ class SlashCommandsService < Service chat_user = find_chat_user(params) if chat_user&.user - return Gitlab::SlashCommands::Presenters::Access.new.access_denied unless chat_user.user.can?(:use_slash_commands) + unless chat_user.user.can?(:use_slash_commands) + return Gitlab::SlashCommands::Presenters::Access.new.access_denied(project) + end Gitlab::SlashCommands::Command.new(project, chat_user, params).execute else diff --git a/app/models/repository.rb b/app/models/repository.rb index 6f63cd32da4..7882b2b3036 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -3,9 +3,9 @@ require 'securerandom' class Repository - REF_MERGE_REQUEST = 'merge-requests'.freeze - REF_KEEP_AROUND = 'keep-around'.freeze - REF_ENVIRONMENTS = 'environments'.freeze + REF_MERGE_REQUEST = 'merge-requests' + REF_KEEP_AROUND = 'keep-around' + REF_ENVIRONMENTS = 'environments' ARCHIVE_CACHE_TIME = 60 # Cache archives referred to by a (mutable) ref for 1 minute ARCHIVE_CACHE_TIME_IMMUTABLE = 3600 # Cache archives referred to by an immutable reference for 1 hour diff --git a/app/models/user.rb b/app/models/user.rb index 3ca84ba612a..67d730e2fa3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -59,7 +59,7 @@ class User < ApplicationRecord :validatable, :omniauthable, :confirmable, :registerable BLOCKED_MESSAGE = "Your account has been blocked. Please contact your GitLab " \ - "administrator if you think this is an error.".freeze + "administrator if you think this is an error." # Override Devise::Models::Trackable#update_tracked_fields! # to limit database writes to at most once every hour @@ -494,7 +494,7 @@ class User < ApplicationRecord def by_login(login) return unless login - if login.include?('@'.freeze) + if login.include?('@') unscoped.iwhere(email: login).take else unscoped.iwhere(username: login).take diff --git a/app/models/user_status.rb b/app/models/user_status.rb index 6ced4f56823..016b89bae81 100644 --- a/app/models/user_status.rb +++ b/app/models/user_status.rb @@ -5,7 +5,7 @@ class UserStatus < ApplicationRecord self.primary_key = :user_id - DEFAULT_EMOJI = 'speech_balloon'.freeze + DEFAULT_EMOJI = 'speech_balloon' belongs_to :user diff --git a/app/services/clusters/create_service.rb b/app/services/clusters/create_service.rb index e5a5b73321a..bbbeb4b30e4 100644 --- a/app/services/clusters/create_service.rb +++ b/app/services/clusters/create_service.rb @@ -37,7 +37,7 @@ module Clusters end def global_params - { user: current_user, namespace_per_environment: Feature.enabled?(:kubernetes_namespace_per_environment, default_enabled: true) } + { user: current_user } end def clusterable_params diff --git a/app/services/clusters/gcp/finalize_creation_service.rb b/app/services/clusters/gcp/finalize_creation_service.rb index 2f3c1df7651..c5cde831964 100644 --- a/app/services/clusters/gcp/finalize_creation_service.rb +++ b/app/services/clusters/gcp/finalize_creation_service.rb @@ -26,7 +26,7 @@ module Clusters private def create_gitlab_service_account! - Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService.gitlab_creator( + Clusters::Kubernetes::CreateOrUpdateServiceAccountService.gitlab_creator( kube_client, rbac: create_rbac_cluster? ).execute @@ -49,10 +49,10 @@ module Clusters end def request_kubernetes_token - Clusters::Gcp::Kubernetes::FetchKubernetesTokenService.new( + Clusters::Kubernetes::FetchKubernetesTokenService.new( kube_client, - Clusters::Gcp::Kubernetes::GITLAB_ADMIN_TOKEN_NAME, - Clusters::Gcp::Kubernetes::GITLAB_SERVICE_ACCOUNT_NAMESPACE + Clusters::Kubernetes::GITLAB_ADMIN_TOKEN_NAME, + Clusters::Kubernetes::GITLAB_SERVICE_ACCOUNT_NAMESPACE ).execute end diff --git a/app/services/clusters/gcp/kubernetes.rb b/app/services/clusters/gcp/kubernetes.rb deleted file mode 100644 index 85711764785..00000000000 --- a/app/services/clusters/gcp/kubernetes.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Clusters - module Gcp - module Kubernetes - GITLAB_SERVICE_ACCOUNT_NAME = 'gitlab' - GITLAB_SERVICE_ACCOUNT_NAMESPACE = 'default' - GITLAB_ADMIN_TOKEN_NAME = 'gitlab-token' - GITLAB_CLUSTER_ROLE_BINDING_NAME = 'gitlab-admin' - GITLAB_CLUSTER_ROLE_NAME = 'cluster-admin' - PROJECT_CLUSTER_ROLE_NAME = 'edit' - GITLAB_KNATIVE_SERVING_ROLE_NAME = 'gitlab-knative-serving-role' - GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME = 'gitlab-knative-serving-rolebinding' - end - end -end diff --git a/app/services/clusters/gcp/kubernetes/create_or_update_namespace_service.rb b/app/services/clusters/gcp/kubernetes/create_or_update_namespace_service.rb deleted file mode 100644 index c45dac7b273..00000000000 --- a/app/services/clusters/gcp/kubernetes/create_or_update_namespace_service.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -module Clusters - module Gcp - module Kubernetes - class CreateOrUpdateNamespaceService - def initialize(cluster:, kubernetes_namespace:) - @cluster = cluster - @kubernetes_namespace = kubernetes_namespace - @platform = cluster.platform - end - - def execute - create_project_service_account - configure_kubernetes_token - - kubernetes_namespace.save! - end - - private - - attr_reader :cluster, :kubernetes_namespace, :platform - - def create_project_service_account - Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService.namespace_creator( - platform.kubeclient, - service_account_name: kubernetes_namespace.service_account_name, - service_account_namespace: kubernetes_namespace.namespace, - rbac: platform.rbac? - ).execute - end - - def configure_kubernetes_token - kubernetes_namespace.service_account_token = fetch_service_account_token - end - - def fetch_service_account_token - Clusters::Gcp::Kubernetes::FetchKubernetesTokenService.new( - platform.kubeclient, - kubernetes_namespace.token_name, - kubernetes_namespace.namespace - ).execute - end - end - end - end -end diff --git a/app/services/clusters/gcp/kubernetes/create_or_update_service_account_service.rb b/app/services/clusters/gcp/kubernetes/create_or_update_service_account_service.rb deleted file mode 100644 index 7c5450dbcd6..00000000000 --- a/app/services/clusters/gcp/kubernetes/create_or_update_service_account_service.rb +++ /dev/null @@ -1,141 +0,0 @@ -# frozen_string_literal: true - -module Clusters - module Gcp - module Kubernetes - class CreateOrUpdateServiceAccountService - def initialize(kubeclient, service_account_name:, service_account_namespace:, token_name:, rbac:, namespace_creator: false, role_binding_name: nil) - @kubeclient = kubeclient - @service_account_name = service_account_name - @service_account_namespace = service_account_namespace - @token_name = token_name - @rbac = rbac - @namespace_creator = namespace_creator - @role_binding_name = role_binding_name - end - - def self.gitlab_creator(kubeclient, rbac:) - self.new( - kubeclient, - service_account_name: Clusters::Gcp::Kubernetes::GITLAB_SERVICE_ACCOUNT_NAME, - service_account_namespace: Clusters::Gcp::Kubernetes::GITLAB_SERVICE_ACCOUNT_NAMESPACE, - token_name: Clusters::Gcp::Kubernetes::GITLAB_ADMIN_TOKEN_NAME, - rbac: rbac - ) - end - - def self.namespace_creator(kubeclient, service_account_name:, service_account_namespace:, rbac:) - self.new( - kubeclient, - service_account_name: service_account_name, - service_account_namespace: service_account_namespace, - token_name: "#{service_account_namespace}-token", - rbac: rbac, - namespace_creator: true, - role_binding_name: "gitlab-#{service_account_namespace}" - ) - end - - def execute - ensure_project_namespace_exists if namespace_creator - - kubeclient.create_or_update_service_account(service_account_resource) - kubeclient.create_or_update_secret(service_account_token_resource) - - return unless rbac - - create_role_or_cluster_role_binding - - return unless namespace_creator - - create_or_update_knative_serving_role - create_or_update_knative_serving_role_binding - end - - private - - attr_reader :kubeclient, :service_account_name, :service_account_namespace, :token_name, :rbac, :namespace_creator, :role_binding_name - - def ensure_project_namespace_exists - Gitlab::Kubernetes::Namespace.new( - service_account_namespace, - kubeclient - ).ensure_exists! - end - - def create_role_or_cluster_role_binding - if namespace_creator - kubeclient.create_or_update_role_binding(role_binding_resource) - else - kubeclient.create_or_update_cluster_role_binding(cluster_role_binding_resource) - end - end - - def create_or_update_knative_serving_role - kubeclient.update_role(knative_serving_role_resource) - end - - def create_or_update_knative_serving_role_binding - kubeclient.update_role_binding(knative_serving_role_binding_resource) - end - - def service_account_resource - Gitlab::Kubernetes::ServiceAccount.new( - service_account_name, - service_account_namespace - ).generate - end - - def service_account_token_resource - Gitlab::Kubernetes::ServiceAccountToken.new( - token_name, - service_account_name, - service_account_namespace - ).generate - end - - def cluster_role_binding_resource - subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: service_account_namespace }] - - Gitlab::Kubernetes::ClusterRoleBinding.new( - Clusters::Gcp::Kubernetes::GITLAB_CLUSTER_ROLE_BINDING_NAME, - Clusters::Gcp::Kubernetes::GITLAB_CLUSTER_ROLE_NAME, - subjects - ).generate - end - - def role_binding_resource - Gitlab::Kubernetes::RoleBinding.new( - name: role_binding_name, - role_name: Clusters::Gcp::Kubernetes::PROJECT_CLUSTER_ROLE_NAME, - role_kind: :ClusterRole, - namespace: service_account_namespace, - service_account_name: service_account_name - ).generate - end - - def knative_serving_role_resource - Gitlab::Kubernetes::Role.new( - name: Clusters::Gcp::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, - namespace: service_account_namespace, - rules: [{ - apiGroups: %w(serving.knative.dev), - resources: %w(configurations configurationgenerations routes revisions revisionuids autoscalers services), - verbs: %w(get list create update delete patch watch) - }] - ).generate - end - - def knative_serving_role_binding_resource - Gitlab::Kubernetes::RoleBinding.new( - name: Clusters::Gcp::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME, - role_name: Clusters::Gcp::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, - role_kind: :Role, - namespace: service_account_namespace, - service_account_name: service_account_name - ).generate - end - end - end - end -end diff --git a/app/services/clusters/gcp/kubernetes/fetch_kubernetes_token_service.rb b/app/services/clusters/gcp/kubernetes/fetch_kubernetes_token_service.rb deleted file mode 100644 index 5d9bdc52d37..00000000000 --- a/app/services/clusters/gcp/kubernetes/fetch_kubernetes_token_service.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -module Clusters - module Gcp - module Kubernetes - class FetchKubernetesTokenService - DEFAULT_TOKEN_RETRY_DELAY = 5.seconds - TOKEN_RETRY_LIMIT = 5 - - attr_reader :kubeclient, :service_account_token_name, :namespace - - def initialize(kubeclient, service_account_token_name, namespace, token_retry_delay: DEFAULT_TOKEN_RETRY_DELAY) - @kubeclient = kubeclient - @service_account_token_name = service_account_token_name - @namespace = namespace - @token_retry_delay = token_retry_delay - end - - def execute - # Kubernetes will create the Secret and set the token asynchronously - # so it is necessary to retry - # https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#token-controller - TOKEN_RETRY_LIMIT.times do - token_base64 = get_secret&.dig('data', 'token') - return Base64.decode64(token_base64) if token_base64 - - sleep @token_retry_delay - end - - nil - end - - private - - def get_secret - kubeclient.get_secret(service_account_token_name, namespace).as_json - rescue Kubeclient::ResourceNotFoundError - end - end - end - end -end diff --git a/app/services/clusters/kubernetes/create_or_update_namespace_service.rb b/app/services/clusters/kubernetes/create_or_update_namespace_service.rb new file mode 100644 index 00000000000..15be8446cc0 --- /dev/null +++ b/app/services/clusters/kubernetes/create_or_update_namespace_service.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Clusters + module Kubernetes + class CreateOrUpdateNamespaceService + def initialize(cluster:, kubernetes_namespace:) + @cluster = cluster + @kubernetes_namespace = kubernetes_namespace + @platform = cluster.platform + end + + def execute + create_project_service_account + configure_kubernetes_token + + kubernetes_namespace.save! + end + + private + + attr_reader :cluster, :kubernetes_namespace, :platform + + def create_project_service_account + Clusters::Kubernetes::CreateOrUpdateServiceAccountService.namespace_creator( + platform.kubeclient, + service_account_name: kubernetes_namespace.service_account_name, + service_account_namespace: kubernetes_namespace.namespace, + rbac: platform.rbac? + ).execute + end + + def configure_kubernetes_token + kubernetes_namespace.service_account_token = fetch_service_account_token + end + + def fetch_service_account_token + Clusters::Kubernetes::FetchKubernetesTokenService.new( + platform.kubeclient, + kubernetes_namespace.token_name, + kubernetes_namespace.namespace + ).execute + end + end + 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 new file mode 100644 index 00000000000..8b8ad924b64 --- /dev/null +++ b/app/services/clusters/kubernetes/create_or_update_service_account_service.rb @@ -0,0 +1,139 @@ +# frozen_string_literal: true + +module Clusters + module Kubernetes + class CreateOrUpdateServiceAccountService + def initialize(kubeclient, service_account_name:, service_account_namespace:, token_name:, rbac:, namespace_creator: false, role_binding_name: nil) + @kubeclient = kubeclient + @service_account_name = service_account_name + @service_account_namespace = service_account_namespace + @token_name = token_name + @rbac = rbac + @namespace_creator = namespace_creator + @role_binding_name = role_binding_name + end + + def self.gitlab_creator(kubeclient, rbac:) + self.new( + kubeclient, + service_account_name: Clusters::Kubernetes::GITLAB_SERVICE_ACCOUNT_NAME, + service_account_namespace: Clusters::Kubernetes::GITLAB_SERVICE_ACCOUNT_NAMESPACE, + token_name: Clusters::Kubernetes::GITLAB_ADMIN_TOKEN_NAME, + rbac: rbac + ) + end + + def self.namespace_creator(kubeclient, service_account_name:, service_account_namespace:, rbac:) + self.new( + kubeclient, + service_account_name: service_account_name, + service_account_namespace: service_account_namespace, + token_name: "#{service_account_namespace}-token", + rbac: rbac, + namespace_creator: true, + role_binding_name: "gitlab-#{service_account_namespace}" + ) + end + + def execute + ensure_project_namespace_exists if namespace_creator + + kubeclient.create_or_update_service_account(service_account_resource) + kubeclient.create_or_update_secret(service_account_token_resource) + + return unless rbac + + create_role_or_cluster_role_binding + + return unless namespace_creator + + create_or_update_knative_serving_role + create_or_update_knative_serving_role_binding + end + + private + + attr_reader :kubeclient, :service_account_name, :service_account_namespace, :token_name, :rbac, :namespace_creator, :role_binding_name + + def ensure_project_namespace_exists + Gitlab::Kubernetes::Namespace.new( + service_account_namespace, + kubeclient + ).ensure_exists! + end + + def create_role_or_cluster_role_binding + if namespace_creator + kubeclient.create_or_update_role_binding(role_binding_resource) + else + kubeclient.create_or_update_cluster_role_binding(cluster_role_binding_resource) + end + end + + def create_or_update_knative_serving_role + kubeclient.update_role(knative_serving_role_resource) + end + + def create_or_update_knative_serving_role_binding + kubeclient.update_role_binding(knative_serving_role_binding_resource) + end + + def service_account_resource + Gitlab::Kubernetes::ServiceAccount.new( + service_account_name, + service_account_namespace + ).generate + end + + def service_account_token_resource + Gitlab::Kubernetes::ServiceAccountToken.new( + token_name, + service_account_name, + service_account_namespace + ).generate + end + + def cluster_role_binding_resource + subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: service_account_namespace }] + + Gitlab::Kubernetes::ClusterRoleBinding.new( + Clusters::Kubernetes::GITLAB_CLUSTER_ROLE_BINDING_NAME, + Clusters::Kubernetes::GITLAB_CLUSTER_ROLE_NAME, + subjects + ).generate + end + + def role_binding_resource + Gitlab::Kubernetes::RoleBinding.new( + name: role_binding_name, + role_name: Clusters::Kubernetes::PROJECT_CLUSTER_ROLE_NAME, + role_kind: :ClusterRole, + namespace: service_account_namespace, + service_account_name: service_account_name + ).generate + end + + def knative_serving_role_resource + Gitlab::Kubernetes::Role.new( + name: Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, + namespace: service_account_namespace, + rules: [{ + apiGroups: %w(serving.knative.dev), + resources: %w(configurations configurationgenerations routes revisions revisionuids autoscalers services), + verbs: %w(get list create update delete patch watch) + }] + ).generate + end + + def knative_serving_role_binding_resource + Gitlab::Kubernetes::RoleBinding.new( + name: Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME, + role_name: Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, + role_kind: :Role, + namespace: service_account_namespace, + service_account_name: service_account_name + ).generate + end + end + end +end diff --git a/app/services/clusters/kubernetes/fetch_kubernetes_token_service.rb b/app/services/clusters/kubernetes/fetch_kubernetes_token_service.rb new file mode 100644 index 00000000000..aaf437abfad --- /dev/null +++ b/app/services/clusters/kubernetes/fetch_kubernetes_token_service.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module Clusters + module Kubernetes + class FetchKubernetesTokenService + DEFAULT_TOKEN_RETRY_DELAY = 5.seconds + TOKEN_RETRY_LIMIT = 5 + + attr_reader :kubeclient, :service_account_token_name, :namespace + + def initialize(kubeclient, service_account_token_name, namespace, token_retry_delay: DEFAULT_TOKEN_RETRY_DELAY) + @kubeclient = kubeclient + @service_account_token_name = service_account_token_name + @namespace = namespace + @token_retry_delay = token_retry_delay + end + + def execute + # Kubernetes will create the Secret and set the token asynchronously + # so it is necessary to retry + # https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#token-controller + TOKEN_RETRY_LIMIT.times do + token_base64 = get_secret&.dig('data', 'token') + return Base64.decode64(token_base64) if token_base64 + + sleep @token_retry_delay + end + + nil + end + + private + + def get_secret + kubeclient.get_secret(service_account_token_name, namespace).as_json + rescue Kubeclient::ResourceNotFoundError + end + end + end +end diff --git a/app/services/clusters/kubernetes/kubernetes.rb b/app/services/clusters/kubernetes/kubernetes.rb new file mode 100644 index 00000000000..7d5d0c2c1d6 --- /dev/null +++ b/app/services/clusters/kubernetes/kubernetes.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Clusters + module Kubernetes + GITLAB_SERVICE_ACCOUNT_NAME = 'gitlab' + GITLAB_SERVICE_ACCOUNT_NAMESPACE = 'default' + GITLAB_ADMIN_TOKEN_NAME = 'gitlab-token' + GITLAB_CLUSTER_ROLE_BINDING_NAME = 'gitlab-admin' + GITLAB_CLUSTER_ROLE_NAME = 'cluster-admin' + PROJECT_CLUSTER_ROLE_NAME = 'edit' + GITLAB_KNATIVE_SERVING_ROLE_NAME = 'gitlab-knative-serving-role' + GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME = 'gitlab-knative-serving-rolebinding' + end +end diff --git a/changelogs/unreleased/improve-chatops-help.yml b/changelogs/unreleased/improve-chatops-help.yml new file mode 100644 index 00000000000..77e6f2e5308 --- /dev/null +++ b/changelogs/unreleased/improve-chatops-help.yml @@ -0,0 +1,5 @@ +--- +title: Improve chatops help output +merge_request: 32208 +author: +type: changed diff --git a/changelogs/unreleased/sh-fix-ci-lint-500-error.yml b/changelogs/unreleased/sh-fix-ci-lint-500-error.yml new file mode 100644 index 00000000000..74d9f980d46 --- /dev/null +++ b/changelogs/unreleased/sh-fix-ci-lint-500-error.yml @@ -0,0 +1,5 @@ +--- +title: Fix 500 error in CI lint when included templates are an array +merge_request: 32232 +author: +type: fixed diff --git a/doc/api/applications.md b/doc/api/applications.md index 82955f0c1db..807a0e57e8b 100644 --- a/doc/api/applications.md +++ b/doc/api/applications.md @@ -88,7 +88,9 @@ DELETE /applications/:id Parameters: -- `id` (required) - The id of the application (not the application_id) +| Attribute | Type | Required | Description | +|:----------|:--------|:---------|:----------------------------------------------------| +| `id` | integer | yes | The id of the application (not the application_id). | Example request: diff --git a/doc/api/releases/index.md b/doc/api/releases/index.md index e74b35fd959..850cf57a06f 100644 --- a/doc/api/releases/index.md +++ b/doc/api/releases/index.md @@ -12,14 +12,14 @@ Paginated list of Releases, sorted by `released_at`. GET /projects/:id/releases ``` -| Attribute | Type | Required | Description | -| ------------- | -------------- | -------- | --------------------------------------- | +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | ----------------------------------------------------------------------------------- | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). | Example request: ```sh -curl --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases" +curl --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "https://gitlab.example.com/api/v4/projects/24/releases" ``` Example response: @@ -39,7 +39,7 @@ Example response: "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", - "web_url":"http://localhost:3000/root" + "web_url":"https://gitlab.example.com/root" }, "commit":{ "id":"079e90101242458910cccd35eab0e211dfc359c0", @@ -62,19 +62,19 @@ Example response: "sources":[ { "format":"zip", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.zip" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.zip" }, { "format":"tar.gz", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar.gz" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar.gz" }, { "format":"tar.bz2", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar.bz2" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar.bz2" }, { "format":"tar", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.2/awesome-app-v0.2.tar" } ], "links":[ @@ -106,7 +106,7 @@ Example response: "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", - "web_url":"http://localhost:3000/root" + "web_url":"https://gitlab.example.com/root" }, "commit":{ "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", @@ -129,19 +129,19 @@ Example response: "sources":[ { "format":"zip", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" }, { "format":"tar.gz", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" }, { "format":"tar.bz2", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" }, { "format":"tar", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" } ], "links":[ @@ -160,15 +160,15 @@ Get a Release for the given tag. GET /projects/:id/releases/:tag_name ``` -| Attribute | Type | Required | Description | -| ------------- | -------------- | -------- | --------------------------------------- | +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | ----------------------------------------------------------------------------------- | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). | -| `tag_name` | string | yes | The tag where the release will be created from. | +| `tag_name` | string | yes | The tag where the release will be created from. | Example request: ```sh -curl --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases/v0.1" +curl --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "https://gitlab.example.com/api/v4/projects/24/releases/v0.1" ``` Example response: @@ -187,7 +187,7 @@ Example response: "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", - "web_url":"http://localhost:3000/root" + "web_url":"https://gitlab.example.com/root" }, "commit":{ "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", @@ -210,19 +210,19 @@ Example response: "sources":[ { "format":"zip", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" }, { "format":"tar.gz", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" }, { "format":"tar.bz2", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" }, { "format":"tar", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" } ], "links":[ @@ -240,24 +240,24 @@ Create a Release. You need push access to the repository to create a Release. POST /projects/:id/releases ``` -| Attribute | Type | Required | Description | -| ------------- | -------------- | -------- | --------------------------------------- | -| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). | -| `name` | string | yes | The release name. | -| `tag_name` | string | yes | The tag where the release will be created from. | -| `description` | string | yes | The description of the release. You can use [markdown](../../user/markdown.md). | -| `ref` | string | no | If `tag_name` doesn't exist, the release will be created from `ref`. It can be a commit SHA, another tag name, or a branch name. | -| `assets:links`| array of hash | no | An array of assets links. | -| `assets:links:name`| string | no (if `assets:links` specified, it's required) | The name of the link. | -| `assets:links:url`| string | no (if `assets:links` specified, it's required) | The url of the link. | -| `released_at` | datetime | no | The date when the release will be/was ready. Defaults to the current time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | +| Attribute | Type | Required | Description | +| -------------------| -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). | +| `name` | string | yes | The release name. | +| `tag_name` | string | yes | The tag where the release will be created from. | +| `description` | string | yes | The description of the release. You can use [markdown](../../user/markdown.md). | +| `ref` | string | no | If `tag_name` doesn't exist, the release will be created from `ref`. It can be a commit SHA, another tag name, or a branch name. | +| `assets:links` | array of hash | no | An array of assets links. | +| `assets:links:name`| string | required by: `assets:links` | The name of the link. | +| `assets:links:url` | string | required by: `assets:links` | The url of the link. | +| `released_at` | datetime | no | The date when the release will be/was ready. Defaults to the current time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | Example request: ```sh curl --header 'Content-Type: application/json' --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" \ --data '{ "name": "New release", "tag_name": "v0.3", "description": "Super nice release", "assets": { "links": [{ "name": "hoge", "url": "https://google.com" }] } }' \ - --request POST http://localhost:3000/api/v4/projects/24/releases + --request POST https://gitlab.example.com/api/v4/projects/24/releases ``` Example response: @@ -276,7 +276,7 @@ Example response: "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", - "web_url":"http://localhost:3000/root" + "web_url":"https://gitlab.example.com/root" }, "commit":{ "id":"079e90101242458910cccd35eab0e211dfc359c0", @@ -299,19 +299,19 @@ Example response: "sources":[ { "format":"zip", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.zip" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.zip" }, { "format":"tar.gz", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar.gz" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar.gz" }, { "format":"tar.bz2", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar.bz2" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar.bz2" }, { "format":"tar", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.3/awesome-app-v0.3.tar" } ], "links":[ @@ -334,18 +334,18 @@ Update a Release. PUT /projects/:id/releases/:tag_name ``` -| Attribute | Type | Required | Description | -| ------------- | -------------- | -------- | --------------------------------------- | -| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). | -| `tag_name` | string | yes | The tag where the release will be created from. | -| `name` | string | no | The release name. | -| `description` | string | no | The description of the release. You can use [markdown](../../user/markdown.md). | +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | -------------------------------------------------------------------------------------------------- | +| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). | +| `tag_name` | string | yes | The tag where the release will be created from. | +| `name` | string | no | The release name. | +| `description` | string | no | The description of the release. You can use [markdown](../../user/markdown.md). | | `released_at` | datetime | no | The date when the release will be/was ready. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). | Example request: ```sh -curl --request PUT --data name="new name" --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases/v0.1" +curl --request PUT --data name="new name" --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "https://gitlab.example.com/api/v4/projects/24/releases/v0.1" ``` Example response: @@ -364,7 +364,7 @@ Example response: "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", - "web_url":"http://localhost:3000/root" + "web_url":"https://gitlab.example.com/root" }, "commit":{ "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", @@ -387,19 +387,19 @@ Example response: "sources":[ { "format":"zip", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" }, { "format":"tar.gz", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" }, { "format":"tar.bz2", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" }, { "format":"tar", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" } ], "links":[ @@ -417,15 +417,15 @@ Delete a Release. Deleting a Release will not delete the associated tag. DELETE /projects/:id/releases/:tag_name ``` -| Attribute | Type | Required | Description | -| ------------- | -------------- | -------- | --------------------------------------- | +| Attribute | Type | Required | Description | +| ------------- | -------------- | -------- | ----------------------------------------------------------------------------------- | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). | -| `tag_name` | string | yes | The tag where the release will be created from. | +| `tag_name` | string | yes | The tag where the release will be created from. | Example request: ```sh -curl --request DELETE --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "http://localhost:3000/api/v4/projects/24/releases/v0.1" +curl --request DELETE --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" "https://gitlab.example.com/api/v4/projects/24/releases/v0.1" ``` Example response: @@ -444,7 +444,7 @@ Example response: "username":"root", "state":"active", "avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", - "web_url":"http://localhost:3000/root" + "web_url":"https://gitlab.example.com/root" }, "commit":{ "id":"f8d3d94cbd347e924aa7b715845e439d00e80ca4", @@ -467,19 +467,19 @@ Example response: "sources":[ { "format":"zip", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.zip" }, { "format":"tar.gz", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.gz" }, { "format":"tar.bz2", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar.bz2" }, { "format":"tar", - "url":"http://localhost:3000/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" + "url":"https://gitlab.example.com/root/awesome-app/-/archive/v0.1/awesome-app-v0.1.tar" } ], "links":[ diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md index 7c173970324..730e46f994e 100644 --- a/doc/ci/docker/using_docker_build.md +++ b/doc/ci/docker/using_docker_build.md @@ -603,7 +603,7 @@ Below is an example of how your `.gitlab-ci.yml` should look like, assuming you - docker run my-docker-image /script/to/run/tests ``` -If you forget to set the service alias the `docker:19.03.1` image won't find the +If you forget to set the service alias the `docker:19.03.1` image won't find the `dind` service, and an error like the following is thrown: ```sh diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 38276de6791..10255f768e6 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -2171,6 +2171,14 @@ include: - template: Auto-DevOps.gitlab-ci.yml ``` +Multiple `include:template` files: + +```yaml +include: + - template: Android-Fastlane.gitlab-ci.yml + - template: Auto-DevOps.gitlab-ci.yml +``` + All [nested includes](#nested-includes) will be executed only with the permission of the user, so it is possible to use project, remote or template includes. diff --git a/doc/user/admin_area/settings/account_and_limit_settings.md b/doc/user/admin_area/settings/account_and_limit_settings.md index 5e385b7216d..20691210fbd 100644 --- a/doc/user/admin_area/settings/account_and_limit_settings.md +++ b/doc/user/admin_area/settings/account_and_limit_settings.md @@ -44,12 +44,19 @@ there are no restrictions. These settings can be found within: -- Each project's settings. -- A group's settings. -- The **Size limit per repository (MB)** field in the **Account and limit** section of a GitLab instance's - settings by navigating to either: - - **Admin Area > Settings > General**. - - The path `/admin/application_settings`. +- Each project's settings: + 1. From the Project's homepage, navigate to **Settings > General**. + 1. Fill in the **Repository size limit (MB)** field in the **Naming, topics, avatar** section. + 1. Click **Save changes**. +- Each group's settings: + 1. From the Group's homepage, navigate to **Settings > General**. + 1. Fill in the **Repository size limit (MB)** field in the **Naming, visibility** section. + 1. Click **Save changes**. +- GitLab's global settings: + 1. From the Dashboard, navigate to **Admin Area > Settings > General**. + 1. Expand the **Account and limit** section. + 1. Fill in the **Size limit per repository (MB)** field. + 1. Click **Save changes**. The first push of a new project, including LFS objects, will be checked for size and **will** be rejected if the sum of their sizes exceeds the maximum allowed diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md index ca9450f94b9..2f2955f5a1c 100644 --- a/doc/user/gitlab_com/index.md +++ b/doc/user/gitlab_com/index.md @@ -334,7 +334,7 @@ No response headers are provided. GitLab.com: - Has [rate limits on raw endpoints](../../user/admin_area/settings/rate_limits_on_raw_endpoints.md) - set to the default. + set to the default. - Does not have the user and IP rate limits settings enabled. ## GitLab.com at scale diff --git a/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb b/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb index 6ab4fca3854..f448d55f00a 100644 --- a/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb +++ b/lib/gitlab/ci/build/prerequisite/kubernetes_namespace.rb @@ -43,7 +43,7 @@ module Gitlab end def create_namespace - Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService.new( + Clusters::Kubernetes::CreateOrUpdateNamespaceService.new( cluster: deployment_cluster, kubernetes_namespace: kubernetes_namespace || build_namespace_record ).execute diff --git a/lib/gitlab/ci/config/external/file/base.rb b/lib/gitlab/ci/config/external/file/base.rb index 2ffbb214a92..c56d33544ba 100644 --- a/lib/gitlab/ci/config/external/file/base.rb +++ b/lib/gitlab/ci/config/external/file/base.rb @@ -26,6 +26,10 @@ module Gitlab location.present? end + def invalid_location_type? + !location.is_a?(String) + end + def invalid_extension? location.nil? || !::File.basename(location).match?(YAML_WHITELIST_EXTENSION) end @@ -71,7 +75,9 @@ module Gitlab end def validate_location! - if invalid_extension? + if invalid_location_type? + errors.push("Included file `#{location}` needs to be a string") + elsif invalid_extension? errors.push("Included file `#{location}` does not have YAML extension!") end end diff --git a/lib/gitlab/slash_commands/application_help.rb b/lib/gitlab/slash_commands/application_help.rb index 0ea7554ba64..1a92346be15 100644 --- a/lib/gitlab/slash_commands/application_help.rb +++ b/lib/gitlab/slash_commands/application_help.rb @@ -3,12 +3,15 @@ module Gitlab module SlashCommands class ApplicationHelp < BaseCommand - def initialize(params) + def initialize(project, params) + @project = project @params = params end def execute - Gitlab::SlashCommands::Presenters::Help.new(commands).present(trigger, params[:text]) + Gitlab::SlashCommands::Presenters::Help + .new(project, commands) + .present(trigger, params[:text]) end private diff --git a/lib/gitlab/slash_commands/command.rb b/lib/gitlab/slash_commands/command.rb index 905e0ec5cc1..079b5916566 100644 --- a/lib/gitlab/slash_commands/command.rb +++ b/lib/gitlab/slash_commands/command.rb @@ -22,7 +22,7 @@ module Gitlab if command.allowed?(project, current_user) command.new(project, chat_name, params).execute(match) else - Gitlab::SlashCommands::Presenters::Access.new.access_denied + Gitlab::SlashCommands::Presenters::Access.new.access_denied(project) end else Gitlab::SlashCommands::Help.new(project, chat_name, params) diff --git a/lib/gitlab/slash_commands/help.rb b/lib/gitlab/slash_commands/help.rb index dbe15baa3d7..3eff64192ab 100644 --- a/lib/gitlab/slash_commands/help.rb +++ b/lib/gitlab/slash_commands/help.rb @@ -19,7 +19,9 @@ module Gitlab end def execute(commands, text) - Gitlab::SlashCommands::Presenters::Help.new(commands).present(trigger, text) + Gitlab::SlashCommands::Presenters::Help + .new(project, commands) + .present(trigger, text) end def trigger diff --git a/lib/gitlab/slash_commands/presenters/access.rb b/lib/gitlab/slash_commands/presenters/access.rb index fa163cb098e..b1bfaa6cb59 100644 --- a/lib/gitlab/slash_commands/presenters/access.rb +++ b/lib/gitlab/slash_commands/presenters/access.rb @@ -4,8 +4,15 @@ module Gitlab module SlashCommands module Presenters class Access < Presenters::Base - def access_denied - ephemeral_response(text: "Whoops! This action is not allowed. This incident will be [reported](https://xkcd.com/838/).") + def access_denied(project) + ephemeral_response(text: <<~MESSAGE) + You are not allowed to perform the given chatops command. Most + likely you do not have access to the GitLab project for this chatops + integration. + + The GitLab project for this chatops integration can be found at + #{url_for(project)}. + MESSAGE end def not_found @@ -22,20 +29,6 @@ module Gitlab ephemeral_response(text: message) end - - def unknown_command(commands) - ephemeral_response(text: help_message(trigger)) - end - - private - - def help_message(trigger) - header_with_list("Command not found, these are the commands you can use", full_commands(trigger)) - end - - def full_commands(trigger) - @resource.map { |command| "#{trigger} #{command.help_message}" } - end end end end diff --git a/lib/gitlab/slash_commands/presenters/help.rb b/lib/gitlab/slash_commands/presenters/help.rb index 480d7aa6a30..5421b0b9a84 100644 --- a/lib/gitlab/slash_commands/presenters/help.rb +++ b/lib/gitlab/slash_commands/presenters/help.rb @@ -4,6 +4,11 @@ module Gitlab module SlashCommands module Presenters class Help < Presenters::Base + def initialize(project, commands) + @project = project + @commands = commands + end + def present(trigger, text) ephemeral_response(text: help_message(trigger, text)) end @@ -11,17 +16,64 @@ module Gitlab private def help_message(trigger, text) - return "No commands available :thinking_face:" unless @resource.present? + unless @commands.present? + return <<~MESSAGE + This chatops integration does not have any commands that can be + executed. + + #{footer} + MESSAGE + end if text.start_with?('help') - header_with_list("Available commands", full_commands(trigger)) + <<~MESSAGE + #{full_commands_message(trigger)} + + #{help_footer} + MESSAGE else - header_with_list("Unknown command, these commands are available", full_commands(trigger)) + <<~MESSAGE + The specified command is not valid. + + #{full_commands_message(trigger)} + + #{help_footer} + MESSAGE end end - def full_commands(trigger) - @resource.map { |command| "#{trigger} #{command.help_message}" } + def help_footer + <<~MESSAGE + *Project* + + The GitLab project for this chatops integration can be found at + #{url_for(@project)}. + + *Documentation* + + For more information about GitLab chatops, refer to its + documentation: https://docs.gitlab.com/ce/ci/chatops/README.html. + MESSAGE + end + + def full_commands_message(trigger) + list = @commands + .map { |command| "#{trigger} #{command.help_message}" } + .join("\n") + + <<~MESSAGE + *Available commands* + + The following commands are available for this chatops integration: + + #{list} + + If available, the `run` command is used for running GitLab CI jobs + defined in this project's `.gitlab-ci.yml` file. For example, if a + job called "help" is defined you can run it like so: + + `#{trigger} run help` + MESSAGE end end end diff --git a/spec/features/groups/clusters/user_spec.rb b/spec/features/groups/clusters/user_spec.rb index 84a8691a7f2..8891866c1f8 100644 --- a/spec/features/groups/clusters/user_spec.rb +++ b/spec/features/groups/clusters/user_spec.rb @@ -13,7 +13,7 @@ describe 'User Cluster', :js do gitlab_sign_in(user) allow(Groups::ClustersController).to receive(:STATUS_POLLING_INTERVAL) { 100 } - allow_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute) + allow_any_instance_of(Clusters::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute) allow_any_instance_of(Clusters::Cluster).to receive(:retrieve_connection_status).and_return(:connected) end diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb index 3899aab8170..84f2e3e09ae 100644 --- a/spec/features/projects/clusters/user_spec.rb +++ b/spec/features/projects/clusters/user_spec.rb @@ -13,7 +13,7 @@ describe 'User Cluster', :js do gitlab_sign_in(user) allow(Projects::ClustersController).to receive(:STATUS_POLLING_INTERVAL) { 100 } - allow_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute) + allow_any_instance_of(Clusters::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute) allow_any_instance_of(Clusters::Cluster).to receive(:retrieve_connection_status).and_return(:connected) end 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 775550f2acc..c7a5ac783b3 100644 --- a/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb +++ b/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb @@ -87,7 +87,7 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do .with(cluster, environment: deployment.environment) .and_return(namespace_builder) - expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService) + expect(Clusters::Kubernetes::CreateOrUpdateNamespaceService) .to receive(:new) .with(cluster: cluster, kubernetes_namespace: kubernetes_namespace) .and_return(service) @@ -107,7 +107,7 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do it 'creates a namespace using the tokenless record' do expect(Clusters::BuildKubernetesNamespaceService).not_to receive(:new) - expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService) + expect(Clusters::Kubernetes::CreateOrUpdateNamespaceService) .to receive(:new) .with(cluster: cluster, kubernetes_namespace: kubernetes_namespace) .and_return(service) @@ -123,7 +123,7 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do end it 'does not create a namespace' do - expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).not_to receive(:new) + expect(Clusters::Kubernetes::CreateOrUpdateNamespaceService).not_to receive(:new) subject end diff --git a/spec/lib/gitlab/ci/config/external/file/base_spec.rb b/spec/lib/gitlab/ci/config/external/file/base_spec.rb index dd536a241bd..af995f4869a 100644 --- a/spec/lib/gitlab/ci/config/external/file/base_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/base_spec.rb @@ -41,6 +41,12 @@ describe Gitlab::Ci::Config::External::File::Base do end describe '#valid?' do + context 'when location is not a string' do + let(:location) { %w(some/file.txt other/file.txt) } + + it { is_expected.not_to be_valid } + end + context 'when location is not a YAML file' do let(:location) { 'some/file.txt' } diff --git a/spec/lib/gitlab/slash_commands/application_help_spec.rb b/spec/lib/gitlab/slash_commands/application_help_spec.rb index b203a1ee79c..afa63c21584 100644 --- a/spec/lib/gitlab/slash_commands/application_help_spec.rb +++ b/spec/lib/gitlab/slash_commands/application_help_spec.rb @@ -4,10 +4,11 @@ require 'spec_helper' describe Gitlab::SlashCommands::ApplicationHelp do let(:params) { { command: '/gitlab', text: 'help' } } + let(:project) { build(:project) } describe '#execute' do subject do - described_class.new(params).execute + described_class.new(project, params).execute end it 'displays the help section' do diff --git a/spec/lib/gitlab/slash_commands/command_spec.rb b/spec/lib/gitlab/slash_commands/command_spec.rb index c4ea8cbf2b1..dc412c80e68 100644 --- a/spec/lib/gitlab/slash_commands/command_spec.rb +++ b/spec/lib/gitlab/slash_commands/command_spec.rb @@ -27,7 +27,7 @@ describe Gitlab::SlashCommands::Command do it 'displays the help message' do expect(subject[:response_type]).to be(:ephemeral) - expect(subject[:text]).to start_with('Unknown command') + expect(subject[:text]).to start_with('The specified command is not valid') expect(subject[:text]).to match('/gitlab issue show') end end @@ -37,7 +37,7 @@ describe Gitlab::SlashCommands::Command do it 'rejects the actions' do expect(subject[:response_type]).to be(:ephemeral) - expect(subject[:text]).to start_with('Whoops! This action is not allowed') + expect(subject[:text]).to start_with('You are not allowed') end end @@ -57,7 +57,7 @@ describe Gitlab::SlashCommands::Command do context 'and user can not create deployment' do it 'returns action' do expect(subject[:response_type]).to be(:ephemeral) - expect(subject[:text]).to start_with('Whoops! This action is not allowed') + expect(subject[:text]).to start_with('You are not allowed') end end diff --git a/spec/lib/gitlab/slash_commands/presenters/access_spec.rb b/spec/lib/gitlab/slash_commands/presenters/access_spec.rb index 286fec892e6..f00039c634f 100644 --- a/spec/lib/gitlab/slash_commands/presenters/access_spec.rb +++ b/spec/lib/gitlab/slash_commands/presenters/access_spec.rb @@ -4,12 +4,14 @@ require 'spec_helper' describe Gitlab::SlashCommands::Presenters::Access do describe '#access_denied' do - subject { described_class.new.access_denied } + let(:project) { build(:project) } + + subject { described_class.new.access_denied(project) } it { is_expected.to be_a(Hash) } it 'displays an error message' do - expect(subject[:text]).to match("is not allowed") + expect(subject[:text]).to match('are not allowed') expect(subject[:response_type]).to be(:ephemeral) end end diff --git a/spec/services/clusters/gcp/kubernetes/create_or_update_namespace_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb index e44cc3f5a78..5a3b1cd6cfb 100644 --- a/spec/services/clusters/gcp/kubernetes/create_or_update_namespace_service_spec.rb +++ b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do +describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do include KubernetesHelpers let(:cluster) { create(:cluster, :project, :provided_by_gcp) } @@ -35,8 +35,8 @@ describe Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService, '#execute' d stub_kubeclient_create_service_account(api_url, namespace: namespace) stub_kubeclient_create_secret(api_url, namespace: namespace) stub_kubeclient_put_secret(api_url, "#{namespace}-token", namespace: namespace) - stub_kubeclient_put_role(api_url, Clusters::Gcp::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, namespace: namespace) - stub_kubeclient_put_role_binding(api_url, Clusters::Gcp::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME, 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_get_secret( api_url, @@ -56,7 +56,7 @@ describe Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService, '#execute' d end it 'creates project service account' do - expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService).to receive(:execute).once + expect_any_instance_of(Clusters::Kubernetes::CreateOrUpdateServiceAccountService).to receive(:execute).once subject end @@ -123,7 +123,7 @@ describe Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService, '#execute' d end it 'creates project service account' do - expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService).to receive(:execute).once + expect_any_instance_of(Clusters::Kubernetes::CreateOrUpdateServiceAccountService).to receive(:execute).once subject end diff --git a/spec/services/clusters/gcp/kubernetes/create_or_update_service_account_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb index 8b874989758..10dbfc800ff 100644 --- a/spec/services/clusters/gcp/kubernetes/create_or_update_service_account_service_spec.rb +++ b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'spec_helper' -describe Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService do +describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do include KubernetesHelpers let(:api_url) { 'http://111.111.111.111' } @@ -143,8 +143,8 @@ describe Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService do 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::Gcp::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, namespace: namespace) - stub_kubeclient_put_role_binding(api_url, Clusters::Gcp::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME, 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) end it_behaves_like 'creates service account and token' @@ -175,10 +175,10 @@ describe Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService do it 'creates a role and role binding granting knative serving permissions to the service account' do subject - expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/roles/#{Clusters::Gcp::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME}").with( + expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/roles/#{Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME}").with( body: hash_including( metadata: { - name: Clusters::Gcp::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, + name: Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_NAME, namespace: namespace }, rules: [{ diff --git a/spec/services/clusters/gcp/kubernetes/fetch_kubernetes_token_service_spec.rb b/spec/services/clusters/kubernetes/fetch_kubernetes_token_service_spec.rb index 93c0dc37ade..145528616ee 100644 --- a/spec/services/clusters/gcp/kubernetes/fetch_kubernetes_token_service_spec.rb +++ b/spec/services/clusters/kubernetes/fetch_kubernetes_token_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Clusters::Gcp::Kubernetes::FetchKubernetesTokenService do +describe Clusters::Kubernetes::FetchKubernetesTokenService do include KubernetesHelpers describe '#execute' do diff --git a/spec/support/services/clusters/create_service_shared.rb b/spec/support/services/clusters/create_service_shared.rb index 27f6d0570b6..468f25bfffe 100644 --- a/spec/support/services/clusters/create_service_shared.rb +++ b/spec/support/services/clusters/create_service_shared.rb @@ -32,56 +32,24 @@ shared_context 'invalid cluster create params' do end shared_examples 'create cluster service success' do - context 'namespace per environment feature is enabled' do - before do - stub_feature_flags(kubernetes_namespace_per_environment: true) - end - - it 'creates a cluster object and performs a worker' do - expect(ClusterProvisionWorker).to receive(:perform_async) - - expect { subject } - .to change { Clusters::Cluster.count }.by(1) - .and change { Clusters::Providers::Gcp.count }.by(1) - - expect(subject.name).to eq('test-cluster') - expect(subject.user).to eq(user) - expect(subject.project).to eq(project) - expect(subject.provider.gcp_project_id).to eq('gcp-project') - expect(subject.provider.zone).to eq('us-central1-a') - expect(subject.provider.num_nodes).to eq(1) - expect(subject.provider.machine_type).to eq('machine_type-a') - expect(subject.provider.access_token).to eq(access_token) - expect(subject.provider).to be_legacy_abac - expect(subject.platform).to be_nil - expect(subject.namespace_per_environment).to eq true - end - end - - context 'namespace per environment feature is disabled' do - before do - stub_feature_flags(kubernetes_namespace_per_environment: false) - end - - it 'creates a cluster object and performs a worker' do - expect(ClusterProvisionWorker).to receive(:perform_async) - - expect { subject } - .to change { Clusters::Cluster.count }.by(1) - .and change { Clusters::Providers::Gcp.count }.by(1) - - expect(subject.name).to eq('test-cluster') - expect(subject.user).to eq(user) - expect(subject.project).to eq(project) - expect(subject.provider.gcp_project_id).to eq('gcp-project') - expect(subject.provider.zone).to eq('us-central1-a') - expect(subject.provider.num_nodes).to eq(1) - expect(subject.provider.machine_type).to eq('machine_type-a') - expect(subject.provider.access_token).to eq(access_token) - expect(subject.provider).to be_legacy_abac - expect(subject.platform).to be_nil - expect(subject.namespace_per_environment).to eq false - end + it 'creates a cluster object and performs a worker' do + expect(ClusterProvisionWorker).to receive(:perform_async) + + expect { subject } + .to change { Clusters::Cluster.count }.by(1) + .and change { Clusters::Providers::Gcp.count }.by(1) + + expect(subject.name).to eq('test-cluster') + expect(subject.user).to eq(user) + expect(subject.project).to eq(project) + expect(subject.provider.gcp_project_id).to eq('gcp-project') + expect(subject.provider.zone).to eq('us-central1-a') + expect(subject.provider.num_nodes).to eq(1) + expect(subject.provider.machine_type).to eq('machine_type-a') + expect(subject.provider.access_token).to eq(access_token) + expect(subject.provider).to be_legacy_abac + expect(subject.platform).to be_nil + expect(subject.namespace_per_environment).to eq true end end diff --git a/spec/support/shared_examples/chat_slash_commands_shared_examples.rb b/spec/support/shared_examples/chat_slash_commands_shared_examples.rb index dcc92dda950..a99068ab678 100644 --- a/spec/support/shared_examples/chat_slash_commands_shared_examples.rb +++ b/spec/support/shared_examples/chat_slash_commands_shared_examples.rb @@ -103,7 +103,7 @@ RSpec.shared_examples 'chat slash commands service' do expect_any_instance_of(Gitlab::SlashCommands::Command).not_to receive(:execute) result = subject.trigger(params) - expect(result).to include(text: /^Whoops! This action is not allowed/) + expect(result).to include(text: /^You are not allowed/) end end end |