Commit 05f1d5d9 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent e440c869
......@@ -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
......
# 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
......@@ -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
# 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
---
title: Add enable_modsecurity setting to managed ingress
merge_request: 21966
author:
type: added
---
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
......
# 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 ""
......
# 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
{
......
# 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment