diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-07 15:07:55 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-07 15:07:55 +0300 |
commit | 05f1d5d9813332bdd456cb358517e56168a24224 (patch) | |
tree | f9ed7a2692a537b5e1e541318f39d7464fdd8098 /app | |
parent | e440c86979e9c02a09fb6558f59a1fbe29433b51 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/clusters/clusters_bundle.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/clusters/components/applications.vue | 51 | ||||
-rw-r--r-- | app/assets/javascripts/clusters/stores/clusters_store.js | 5 | ||||
-rw-r--r-- | app/controllers/clusters/applications_controller.rb | 2 | ||||
-rw-r--r-- | app/models/clusters/applications/ingress.rb | 3 | ||||
-rw-r--r-- | app/serializers/cluster_application_entity.rb | 1 | ||||
-rw-r--r-- | app/services/clusters/applications/base_service.rb | 4 | ||||
-rw-r--r-- | app/views/clusters/clusters/show.html.haml | 1 | ||||
-rw-r--r-- | app/workers/all_queues.yml | 1 | ||||
-rw-r--r-- | app/workers/self_monitoring_project_create_worker.rb | 40 |
10 files changed, 106 insertions, 5 deletions
diff --git a/app/assets/javascripts/clusters/clusters_bundle.js b/app/assets/javascripts/clusters/clusters_bundle.js index d990d2677a8..b764348eb3c 100644 --- a/app/assets/javascripts/clusters/clusters_bundle.js +++ b/app/assets/javascripts/clusters/clusters_bundle.js @@ -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, diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue index 99844a356c8..af50ca7361d 100644 --- a/app/assets/javascripts/clusters/components/applications.vue +++ b/app/assets/javascripts/clusters/components/applications.vue @@ -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> diff --git a/app/assets/javascripts/clusters/stores/clusters_store.js b/app/assets/javascripts/clusters/stores/clusters_store.js index 35dbf951551..9c8563e8f77 100644 --- a/app/assets/javascripts/clusters/stores/clusters_store.js +++ b/app/assets/javascripts/clusters/stores/clusters_store.js @@ -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; diff --git a/app/controllers/clusters/applications_controller.rb b/app/controllers/clusters/applications_controller.rb index be68d0d0a1d..788ebb14fec 100644 --- a/app/controllers/clusters/applications_controller.rb +++ b/app/controllers/clusters/applications_controller.rb @@ -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 diff --git a/app/models/clusters/applications/ingress.rb b/app/models/clusters/applications/ingress.rb index d140649af3c..d41fc72ae68 100644 --- a/app/models/clusters/applications/ingress.rb +++ b/app/models/clusters/applications/ingress.rb @@ -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" => { diff --git a/app/serializers/cluster_application_entity.rb b/app/serializers/cluster_application_entity.rb index 218bdd21e37..e7e4f5767e9 100644 --- a/app/serializers/cluster_application_entity.rb +++ b/app/serializers/cluster_application_entity.rb @@ -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 diff --git a/app/services/clusters/applications/base_service.rb b/app/services/clusters/applications/base_service.rb index c9f7917938f..4b6c937fd5d 100644 --- a/app/services/clusters/applications/base_service.rb +++ b/app/services/clusters/applications/base_service.rb @@ -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 diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml index 5beeaf7259a..4b295cd022d 100644 --- a/app/views/clusters/clusters/show.html.haml +++ b/app/views/clusters/clusters/show.html.haml @@ -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'), diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 96d75b2fd33..ca050887e0f 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -187,3 +187,4 @@ - project_daily_statistics - create_evidence - group_export +- self_monitoring_project_create diff --git a/app/workers/self_monitoring_project_create_worker.rb b/app/workers/self_monitoring_project_create_worker.rb new file mode 100644 index 00000000000..69bc5431ff7 --- /dev/null +++ b/app/workers/self_monitoring_project_create_worker.rb @@ -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 |