Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
e440c86979
commit
05f1d5d981
32 changed files with 297 additions and 146 deletions
|
@ -10,7 +10,6 @@ stages:
|
|||
- review
|
||||
- qa
|
||||
- post-qa
|
||||
- notification
|
||||
- pages
|
||||
|
||||
variables:
|
||||
|
@ -36,7 +35,6 @@ include:
|
|||
- local: .gitlab/ci/frontend.gitlab-ci.yml
|
||||
- local: .gitlab/ci/global.gitlab-ci.yml
|
||||
- local: .gitlab/ci/memory.gitlab-ci.yml
|
||||
- local: .gitlab/ci/notifications.gitlab-ci.yml
|
||||
- local: .gitlab/ci/pages.gitlab-ci.yml
|
||||
- local: .gitlab/ci/qa.gitlab-ci.yml
|
||||
- local: .gitlab/ci/reports.gitlab-ci.yml
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
# Make sure to update all the similar conditions in other CI config files if you modify these conditions
|
||||
.if-canonical-gitlab-schedule: &if-canonical-gitlab-schedule
|
||||
if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_NAMESPACE =~ /^gitlab-org($|\/)/ && $CI_PIPELINE_SOURCE == "schedule"'
|
||||
|
||||
.notify:
|
||||
image: ruby:2.6-alpine
|
||||
stage: notification
|
||||
dependencies: []
|
||||
cache: {}
|
||||
before_script:
|
||||
- apk update && apk add git curl bash
|
||||
- source scripts/utils.sh
|
||||
- source scripts/notifications.sh
|
||||
- install_gitlab_gem
|
||||
variables:
|
||||
COMMIT_NOTES_URL: "https://${CI_SERVER_HOST}/${CI_PROJECT_PATH}/commit/${CI_COMMIT_SHA}#notes-list"
|
||||
|
||||
package-and-qa:notify-failure:
|
||||
extends: .notify
|
||||
rules:
|
||||
- <<: *if-canonical-gitlab-schedule
|
||||
when: manual # TODO: remove notify job if not necessary
|
||||
script:
|
||||
- 'export NOTIFICATION_MESSAGE=":skull_and_crossbones: Scheduled QA against master failed! :skull_and_crossbones: See ${CI_PIPELINE_URL}. For downstream pipelines, see ${COMMIT_NOTES_URL}"'
|
||||
- 'notify_on_job_failure package-and-qa qa-master "${NOTIFICATION_MESSAGE}" ci_failing'
|
||||
needs: ["package-and-qa"]
|
||||
allow_failure: true
|
|
@ -1 +1 @@
|
|||
1.78.0
|
||||
1.79.0
|
||||
|
|
|
@ -53,6 +53,7 @@ export default class Clusters {
|
|||
helpPath,
|
||||
ingressHelpPath,
|
||||
ingressDnsHelpPath,
|
||||
ingressModSecurityHelpPath,
|
||||
environmentsHelpPath,
|
||||
clustersHelpPath,
|
||||
deployBoardsHelpPath,
|
||||
|
@ -69,6 +70,7 @@ export default class Clusters {
|
|||
helpPath,
|
||||
ingressHelpPath,
|
||||
ingressDnsHelpPath,
|
||||
ingressModSecurityHelpPath,
|
||||
environmentsHelpPath,
|
||||
clustersHelpPath,
|
||||
deployBoardsHelpPath,
|
||||
|
@ -169,6 +171,7 @@ export default class Clusters {
|
|||
ingressHelpPath: this.state.ingressHelpPath,
|
||||
managePrometheusPath: this.state.managePrometheusPath,
|
||||
ingressDnsHelpPath: this.state.ingressDnsHelpPath,
|
||||
ingressModSecurityHelpPath: this.state.ingressModSecurityHelpPath,
|
||||
cloudRunHelpPath: this.state.cloudRunHelpPath,
|
||||
providerType: this.state.providerType,
|
||||
preInstalledKnative: this.state.preInstalledKnative,
|
||||
|
|
|
@ -56,6 +56,11 @@ export default {
|
|||
required: false,
|
||||
default: '',
|
||||
},
|
||||
ingressModSecurityHelpPath: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
cloudRunHelpPath: {
|
||||
type: String,
|
||||
required: false,
|
||||
|
@ -112,6 +117,9 @@ export default {
|
|||
ingressInstalled() {
|
||||
return this.applications.ingress.status === APPLICATION_STATUS.INSTALLED;
|
||||
},
|
||||
ingressEnableModsecurity() {
|
||||
return this.applications.ingress.modsecurity_enabled;
|
||||
},
|
||||
ingressExternalEndpoint() {
|
||||
return this.applications.ingress.externalIp || this.applications.ingress.externalHostname;
|
||||
},
|
||||
|
@ -127,6 +135,18 @@ export default {
|
|||
enableClusterApplicationElasticStack() {
|
||||
return gon.features && gon.features.enableClusterApplicationElasticStack;
|
||||
},
|
||||
ingressModSecurityDescription() {
|
||||
const escapedUrl = _.escape(this.ingressModSecurityHelpPath);
|
||||
|
||||
return sprintf(
|
||||
s__('ClusterIntegration|Learn more about %{startLink}ModSecurity%{endLink}'),
|
||||
{
|
||||
startLink: `<a href="${escapedUrl}" target="_blank" rel="noopener noreferrer">`,
|
||||
endLink: '</a>',
|
||||
},
|
||||
false,
|
||||
);
|
||||
},
|
||||
ingressDescription() {
|
||||
return sprintf(
|
||||
_.escape(
|
||||
|
@ -135,9 +155,9 @@ export default {
|
|||
),
|
||||
),
|
||||
{
|
||||
pricingLink: `<strong><a href="https://cloud.google.com/compute/pricing#lb"
|
||||
pricingLink: `<a href="https://cloud.google.com/compute/pricing#lb"
|
||||
target="_blank" rel="noopener noreferrer">
|
||||
${_.escape(s__('ClusterIntegration|pricing'))}</a></strong>`,
|
||||
${_.escape(s__('ClusterIntegration|pricing'))}</a>`,
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
@ -311,6 +331,9 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
|
|||
:request-reason="applications.ingress.requestReason"
|
||||
:installed="applications.ingress.installed"
|
||||
:install-failed="applications.ingress.installFailed"
|
||||
:install-application-request-params="{
|
||||
modsecurity_enabled: applications.ingress.modsecurity_enabled,
|
||||
}"
|
||||
:uninstallable="applications.ingress.uninstallable"
|
||||
:uninstall-successful="applications.ingress.uninstallSuccessful"
|
||||
:uninstall-failed="applications.ingress.uninstallFailed"
|
||||
|
@ -326,6 +349,26 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
|
|||
}}
|
||||
</p>
|
||||
|
||||
<template>
|
||||
<div class="form-group">
|
||||
<div class="form-check form-check-inline">
|
||||
<input
|
||||
v-model="applications.ingress.modsecurity_enabled"
|
||||
:disabled="ingressInstalled"
|
||||
type="checkbox"
|
||||
autocomplete="off"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label class="form-check-label label-bold" for="ingress-enable-modsecurity">
|
||||
{{ s__('ClusterIntegration|Enable Web Application Firewall') }}
|
||||
</label>
|
||||
</div>
|
||||
<p class="form-text text-muted">
|
||||
<strong v-html="ingressModSecurityDescription"></strong>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="ingressInstalled">
|
||||
<div class="form-group">
|
||||
<label for="ingress-endpoint">{{ s__('ClusterIntegration|Ingress Endpoint') }}</label>
|
||||
|
@ -375,7 +418,9 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
|
|||
</p>
|
||||
</template>
|
||||
<template v-if="!ingressInstalled">
|
||||
<div class="bs-callout bs-callout-info" v-html="ingressDescription"></div>
|
||||
<div class="bs-callout bs-callout-info">
|
||||
<strong v-html="ingressDescription"></strong>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</application-row>
|
||||
|
|
|
@ -52,6 +52,7 @@ export default class ClusterStore {
|
|||
ingress: {
|
||||
...applicationInitialState,
|
||||
title: s__('ClusterIntegration|Ingress'),
|
||||
modsecurity_enabled: false,
|
||||
externalIp: null,
|
||||
externalHostname: null,
|
||||
},
|
||||
|
@ -108,6 +109,7 @@ export default class ClusterStore {
|
|||
helpPath,
|
||||
ingressHelpPath,
|
||||
ingressDnsHelpPath,
|
||||
ingressModSecurityHelpPath,
|
||||
environmentsHelpPath,
|
||||
clustersHelpPath,
|
||||
deployBoardsHelpPath,
|
||||
|
@ -116,6 +118,7 @@ export default class ClusterStore {
|
|||
this.state.helpPath = helpPath;
|
||||
this.state.ingressHelpPath = ingressHelpPath;
|
||||
this.state.ingressDnsHelpPath = ingressDnsHelpPath;
|
||||
this.state.ingressModSecurityHelpPath = ingressModSecurityHelpPath;
|
||||
this.state.environmentsHelpPath = environmentsHelpPath;
|
||||
this.state.clustersHelpPath = clustersHelpPath;
|
||||
this.state.deployBoardsHelpPath = deployBoardsHelpPath;
|
||||
|
@ -207,6 +210,8 @@ export default class ClusterStore {
|
|||
if (appId === INGRESS) {
|
||||
this.state.applications.ingress.externalIp = serverAppEntry.external_ip;
|
||||
this.state.applications.ingress.externalHostname = serverAppEntry.external_hostname;
|
||||
this.state.applications.ingress.modsecurity_enabled =
|
||||
serverAppEntry.modsecurity_enabled || this.state.applications.ingress.modsecurity_enabled;
|
||||
} else if (appId === CERT_MANAGER) {
|
||||
this.state.applications.cert_manager.email =
|
||||
this.state.applications.cert_manager.email || serverAppEntry.email;
|
||||
|
|
|
@ -47,7 +47,7 @@ class Clusters::ApplicationsController < Clusters::BaseController
|
|||
end
|
||||
|
||||
def cluster_application_params
|
||||
params.permit(:application, :hostname, :kibana_hostname, :email, :stack)
|
||||
params.permit(:application, :hostname, :kibana_hostname, :email, :stack, :modsecurity_enabled)
|
||||
end
|
||||
|
||||
def cluster_application_destroy_params
|
||||
|
|
|
@ -14,6 +14,7 @@ module Clusters
|
|||
include AfterCommitQueue
|
||||
|
||||
default_value_for :ingress_type, :nginx
|
||||
default_value_for :modsecurity_enabled, false
|
||||
default_value_for :version, VERSION
|
||||
|
||||
enum ingress_type: {
|
||||
|
@ -73,7 +74,7 @@ module Clusters
|
|||
private
|
||||
|
||||
def specification
|
||||
return {} unless Feature.enabled?(:ingress_modsecurity)
|
||||
return {} unless modsecurity_enabled
|
||||
|
||||
{
|
||||
"controller" => {
|
||||
|
|
|
@ -11,6 +11,7 @@ class ClusterApplicationEntity < Grape::Entity
|
|||
expose :kibana_hostname, if: -> (e, _) { e.respond_to?(:kibana_hostname) }
|
||||
expose :email, if: -> (e, _) { e.respond_to?(:email) }
|
||||
expose :stack, if: -> (e, _) { e.respond_to?(:stack) }
|
||||
expose :modsecurity_enabled, if: -> (e, _) { e.respond_to?(:modsecurity_enabled) }
|
||||
expose :update_available?, as: :update_available, if: -> (e, _) { e.respond_to?(:update_available?) }
|
||||
expose :can_uninstall?, as: :can_uninstall
|
||||
end
|
||||
|
|
|
@ -31,6 +31,10 @@ module Clusters
|
|||
application.stack = params[:stack]
|
||||
end
|
||||
|
||||
if application.has_attribute?(:modsecurity_enabled)
|
||||
application.modsecurity_enabled = params[:modsecurity_enabled] || false
|
||||
end
|
||||
|
||||
if application.respond_to?(:oauth_application)
|
||||
application.oauth_application = create_oauth_application(application, request)
|
||||
end
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
help_path: help_page_path('user/project/clusters/index.md', anchor: 'installing-applications'),
|
||||
ingress_help_path: help_page_path('user/project/clusters/index.md', anchor: 'getting-the-external-endpoint'),
|
||||
ingress_dns_help_path: help_page_path('user/project/clusters/index.md', anchor: 'manually-determining-the-external-endpoint'),
|
||||
ingress_mod_security_help_path: help_page_path('user/clusters/applications.md', anchor: 'web-application-firewall-modsecurity'),
|
||||
environments_help_path: help_page_path('ci/environments', anchor: 'defining-environments'),
|
||||
clusters_help_path: help_page_path('user/project/clusters/index.md', anchor: 'deploying-to-a-kubernetes-cluster'),
|
||||
deploy_boards_help_path: help_page_path('user/project/deploy_boards.html', anchor: 'enabling-deploy-boards'),
|
||||
|
|
|
@ -187,3 +187,4 @@
|
|||
- project_daily_statistics
|
||||
- create_evidence
|
||||
- group_export
|
||||
- self_monitoring_project_create
|
||||
|
|
40
app/workers/self_monitoring_project_create_worker.rb
Normal file
40
app/workers/self_monitoring_project_create_worker.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SelfMonitoringProjectCreateWorker
|
||||
include ApplicationWorker
|
||||
include ExclusiveLeaseGuard
|
||||
|
||||
# This worker falls under Self-monitoring with Monitor::APM group. However,
|
||||
# self-monitoring is not classified as a feature category but rather as
|
||||
# Other Functionality. Metrics seems to be the closest feature_category for
|
||||
# this worker.
|
||||
feature_category :metrics
|
||||
|
||||
LEASE_TIMEOUT = 15.minutes.to_i
|
||||
|
||||
EXCLUSIVE_LEASE_KEY = 'self_monitoring_service_creation_deletion'
|
||||
|
||||
def perform
|
||||
try_obtain_lease do
|
||||
Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService.new.execute
|
||||
end
|
||||
end
|
||||
|
||||
# @param job_id [String]
|
||||
# Job ID that is used to construct the cache keys.
|
||||
# @return [Hash]
|
||||
# Returns true if the job is enqueued or in progress and false otherwise.
|
||||
def self.in_progress?(job_id)
|
||||
Gitlab::SidekiqStatus.job_status(Array.wrap(job_id)).first
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def lease_key
|
||||
EXCLUSIVE_LEASE_KEY
|
||||
end
|
||||
|
||||
def lease_timeout
|
||||
LEASE_TIMEOUT
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add enable_modsecurity setting to managed ingress
|
||||
merge_request: 21966
|
||||
author:
|
||||
type: added
|
5
changelogs/unreleased/gitaly-version-v1.79.0.yml
Normal file
5
changelogs/unreleased/gitaly-version-v1.79.0.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Upgrade to Gitaly v1.79.0
|
||||
merge_request: 22515
|
||||
author:
|
||||
type: changed
|
|
@ -99,6 +99,7 @@
|
|||
- [chaos, 2]
|
||||
- [create_evidence, 2]
|
||||
- [group_export, 1]
|
||||
- [self_monitoring_project_create, 2]
|
||||
|
||||
# EE-specific queues
|
||||
- [analytics, 1]
|
||||
|
|
|
@ -264,10 +264,6 @@ subgraph "`qa` stage"
|
|||
dast -.-> |needs and depends on| G;
|
||||
end
|
||||
|
||||
subgraph "`notification` stage"
|
||||
NOTIFICATION2["package-and-qa:notify-failure<br>(manual)"] -.-> |needs| Q;
|
||||
end
|
||||
|
||||
subgraph "`post-test` stage"
|
||||
M
|
||||
end
|
||||
|
|
|
@ -248,10 +248,10 @@ use an A record. If your external endpoint is a hostname, use a CNAME record.
|
|||
|
||||
#### Web Application Firewall (ModSecurity)
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/65192) in GitLab 12.3 (enabled using `ingress_modsecurity` [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development)).
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/21966) in GitLab 12.7.
|
||||
|
||||
Out of the box, GitLab provides you real-time security monitoring with
|
||||
[`modsecurity`](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#modsecurity)
|
||||
[ModSecurity](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#modsecurity).
|
||||
|
||||
Modsecurity is a toolkit for real-time web application monitoring, logging,
|
||||
and access control. With GitLab's offering, the [OWASP's Core Rule Set](https://www.modsecurity.org/CRS/Documentation/), which provides generic attack detection capabilities,
|
||||
|
@ -267,22 +267,18 @@ This feature:
|
|||
kubectl -n gitlab-managed-apps exec -it $(kubectl get pods -n gitlab-managed-apps | grep 'ingress-controller' | awk '{print $1}') -- tail -f /var/log/modsec/audit.log
|
||||
```
|
||||
|
||||
There is a small performance overhead by enabling `modsecurity`. If this is
|
||||
considered significant for your application, you can either:
|
||||
To enable ModSecurity, check the **Enable Web Application Firewall** checkbox
|
||||
when installing your [Ingress application](#ingress).
|
||||
|
||||
- Disable ModSecurity's rule engine for your deployed application by setting
|
||||
[the deployment variable](../../topics/autodevops/index.md)
|
||||
`AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE` to `Off`. This will prevent ModSecurity from
|
||||
processing any requests for the given application or environment.
|
||||
- Toggle the feature flag to false by running the following command within your
|
||||
instance's Rails console:
|
||||
There is a small performance overhead by enabling ModSecurity. If this is
|
||||
considered significant for your application, you can disable ModSecurity's
|
||||
rule engine for your deployed application by setting
|
||||
[the deployment variable](../../topics/autodevops/index.md)
|
||||
`AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE` to `Off`. This will prevent ModSecurity
|
||||
from processing any requests for the given application or environment.
|
||||
|
||||
```ruby
|
||||
Feature.disable(:ingress_modsecurity)
|
||||
```
|
||||
|
||||
Once disabled, you must [uninstall](#uninstalling-applications) and reinstall your Ingress
|
||||
application for the changes to take effect.
|
||||
To permanently disable it, you must [uninstall](#uninstalling-applications) and
|
||||
reinstall your Ingress application for the changes to take effect.
|
||||
|
||||
### JupyterHub
|
||||
|
||||
|
|
25
lib/gitlab/database_importers/self_monitoring/helpers.rb
Normal file
25
lib/gitlab/database_importers/self_monitoring/helpers.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module DatabaseImporters
|
||||
module SelfMonitoring
|
||||
module Helpers
|
||||
def application_settings
|
||||
@application_settings ||= ApplicationSetting.current_without_cache
|
||||
end
|
||||
|
||||
def project_created?
|
||||
self_monitoring_project.present?
|
||||
end
|
||||
|
||||
def self_monitoring_project
|
||||
application_settings.instance_administration_project
|
||||
end
|
||||
|
||||
def self_monitoring_project_id
|
||||
application_settings.instance_administration_project_id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,38 +6,26 @@ module Gitlab
|
|||
module Project
|
||||
class CreateService < ::BaseService
|
||||
include Stepable
|
||||
|
||||
STEPS_ALLOWED_TO_FAIL = [
|
||||
:validate_application_settings, :validate_project_created, :validate_admins
|
||||
].freeze
|
||||
include SelfMonitoring::Helpers
|
||||
|
||||
VISIBILITY_LEVEL = Gitlab::VisibilityLevel::INTERNAL
|
||||
PROJECT_NAME = 'GitLab Instance Administration'
|
||||
|
||||
steps :validate_application_settings,
|
||||
:validate_project_created,
|
||||
:validate_admins,
|
||||
:create_group,
|
||||
:create_project,
|
||||
:save_project_id,
|
||||
:add_group_members,
|
||||
:add_prometheus_manual_configuration
|
||||
:add_prometheus_manual_configuration,
|
||||
:track_event
|
||||
|
||||
def initialize
|
||||
super(nil)
|
||||
end
|
||||
|
||||
def execute!
|
||||
result = execute_steps
|
||||
if result[:status] == :success
|
||||
::Gitlab::Tracking.event("self_monitoring", "project_created")
|
||||
result
|
||||
elsif STEPS_ALLOWED_TO_FAIL.include?(result[:last_step])
|
||||
::Gitlab::Tracking.event("self_monitoring", "project_created")
|
||||
success
|
||||
else
|
||||
raise StandardError, result[:message]
|
||||
end
|
||||
def execute
|
||||
execute_steps
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -49,13 +37,6 @@ module Gitlab
|
|||
error(_('No application_settings found'))
|
||||
end
|
||||
|
||||
def validate_project_created(result)
|
||||
return success(result) unless project_created?
|
||||
|
||||
log_error('Project already created')
|
||||
error(_('Project already created'))
|
||||
end
|
||||
|
||||
def validate_admins(result)
|
||||
unless instance_admins.any?
|
||||
log_error('No active admin user found')
|
||||
|
@ -68,7 +49,7 @@ module Gitlab
|
|||
def create_group(result)
|
||||
if project_created?
|
||||
log_info(_('Instance administrators group already exists'))
|
||||
result[:group] = application_settings.instance_administration_project.owner
|
||||
result[:group] = self_monitoring_project.owner
|
||||
return success(result)
|
||||
end
|
||||
|
||||
|
@ -84,7 +65,7 @@ module Gitlab
|
|||
def create_project(result)
|
||||
if project_created?
|
||||
log_info('Instance administration project already exists')
|
||||
result[:project] = application_settings.instance_administration_project
|
||||
result[:project] = self_monitoring_project
|
||||
return success(result)
|
||||
end
|
||||
|
||||
|
@ -99,7 +80,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def save_project_id(result)
|
||||
return success if project_created?
|
||||
return success(result) if project_created?
|
||||
|
||||
response = application_settings.update(
|
||||
instance_administration_project_id: result[:project].id
|
||||
|
@ -140,12 +121,10 @@ module Gitlab
|
|||
success(result)
|
||||
end
|
||||
|
||||
def application_settings
|
||||
@application_settings ||= ApplicationSetting.current_without_cache
|
||||
end
|
||||
def track_event(result)
|
||||
::Gitlab::Tracking.event("self_monitoring", "project_created")
|
||||
|
||||
def project_created?
|
||||
application_settings.instance_administration_project.present?
|
||||
success(result)
|
||||
end
|
||||
|
||||
def parse_url(uri_string)
|
||||
|
|
|
@ -2567,6 +2567,9 @@ msgstr ""
|
|||
msgid "BambooService|You must set up automatic revision labeling and a repository trigger in Bamboo."
|
||||
msgstr ""
|
||||
|
||||
msgid "Batch operations"
|
||||
msgstr ""
|
||||
|
||||
msgid "BatchComments|Delete all pending comments"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3848,6 +3851,9 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Enable Cloud Run on GKE (beta)"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Enable Web Application Firewall"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Enable or disable GitLab's connection to your Kubernetes cluster."
|
||||
msgstr ""
|
||||
|
||||
|
@ -4034,6 +4040,9 @@ msgstr ""
|
|||
msgid "ClusterIntegration|Learn more about %{help_link_start}zones%{help_link_end}."
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Learn more about %{startLink}ModSecurity%{endLink}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ClusterIntegration|Learn more about %{startLink}Regions %{externalLinkIcon}%{endLink}."
|
||||
msgstr ""
|
||||
|
||||
|
@ -13827,9 +13836,6 @@ msgstr ""
|
|||
msgid "Project access must be granted explicitly to each user."
|
||||
msgstr ""
|
||||
|
||||
msgid "Project already created"
|
||||
msgstr ""
|
||||
|
||||
msgid "Project already deleted"
|
||||
msgstr ""
|
||||
|
||||
|
@ -15434,6 +15440,12 @@ msgstr ""
|
|||
msgid "Resume replication"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resync"
|
||||
msgstr ""
|
||||
|
||||
msgid "Resync all designs"
|
||||
msgstr ""
|
||||
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
|
||||
|
@ -18332,6 +18344,9 @@ msgstr ""
|
|||
msgid "There was an error subscribing to this label."
|
||||
msgstr ""
|
||||
|
||||
msgid "There was an error syncing the Design Repositories."
|
||||
msgstr ""
|
||||
|
||||
msgid "There was an error trying to validate your query"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
# Sends Slack notification MSG to CI_SLACK_WEBHOOK_URL (which needs to be set).
|
||||
# ICON_EMOJI needs to be set to an icon emoji name (without the `:` around it).
|
||||
function notify_slack() {
|
||||
CHANNEL=$1
|
||||
MSG=$2
|
||||
ICON_EMOJI=$3
|
||||
|
||||
if [ -z "$CHANNEL" ] || [ -z "$CI_SLACK_WEBHOOK_URL" ] || [ -z "$MSG" ] || [ -z "$ICON_EMOJI" ]; then
|
||||
echo "Missing argument(s) - Use: $0 channel message icon_emoji"
|
||||
echo "and set CI_SLACK_WEBHOOK_URL environment variable."
|
||||
else
|
||||
curl -X POST --data-urlencode 'payload={"channel": "#'"${CHANNEL}"'", "username": "GitLab QA Bot", "text": "'"${MSG}"'", "icon_emoji": "'":${ICON_EMOJI}:"'"}' "${CI_SLACK_WEBHOOK_URL}"
|
||||
fi
|
||||
}
|
||||
|
||||
function notify_on_job_failure() {
|
||||
JOB_NAME=$1
|
||||
CHANNEL=$2
|
||||
MSG=$3
|
||||
ICON_EMOJI=$4
|
||||
|
||||
local job_id
|
||||
job_id=$(scripts/get-job-id "$CI_PROJECT_ID" "$CI_PIPELINE_ID" "$JOB_NAME" -s failed)
|
||||
if [ -n "${job_id}" ]; then
|
||||
notify_slack "${CHANNEL}" "${MSG}" "${ICON_EMOJI}"
|
||||
fi
|
||||
}
|
|
@ -71,6 +71,7 @@ FactoryBot.define do
|
|||
end
|
||||
|
||||
factory :clusters_applications_ingress, class: Clusters::Applications::Ingress do
|
||||
modsecurity_enabled { false }
|
||||
cluster factory: %i(cluster with_installed_helm provided_by_gcp)
|
||||
end
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
"kibana_hostname": { "type": ["string", "null"] },
|
||||
"email": { "type": ["string", "null"] },
|
||||
"stack": { "type": ["string", "null"] },
|
||||
"modsecurity_enabled": { "type": ["boolean", "null"] },
|
||||
"update_available": { "type": ["boolean", "null"] },
|
||||
"can_uninstall": { "type": "boolean" }
|
||||
},
|
||||
|
|
|
@ -190,6 +190,7 @@ describe('Applications', () => {
|
|||
title: 'Ingress',
|
||||
status: 'installed',
|
||||
externalHostname: 'localhost.localdomain',
|
||||
modsecurity_enabled: false,
|
||||
},
|
||||
helm: { title: 'Helm Tiller' },
|
||||
cert_manager: { title: 'Cert-Manager' },
|
||||
|
@ -473,7 +474,12 @@ describe('Applications', () => {
|
|||
vm = mountComponent(Applications, {
|
||||
applications: {
|
||||
...APPLICATIONS_MOCK_STATE,
|
||||
ingress: { title: 'Ingress', status: 'installed', externalIp: '1.1.1.1' },
|
||||
ingress: {
|
||||
title: 'Ingress',
|
||||
status: 'installed',
|
||||
externalIp: '1.1.1.1',
|
||||
modsecurity_enabled: false,
|
||||
},
|
||||
elastic_stack: { title: 'Elastic Stack', status: 'installed', kibana_hostname: '' },
|
||||
},
|
||||
});
|
||||
|
|
|
@ -150,7 +150,7 @@ const DEFAULT_APPLICATION_STATE = {
|
|||
|
||||
const APPLICATIONS_MOCK_STATE = {
|
||||
helm: { title: 'Helm Tiller', status: 'installable' },
|
||||
ingress: { title: 'Ingress', status: 'installable' },
|
||||
ingress: { title: 'Ingress', status: 'installable', modsecurity_enabled: false },
|
||||
crossplane: { title: 'Crossplane', status: 'installable', stack: '' },
|
||||
cert_manager: { title: 'Cert-Manager', status: 'installable' },
|
||||
runner: { title: 'GitLab Runner' },
|
||||
|
|
|
@ -86,6 +86,7 @@ describe('Clusters Store', () => {
|
|||
uninstallSuccessful: false,
|
||||
uninstallFailed: false,
|
||||
validationError: null,
|
||||
modsecurity_enabled: false,
|
||||
},
|
||||
runner: {
|
||||
title: 'GitLab Runner',
|
||||
|
|
|
@ -69,15 +69,17 @@ describe('Sentry Error Stack Trace', () => {
|
|||
});
|
||||
|
||||
describe('Stack trace', () => {
|
||||
it('should show stacktrace', () => {
|
||||
beforeEach(() => {
|
||||
store.state.details.loadingStacktrace = false;
|
||||
});
|
||||
|
||||
it('should show stacktrace', () => {
|
||||
mountComponent({ stubs: {} });
|
||||
expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
|
||||
expect(wrapper.find(Stacktrace).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should not show stacktrace if it does not exist', () => {
|
||||
store.state.details.loadingStacktrace = false;
|
||||
expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
|
||||
expect(wrapper.find(Stacktrace).exists()).toBe(false);
|
||||
});
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
|
||||
describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
|
||||
describe '#execute' do
|
||||
let(:result) { subject.execute! }
|
||||
let(:result) { subject.execute }
|
||||
|
||||
let(:prometheus_settings) do
|
||||
{
|
||||
|
@ -18,10 +18,12 @@ describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
|
|||
end
|
||||
|
||||
context 'without application_settings' do
|
||||
it 'does not fail' do
|
||||
it 'returns error' do
|
||||
expect(subject).to receive(:log_error).and_call_original
|
||||
expect(result).to eq(
|
||||
status: :success
|
||||
status: :error,
|
||||
message: 'No application_settings found',
|
||||
last_step: :validate_application_settings
|
||||
)
|
||||
|
||||
expect(Project.count).to eq(0)
|
||||
|
@ -36,10 +38,12 @@ describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
|
|||
allow(ApplicationSetting).to receive(:current_without_cache) { application_setting }
|
||||
end
|
||||
|
||||
it 'does not fail' do
|
||||
it 'returns error' do
|
||||
expect(subject).to receive(:log_error).and_call_original
|
||||
expect(result).to eq(
|
||||
status: :success
|
||||
status: :error,
|
||||
message: 'No active admin user found',
|
||||
last_step: :validate_admins
|
||||
)
|
||||
|
||||
expect(Project.count).to eq(0)
|
||||
|
@ -47,7 +51,7 @@ describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with admin users' do
|
||||
context 'with application settings and admin users' do
|
||||
let(:project) { result[:project] }
|
||||
let(:group) { result[:group] }
|
||||
let(:application_setting) { Gitlab::CurrentSettings.current_application_settings }
|
||||
|
@ -73,6 +77,13 @@ describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
|
|||
|
||||
it_behaves_like 'has prometheus service', 'http://localhost:9090'
|
||||
|
||||
it "tracks successful install" do
|
||||
expect(::Gitlab::Tracking).to receive(:event)
|
||||
expect(::Gitlab::Tracking).to receive(:event).with("self_monitoring", "project_created")
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
it 'creates group' do
|
||||
expect(result[:status]).to eq(:success)
|
||||
expect(group).to be_persisted
|
||||
|
@ -132,7 +143,11 @@ describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
|
|||
it 'returns error when saving project ID fails' do
|
||||
allow(application_setting).to receive(:save) { false }
|
||||
|
||||
expect { result }.to raise_error(StandardError, 'Could not save project ID')
|
||||
expect(result).to eq(
|
||||
status: :error,
|
||||
message: 'Could not save project ID',
|
||||
last_step: :save_project_id
|
||||
)
|
||||
end
|
||||
|
||||
context 'when project already exists' do
|
||||
|
@ -149,9 +164,8 @@ describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
|
|||
application_setting.instance_administration_project_id = existing_project.id
|
||||
end
|
||||
|
||||
it 'does not fail' do
|
||||
expect(subject).to receive(:log_error).and_call_original
|
||||
expect(result[:status]).to eq(:success)
|
||||
it 'returns success' do
|
||||
expect(result).to include(status: :success)
|
||||
|
||||
expect(Project.count).to eq(1)
|
||||
expect(Group.count).to eq(1)
|
||||
|
@ -250,7 +264,11 @@ describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
|
|||
|
||||
it 'returns error' do
|
||||
expect(subject).to receive(:log_error).and_call_original
|
||||
expect { result }.to raise_error(StandardError, 'Could not create project')
|
||||
expect(result).to eq(
|
||||
status: :error,
|
||||
message: 'Could not create project',
|
||||
last_step: :create_project
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -261,7 +279,11 @@ describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
|
|||
|
||||
it 'returns error' do
|
||||
expect(subject).to receive(:log_error).and_call_original
|
||||
expect { result }.to raise_error(StandardError, 'Could not add admins as members')
|
||||
expect(result).to eq(
|
||||
status: :error,
|
||||
message: 'Could not add admins as members',
|
||||
last_step: :add_group_members
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -275,15 +297,13 @@ describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
|
|||
|
||||
it 'returns error' do
|
||||
expect(subject).to receive(:log_error).and_call_original
|
||||
expect { result }.to raise_error(StandardError, 'Could not save prometheus manual configuration')
|
||||
expect(result).to eq(
|
||||
status: :error,
|
||||
message: 'Could not save prometheus manual configuration',
|
||||
last_step: :add_prometheus_manual_configuration
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks successful install" do
|
||||
expect(Gitlab::Tracking).to receive(:event).with("self_monitoring", "project_created")
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -142,11 +142,11 @@ describe Clusters::Applications::Ingress do
|
|||
let(:project) { build(:project) }
|
||||
let(:cluster) { build(:cluster, projects: [project]) }
|
||||
|
||||
context 'when ingress_modsecurity is enabled' do
|
||||
context 'when modsecurity_enabled is enabled' do
|
||||
before do
|
||||
stub_feature_flags(ingress_modsecurity: true)
|
||||
|
||||
allow(subject).to receive(:cluster).and_return(cluster)
|
||||
|
||||
allow(subject).to receive(:modsecurity_enabled).and_return(true)
|
||||
end
|
||||
|
||||
it 'includes modsecurity module enablement' do
|
||||
|
@ -173,10 +173,8 @@ describe Clusters::Applications::Ingress do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when ingress_modsecurity is disabled' do
|
||||
context 'when modsecurity_enabled is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ingress_modsecurity: false)
|
||||
|
||||
allow(subject).to receive(:cluster).and_return(cluster)
|
||||
end
|
||||
|
||||
|
|
|
@ -47,6 +47,33 @@ describe Clusters::Applications::CreateService do
|
|||
create(:clusters_applications_helm, :installed, cluster: cluster)
|
||||
end
|
||||
|
||||
context 'ingress application' do
|
||||
let(:params) do
|
||||
{
|
||||
application: 'ingress',
|
||||
modsecurity_enabled: true
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
expect_any_instance_of(Clusters::Applications::Ingress)
|
||||
.to receive(:make_scheduled!)
|
||||
.and_call_original
|
||||
end
|
||||
|
||||
it 'creates the application' do
|
||||
expect do
|
||||
subject
|
||||
|
||||
cluster.reload
|
||||
end.to change(cluster, :application_ingress)
|
||||
end
|
||||
|
||||
it 'sets modsecurity_enabled' do
|
||||
expect(subject.modsecurity_enabled).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'cert manager application' do
|
||||
let(:params) do
|
||||
{
|
||||
|
|
28
spec/workers/self_monitoring_project_create_worker_spec.rb
Normal file
28
spec/workers/self_monitoring_project_create_worker_spec.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe SelfMonitoringProjectCreateWorker do
|
||||
describe '#perform' do
|
||||
let(:service_class) { Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService }
|
||||
let(:service) { instance_double(service_class) }
|
||||
|
||||
before do
|
||||
allow(service_class).to receive(:new) { service }
|
||||
end
|
||||
|
||||
it 'runs the SelfMonitoring::Project::CreateService' do
|
||||
expect(service).to receive(:execute)
|
||||
|
||||
subject.perform
|
||||
end
|
||||
end
|
||||
|
||||
describe '.in_progress?', :clean_gitlab_redis_shared_state do
|
||||
it 'returns in_progress when job is enqueued' do
|
||||
jid = described_class.perform_async
|
||||
|
||||
expect(described_class.in_progress?(jid)).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue