diff options
28 files changed, 637 insertions, 213 deletions
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index 83f558af1a1..73eb0ee22c0 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -131,6 +131,11 @@ module Clusters scope :with_management_project, -> { where.not(management_project: nil) } scope :for_project_namespace, -> (namespace_id) { joins(:projects).where(projects: { namespace_id: namespace_id }) } + scope :with_application_prometheus, -> { includes(:application_prometheus).joins(:application_prometheus) } + scope :with_project_alert_service_data, -> (project_ids) do + conditions = { projects: { alerts_service: [:data] } } + includes(conditions).joins(conditions).where(projects: { id: project_ids }) + end def self.ancestor_clusters_for_clusterable(clusterable, hierarchy_order: :asc) return [] if clusterable.is_a?(Instance) diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index f06b6f83e88..11972879a8d 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -627,6 +627,14 @@ :weight: 1 :idempotent: :tags: [] +- :name: incident_management:clusters_applications_check_prometheus_health + :feature_category: :incident_management + :has_external_dependencies: true + :urgency: :low + :resource_boundary: :unknown + :weight: 2 + :idempotent: true + :tags: [] - :name: incident_management:incident_management_process_alert :feature_category: :incident_management :has_external_dependencies: diff --git a/app/workers/clusters/applications/check_prometheus_health_worker.rb b/app/workers/clusters/applications/check_prometheus_health_worker.rb new file mode 100644 index 00000000000..2e8ee739946 --- /dev/null +++ b/app/workers/clusters/applications/check_prometheus_health_worker.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Clusters + module Applications + class CheckPrometheusHealthWorker + include ApplicationWorker + # rubocop:disable Scalability/CronWorkerContext + # This worker does not perform work scoped to a context + include CronjobQueue + # rubocop:enable Scalability/CronWorkerContext + + queue_namespace :incident_management + feature_category :incident_management + urgency :low + + idempotent! + worker_has_external_dependencies! + + def perform + demo_project_ids = Gitlab::Monitor::DemoProjects.primary_keys + + clusters = Clusters::Cluster.with_application_prometheus + .with_project_alert_service_data(demo_project_ids) + + # Move to a seperate worker with scoped context if expanded to do work on customer projects + clusters.each { |cluster| Clusters::Applications::PrometheusHealthCheckService.new(cluster).execute } + end + end + end +end diff --git a/changelogs/unreleased/ab-monitor-demo-environments-2.yml b/changelogs/unreleased/ab-monitor-demo-environments-2.yml new file mode 100644 index 00000000000..19bb53079d8 --- /dev/null +++ b/changelogs/unreleased/ab-monitor-demo-environments-2.yml @@ -0,0 +1,5 @@ +--- +title: Add Scheduled Job for Monitoring Monitor Group Demo Environments +merge_request: 27360 +author: +type: added diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 9a2e470f852..36d333f3164 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -1078,8 +1078,6 @@ production: &base monitoring: # Time between sampling of unicorn socket metrics, in seconds # unicorn_sampler_interval: 10 - # Time between sampling of Puma metrics, in seconds - # puma_sampler_interval: 5 # IP whitelist to access monitoring endpoints ip_whitelist: - 127.0.0.0/8 diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index c0cd491547a..84e6c731fa8 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -728,9 +728,6 @@ Settings.action_cable['worker_pool_size'] ||= 4 Settings['monitoring'] ||= Settingslogic.new({}) Settings.monitoring['ip_whitelist'] ||= ['127.0.0.1/8'] Settings.monitoring['unicorn_sampler_interval'] ||= 10 -Settings.monitoring['puma_sampler_interval'] ||= 5 -Settings.monitoring['ruby_sampler_interval'] ||= 60 -Settings.monitoring['global_search_sampler_interval'] ||= 60 Settings.monitoring['sidekiq_exporter'] ||= Settingslogic.new({}) Settings.monitoring.sidekiq_exporter['enabled'] ||= false Settings.monitoring.sidekiq_exporter['address'] ||= 'localhost' diff --git a/config/initializers/7_prometheus_metrics.rb b/config/initializers/7_prometheus_metrics.rb index 62a02781154..bb89850892e 100644 --- a/config/initializers/7_prometheus_metrics.rb +++ b/config/initializers/7_prometheus_metrics.rb @@ -42,11 +42,11 @@ if !Rails.env.test? && Gitlab::Metrics.prometheus_metrics_enabled? Gitlab::Cluster::LifecycleEvents.on_worker_start do defined?(::Prometheus::Client.reinitialize_on_pid_change) && Prometheus::Client.reinitialize_on_pid_change - Gitlab::Metrics::Samplers::RubySampler.initialize_instance(Settings.monitoring.ruby_sampler_interval).start - Gitlab::Metrics::Samplers::DatabaseSampler.initialize_instance(Gitlab::Metrics::Samplers::DatabaseSampler::SAMPLING_INTERVAL_SECONDS).start + Gitlab::Metrics::Samplers::RubySampler.initialize_instance.start + Gitlab::Metrics::Samplers::DatabaseSampler.initialize_instance.start if Gitlab.ee? && Gitlab::Runtime.sidekiq? - Gitlab::Metrics::Samplers::GlobalSearchSampler.instance(Settings.monitoring.global_search_sampler_interval).start + Gitlab::Metrics::Samplers::GlobalSearchSampler.instance.start end rescue IOError => e Gitlab::ErrorTracking.track_exception(e) @@ -59,7 +59,7 @@ if !Rails.env.test? && Gitlab::Metrics.prometheus_metrics_enabled? if Gitlab::Runtime.unicorn? Gitlab::Metrics::Samplers::UnicornSampler.instance(Settings.monitoring.unicorn_sampler_interval).start elsif Gitlab::Runtime.puma? - Gitlab::Metrics::Samplers::PumaSampler.instance(Settings.monitoring.puma_sampler_interval).start + Gitlab::Metrics::Samplers::PumaSampler.instance.start end Gitlab::Metrics.gauge(:deployments, 'GitLab Version', {}, :max).set({ version: Gitlab::VERSION }, 1) diff --git a/doc/ci/ci_cd_for_external_repos/github_integration.md b/doc/ci/ci_cd_for_external_repos/github_integration.md index addf7be1397..a15c02fa148 100644 --- a/doc/ci/ci_cd_for_external_repos/github_integration.md +++ b/doc/ci/ci_cd_for_external_repos/github_integration.md @@ -20,7 +20,7 @@ cannot be used to authenticate with GitHub as an external CI/CD repository. NOTE: **Note:** Personal access tokens can only be used to connect GitHub.com -repositories to GitLab. +repositories to GitLab, and the GitHub user must have the [owner role](https://help.github.com/en/github/getting-started-with-github/access-permissions-on-github). To perform a one-off authorization with GitHub to grant GitLab access your repositories: diff --git a/doc/development/go_guide/dependencies.md b/doc/development/go_guide/dependencies.md new file mode 100644 index 00000000000..a65e91869e3 --- /dev/null +++ b/doc/development/go_guide/dependencies.md @@ -0,0 +1,171 @@ +# Dependency Management in Go + +Go takes an unusual approach to dependency management, in that it is +source-based instead of artifact-based. In an artifact-based dependency +management system, packages consist of artifacts generated from source code and +are stored in a separate repository system from source code. For example, many +NodeJS packages use `npmjs.org` as a package repository and `github.com` as a +source repository. On the other hand, packages in Go *are* source code and +releasing a package does not involve artifact generation or a separate +repository. Go packages must be stored in a version control repository on a VCS +server. Dependencies are fetched directly from their VCS server or via an +intermediary proxy which itself fetches them from their VCS server. + +## Versioning + +Go 1.11 introduced modules and first-class package versioning to the Go ecosystem. +Prior to this, Go did not have any well-defined mechanism for version management. +While 3rd party version management tools existed, the default Go experience had +no support for versioning. + +Go modules use semantic versioning. The versions of a module are defined as VCS +tags that are valid semantic versions prefixed with `v`. For example, to release +version `1.0.0` of `gitlab.com/my/project`, the developer must create the Git +tag `v1.0.0`. + +For major versions other than 0 and 1, the module name must be suffixed with +`/vX` where X is the major version. For example, version `v2.0.0` of +`gitlab.com/my/project` must be named and imported as +`gitlab.com/my/project/v2`. + +Go uses 'pseudo-versions', which are special semantic versions that reference a +specific VCS commit. The prerelease component of the semantic version must be or +end with a timestamp and the first 12 characters of the commit identifier: + +- `vX.0.0-yyyymmddhhmmss-abcdefabcdef`, when no earlier tagged commit exists for X. +- `vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef`, when most recent prior tag is vX.Y.Z-pre. +- `vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef`, when most recent prior tag is vX.Y.Z. + +If a VCS tag matches one of these patterns, it is ignored. + +## 'Module' vs 'Package' + +- A package is a folder containing `*.go` files. +- A module is a folder containing a `go.mod` file. +- A module is *usually* also a package, that is a folder containing a `go.mod` + file and `*.go` files. +- A module may have subdirectories, which may be packages. +- Modules usually come in the form of a VCS repository (Git, SVN, Hg, and so on). +- Any subdirectories of a module that themselves are modules are distinct, + separate modules and are excluded from the containing module. + - Given a module `repo`, if `repo/sub` contains a `go.mod` file then + `repo/sub` and any files contained therein are a separate module and not a + part of `repo`. + +## Naming + +The name of a module or package, excluding the standard library, must be of the +form `(sub.)*domain.tld(/path)*`. This is similar to a URL, but is not a URL. +The package name does not have a scheme (such as `https://`) and cannot have a +port number. `example.com:8443/my/package` is not a valid name. + +## Fetching Packages + +Prior to Go 1.12, the process for fetching a package was as follows: + +1. Query `https://{package name}?go-get=1`. +1. Scan the response for the `go-import` meta tag. +1. Fetch the repository indicated by the meta tag using the indicated VCS. + +The meta tag should have the form `<meta name="go-import" content="{prefix} +{vcs} {url}">`. For example, `gitlab.com/my/project git +https://gitlab.com/my/project.git` indicates that packages beginning with +`gitlab.com/my/project` should be fetched from +`https://gitlab.com/my/project.git` using Git. + +## Fetching Modules + +Go 1.12 introduced checksum databases and module proxies. + +### Checksums + +In addition to `go.mod`, a module will have a `go.sum` file. This file records a +SHA-256 checksum of the code and the `go.mod` file of every version of every +dependency that is referenced by the module or one of the module's dependencies. +Go continually updates `go.sum` as new dependencies are referenced. + +When Go fetches the dependencies of a module, if those dependencies already have +an entry in `go.sum`, Go will verify the checksum of these dependencies. If the +checksum does not match what is in `go.sum`, the build will fail. This ensures +that a given version of a module cannot be changed by its developers or by a +malicious party without causing build failures. + +Go 1.12+ can be configured to use a checksum database. If configured to do so, +when Go fetches a dependency and there is no corresponding entry in `go.sum`, Go +will query the configured checksum database(s) for the checksum of the +dependency instead of calculating it from the downloaded dependency. If the +dependency cannot be found in the checksum database, the build will fail. If the +downloaded dependency's checksum does not match the result from the checksum +database, the build will fail. The following environment variables control this: + +- `GOSUMDB` identifies the name, and optionally the public key and server URL, + of the checksum database to query. + - A value of `off` will entirely disable checksum database queries. + - Go 1.13+ uses `sum.golang.org` if `GOSUMDB` is not defined. +- `GONOSUMDB` is a comma-separated list of module suffixes that checksum + database queries should be disabled for. Wildcards are supported. +- `GOPRIVATE` is a comma-separated list of module names that has the same + function as `GONOSUMDB` in addition to disabling other features. + +### Proxies + +Go 1.12+ can be configured to fetch modules from a Go proxy instead of directly +from the module's VCS. If configured to do so, when Go fetches a dependency, it +attempts to fetch the dependency from the configured proxies, in order. The +following environment variables control this: + +- `GOPROXY` is a comma-separated list of module proxies to query. + - A value of `direct` will entirely disable module proxy queries. + - If the last entry in the list is `direct`, Go will fall back to the process + described [above](#fetching-packages) if none of the proxies can provide the + dependency. + - Go 1.13+ uses `proxy.golang.org,direct` if `GOPROXY` is not defined. +- `GONOPROXY` is a comma-separated list of module suffixes that should be + fetched directly and not from a proxy. Wildcards are supported. +- `GOPRIVATE` is a comma-separated list of module names that has the same + function as `GONOPROXY` in addition to disabling other features. + +### Fetching + +From Go 1.12 onward, the process for fetching a module or package is as follows: + +1. If `GOPROXY` is a list of proxies and the module is not excluded by + `GONOPROXY` or `GOPRIVATE`, query them in order, and stop at the first valid + response. +1. If `GOPROXY` is `direct`, or the module is excluded, or `GOPROXY` ends with + `,direct` and no proxy provided the module, fall back. + 1. Query `https://{module or package name}?go-get=1`. + 1. Scan the response for the `go-import` meta tag. + 1. Fetch the repository indicated by the meta tag using the indicated VCS. + 1. If the `{vcs}` field is `mod`, the URL should be treated as a module proxy instead of a VCS. +1. If the module is being fetched directly and not as a dependency, stop. +1. If `go.sum` contains an entry corresponding to the module, validate the checksum and stop. +1. If `GOSUMDB` identifies a checksum database and the module is not excluded by + `GONOSUMDB` or `GOPRIVATE`, retrieve the module's checksum, add it to + `go.sum`, and validate the downloaded source against it. +1. If `GOSUMDB` is `off` or the module is excluded, calculate a checksum from + the downloaded source and add it to `go.sum`. + +The downloaded source must contain a `go.mod` file. The `go.mod` file must +contain a `module` directive that specifies the name of the module. If the +module name as specified by `go.mod` does not match the name that was used to +fetch the module, the module will fail to compile. + +If the module is being fetched directly and no version was specified, or if the +module is being added as a dependency and no version was specified, Go uses the +most recent version of the module. If the module is fetched from a proxy, Go +queries the proxy for a list of versions and chooses the latest. If the module is +fetched directly, Go queries the repository for a list of tags and chooses the +latest that is also a valid semantic version. + +## Authenticating + +In versions prior to Go 1.13, support for authenticating requests made by Go was +somewhat inconsistent. Go 1.13 improved support for `.netrc` authentication. If +a request is made over HTTPS and a matching `.netrc` entry can be found, Go will +add HTTP Basic authentication credentials to the request. Go will not +authenticate requests made over HTTP. Go will reject HTTP-only entries in +`GOPROXY` that have embedded credentials. + +In a future version, Go may add support for arbitrary authentication headers. +Follow [golang/go#26232](https://github.com/golang/go/issues/26232) for details. diff --git a/doc/development/go_guide/index.md b/doc/development/go_guide/index.md index ac462aa2fe0..5a5e163e142 100644 --- a/doc/development/go_guide/index.md +++ b/doc/development/go_guide/index.md @@ -17,6 +17,22 @@ experiences. Several projects were started with different standards and they can still have specifics. They will be described in their respective `README.md` or `PROCESS.md` files. +## Dependency Management + +Go uses a source-based strategy for dependency management. Dependencies are +downloaded as source from their source repository. This differs from the more +common artifact-based strategy where dependencies are downloaded as artifacts +from a package repository that is separate from the dependency's source +repository. + +Go did not have first-class support for version management prior to 1.11. That +version introduced Go modules and the use of semantic versioning. Go 1.12 +introduced module proxies, which can serve as an intermediate between clients +and source version control systems, and checksum databases, which can be used to +verify the integrity of dependency downloads. + +See [Dependency Management in Go](dependencies.md) for more details. + ## Code Review We follow the common principles of diff --git a/doc/topics/airgap/index.md b/doc/topics/airgap/index.md index 6d4c486d350..3866ec50253 100644 --- a/doc/topics/airgap/index.md +++ b/doc/topics/airgap/index.md @@ -1,138 +1,3 @@ -# Offline GitLab - -Computers in an offline environment are isolated from the public internet as a security measure. This -page lists all the information available for running GitLab in an offline environment. - -## Quick start - -If you plan to deploy a GitLab instance on a physically-isolated and offline network, see the -[quick start guide](quick_start_guide.md) for configuration steps. - -## Features - -Follow these best practices to use GitLab's features in an offline environment: - -- [Operating the GitLab Secure scanners in an offline environment](../../user/application_security/offline_deployments/index.md). - -## Loading Docker images onto your offline host - -To use many GitLab features, including -[security scans](../../user/application_security/index.md#working-in-an-offline-environment) -and [Auto DevOps](../autodevops/), the GitLab Runner must be able to fetch the -relevant Docker images. - -The process for making these images available without direct access to the public internet -involves downloading the images then packaging and transferring them to the offline host. Here's an -example of such a transfer: - -1. Download Docker images from public internet. -1. Package Docker images as tar archives. -1. Transfer images to offline environment. -1. Load transferred images into offline Docker registry. - -### Using the official GitLab template - -GitLab provides a [vendored template](../../ci/yaml/README.md#includetemplate) -to ease this process. - -This template should be used in a new, empty project, with a `gitlab-ci.yml` file containing: - -```yaml -include: - - template: Secure-Binaries.gitlab-ci.yml -``` - -The pipeline downloads the Docker images needed for the Security Scanners and saves them as -[job artifacts](../../ci/pipelines/job_artifacts.md) or pushes them to the [Container Registry](../../user/packages/container_registry/index.md) -of the project where the pipeline is executed. These archives can be transferred to another location -and [loaded](https://docs.docker.com/engine/reference/commandline/load/) in a Docker daemon. -This method requires a GitLab Runner with access to both `gitlab.com` (including -`registry.gitlab.com`) and the local offline instance. This runner must run in -[privileged mode](https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode) -to be able to use the `docker` command inside the jobs. This runner can be installed in a DMZ or on -a bastion, and used only for this specific project. - -#### Scheduling the updates - -By default, this project's pipeline will run only once, when the `.gitlab-ci.yml` is added to the -repo. To update the GitLab security scanners and signatures, it's necessary to run this pipeline -regularly. GitLab provides a way to [schedule pipelines](../../ci/pipelines/schedules.md). For -example, you can set this up to download and store the Docker images every week. - -Some images can be updated more frequently than others. For example, the [vulnerability database](https://hub.docker.com/r/arminc/clair-db/tags) -for Container Scanning is updated daily. To update this single image, create a new Scheduled -Pipeline that runs daily and set `SECURE_BINARIES_ANALYZERS` to `clair-vulnerabilities-db`. Only -this job will be triggered, and the image will be updated daily and made available in the project -registry. - -#### Using the secure bundle created - -The project using the `Secure-Binaries.gitlab-ci.yml` template should now host all the required -images and resources needed to run GitLab Security features. - -Next, you must tell the offline instance to use these resources instead of the default ones on -GitLab.com. To do so, set the environment variable `SECURE_ANALYZERS_PREFIX` with the URL of the -project [container registry](../../user/packages/container_registry/index.md). - -You can set this variable in the projects' `.gitlab-ci.yml`, or -in the GitLab UI at the project or group level. See the [GitLab CI/CD environment variables page](../../ci/variables/README.md#custom-environment-variables) -for more information. - -#### Variables - -The following table shows which variables you can use with the `Secure-Binaries.gitlab-ci.yml` -template: - -| VARIABLE | Description | Default value | -|-------------------------------------------|-----------------------------------------------|-----------------------------------| -| `SECURE_BINARIES_ANALYZERS` | Comma-separated list of analyzers to download | `"bandit, brakeman, gosec, and so on..."` | -| `SECURE_BINARIES_DOWNLOAD_IMAGES` | Used to disable jobs | `"true"` | -| `SECURE_BINARIES_PUSH_IMAGES` | Push files to the project registry | `"true"` | -| `SECURE_BINARIES_SAVE_ARTIFACTS` | Also save image archives as artifacts | `"false"` | -| `SECURE_BINARIES_ANALYZER_VERSION` | Default analyzer version (Docker tag) | `"2"` | - -### Alternate way without the official template - -If it's not possible to follow the above method, the images can be transferred manually instead: - -#### Example image packager script - -```shell -#!/bin/bash -set -ux - -# Specify needed analyzer images -analyzers=${SAST_ANALYZERS:-"bandit eslint gosec"} -gitlab=registry.gitlab.com/gitlab-org/security-products/analyzers/ - -for i in "${analyzers[@]}" -do - tarname="${i}_2.tar" - docker pull $gitlab$i:2 - docker save $gitlab$i:2 -o ./analyzers/${tarname} - chmod +r ./analyzers/${tarname} -done -``` - -#### Example image loader script - -This example loads the images from a bastion host to an offline host. In certain configurations, -physical media may be needed for such a transfer: - -```shell -#!/bin/bash -set -ux - -# Specify needed analyzer images -analyzers=${SAST_ANALYZERS:-"bandit eslint gosec"} -registry=$GITLAB_HOST:4567 - -for i in "${analyzers[@]}" -do - tarname="${i}_2.tar" - scp ./analyzers/${tarname} ${GITLAB_HOST}:~/${tarname} - ssh $GITLAB_HOST "sudo docker load -i ${tarname}" - ssh $GITLAB_HOST "sudo docker tag $(sudo docker images | grep $i | awk '{print $3}') ${registry}/analyzers/${i}:2" - ssh $GITLAB_HOST "sudo docker push ${registry}/analyzers/${i}:2" -done -``` +--- +redirect_to: '../offline/index.md' +--- diff --git a/doc/topics/index.md b/doc/topics/index.md index 35d22e145af..634dd70613a 100644 --- a/doc/topics/index.md +++ b/doc/topics/index.md @@ -14,6 +14,6 @@ tutorials, technical overviews, blog posts) and videos. - [GitLab Flow](gitlab_flow.md) - [GitLab Installation](../install/README.md) - [GitLab Pages](../user/project/pages/index.md) -- [Offline GitLab](airgap/index.md) +- [Offline GitLab](offline/index.md) >**Note:** More topics will be available soon. diff --git a/doc/topics/offline/index.md b/doc/topics/offline/index.md new file mode 100644 index 00000000000..6d4c486d350 --- /dev/null +++ b/doc/topics/offline/index.md @@ -0,0 +1,138 @@ +# Offline GitLab + +Computers in an offline environment are isolated from the public internet as a security measure. This +page lists all the information available for running GitLab in an offline environment. + +## Quick start + +If you plan to deploy a GitLab instance on a physically-isolated and offline network, see the +[quick start guide](quick_start_guide.md) for configuration steps. + +## Features + +Follow these best practices to use GitLab's features in an offline environment: + +- [Operating the GitLab Secure scanners in an offline environment](../../user/application_security/offline_deployments/index.md). + +## Loading Docker images onto your offline host + +To use many GitLab features, including +[security scans](../../user/application_security/index.md#working-in-an-offline-environment) +and [Auto DevOps](../autodevops/), the GitLab Runner must be able to fetch the +relevant Docker images. + +The process for making these images available without direct access to the public internet +involves downloading the images then packaging and transferring them to the offline host. Here's an +example of such a transfer: + +1. Download Docker images from public internet. +1. Package Docker images as tar archives. +1. Transfer images to offline environment. +1. Load transferred images into offline Docker registry. + +### Using the official GitLab template + +GitLab provides a [vendored template](../../ci/yaml/README.md#includetemplate) +to ease this process. + +This template should be used in a new, empty project, with a `gitlab-ci.yml` file containing: + +```yaml +include: + - template: Secure-Binaries.gitlab-ci.yml +``` + +The pipeline downloads the Docker images needed for the Security Scanners and saves them as +[job artifacts](../../ci/pipelines/job_artifacts.md) or pushes them to the [Container Registry](../../user/packages/container_registry/index.md) +of the project where the pipeline is executed. These archives can be transferred to another location +and [loaded](https://docs.docker.com/engine/reference/commandline/load/) in a Docker daemon. +This method requires a GitLab Runner with access to both `gitlab.com` (including +`registry.gitlab.com`) and the local offline instance. This runner must run in +[privileged mode](https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode) +to be able to use the `docker` command inside the jobs. This runner can be installed in a DMZ or on +a bastion, and used only for this specific project. + +#### Scheduling the updates + +By default, this project's pipeline will run only once, when the `.gitlab-ci.yml` is added to the +repo. To update the GitLab security scanners and signatures, it's necessary to run this pipeline +regularly. GitLab provides a way to [schedule pipelines](../../ci/pipelines/schedules.md). For +example, you can set this up to download and store the Docker images every week. + +Some images can be updated more frequently than others. For example, the [vulnerability database](https://hub.docker.com/r/arminc/clair-db/tags) +for Container Scanning is updated daily. To update this single image, create a new Scheduled +Pipeline that runs daily and set `SECURE_BINARIES_ANALYZERS` to `clair-vulnerabilities-db`. Only +this job will be triggered, and the image will be updated daily and made available in the project +registry. + +#### Using the secure bundle created + +The project using the `Secure-Binaries.gitlab-ci.yml` template should now host all the required +images and resources needed to run GitLab Security features. + +Next, you must tell the offline instance to use these resources instead of the default ones on +GitLab.com. To do so, set the environment variable `SECURE_ANALYZERS_PREFIX` with the URL of the +project [container registry](../../user/packages/container_registry/index.md). + +You can set this variable in the projects' `.gitlab-ci.yml`, or +in the GitLab UI at the project or group level. See the [GitLab CI/CD environment variables page](../../ci/variables/README.md#custom-environment-variables) +for more information. + +#### Variables + +The following table shows which variables you can use with the `Secure-Binaries.gitlab-ci.yml` +template: + +| VARIABLE | Description | Default value | +|-------------------------------------------|-----------------------------------------------|-----------------------------------| +| `SECURE_BINARIES_ANALYZERS` | Comma-separated list of analyzers to download | `"bandit, brakeman, gosec, and so on..."` | +| `SECURE_BINARIES_DOWNLOAD_IMAGES` | Used to disable jobs | `"true"` | +| `SECURE_BINARIES_PUSH_IMAGES` | Push files to the project registry | `"true"` | +| `SECURE_BINARIES_SAVE_ARTIFACTS` | Also save image archives as artifacts | `"false"` | +| `SECURE_BINARIES_ANALYZER_VERSION` | Default analyzer version (Docker tag) | `"2"` | + +### Alternate way without the official template + +If it's not possible to follow the above method, the images can be transferred manually instead: + +#### Example image packager script + +```shell +#!/bin/bash +set -ux + +# Specify needed analyzer images +analyzers=${SAST_ANALYZERS:-"bandit eslint gosec"} +gitlab=registry.gitlab.com/gitlab-org/security-products/analyzers/ + +for i in "${analyzers[@]}" +do + tarname="${i}_2.tar" + docker pull $gitlab$i:2 + docker save $gitlab$i:2 -o ./analyzers/${tarname} + chmod +r ./analyzers/${tarname} +done +``` + +#### Example image loader script + +This example loads the images from a bastion host to an offline host. In certain configurations, +physical media may be needed for such a transfer: + +```shell +#!/bin/bash +set -ux + +# Specify needed analyzer images +analyzers=${SAST_ANALYZERS:-"bandit eslint gosec"} +registry=$GITLAB_HOST:4567 + +for i in "${analyzers[@]}" +do + tarname="${i}_2.tar" + scp ./analyzers/${tarname} ${GITLAB_HOST}:~/${tarname} + ssh $GITLAB_HOST "sudo docker load -i ${tarname}" + ssh $GITLAB_HOST "sudo docker tag $(sudo docker images | grep $i | awk '{print $3}') ${registry}/analyzers/${i}:2" + ssh $GITLAB_HOST "sudo docker push ${registry}/analyzers/${i}:2" +done +``` diff --git a/doc/topics/airgap/quick_start_guide.md b/doc/topics/offline/quick_start_guide.md index 0abdd08ffcf..0abdd08ffcf 100644 --- a/doc/topics/airgap/quick_start_guide.md +++ b/doc/topics/offline/quick_start_guide.md diff --git a/doc/user/project/pages/index.md b/doc/user/project/pages/index.md index 0dd8f1b7958..baafb6b20e8 100644 --- a/doc/user/project/pages/index.md +++ b/doc/user/project/pages/index.md @@ -1,7 +1,5 @@ --- description: 'Learn how to use GitLab Pages to deploy a static website at no additional cost.' -last_updated: 2019-06-04 -type: index, reference stage: Release group: Release Management info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers @@ -15,42 +13,53 @@ info: To determine the technical writer assigned to the Stage/Group associated w > - Support for subgroup project's websites was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/30548) in GitLab 11.8. > - Bundled project templates were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47857) in GitLab 11.8. -**GitLab Pages is a feature that allows you to publish static websites -directly from a repository in GitLab.** +With GitLab Pages, you can publish static websites +directly from a repository in GitLab. -You can use it either for personal or business websites, such as -portfolios, documentation, manifestos, and business presentations. -You can also attribute any license to your content. - -<img src="img/pages_workflow_v12_5.png" alt="Pages websites workflow" class="image-noshadow"> - -Pages is available for free for all GitLab.com users as well as for self-managed -instances (GitLab Core, Starter, Premium, and Ultimate). - -## Overview +- Use for any personal or business website. +- Use any Static Site Generator (SSG) or plain HTML. +- Create websites for your projects, groups, or user account. +- Host your site on your own GitLab instance or on GitLab.com for free. +- Connect your custom domains and TLS certificates. +- Attribute any license to your content. <div class="row"> <div class="col-md-9"> <p style="margin-top: 18px;"> -To publish a website with Pages, you can use any Static Site Generator (SSG), -such as Gatsby, Jekyll, Hugo, Middleman, Harp, Hexo, and Brunch, just to name a few. You can also +To publish a website with Pages, you can use any SSG, +like Gatsby, Jekyll, Hugo, Middleman, Harp, Hexo, and Brunch, just to name a few. You can also publish any website written directly in plain HTML, CSS, and JavaScript.</p> -<p>Pages does <strong>not</strong> support dynamic server-side processing, for instance, as <code>.php</code> and <code>.asp</code> requires. See this article to learn more about +<p>Pages does <strong>not</strong> support dynamic server-side processing, for instance, as <code>.php</code> and <code>.asp</code> requires. Learn more about <a href="https://about.gitlab.com/blog/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/">static websites vs dynamic websites</a>.</p> +<p>Learn more about GitLab Pages:</p> </div> <div class="col-md-3"><img src="img/ssgs_pages.png" alt="Examples of SSGs supported by Pages" class="image-noshadow middle display-block"></div> </div> -### How it works +| Document | Description | +| --- | --- | +| [GitLab Pages domain names, URLs, and baseurls](getting_started_part_one.md) | How GitLab Pages default domains work. | +| [GitLab CI/CD for GitLab Pages](getting_started_part_four.md) | Create your own site by using `.gitlab-ci.yml`. | +| [Exploring GitLab Pages](introduction.md) | Requirements, technical aspects, specific GitLab CI/CD configuration options, Access Control, custom 404 pages, limitations, FAQ. | +|---+---| +| [Custom domains and SSL/TLS Certificates](custom_domains_ssl_tls_certification/index.md) | Add custom domains and subdomains to your website, configure DNS records and SSL/TLS certificates. | +| [Let's Encrypt integration](custom_domains_ssl_tls_certification/lets_encrypt_integration.md) | Secure your Pages sites with Let's Encrypt certificates, which are automatically obtained and renewed by GitLab. | +| [CloudFlare certificates](https://about.gitlab.com/blog/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) | Secure your Pages site with CloudFlare certificates. | +|---+---| +| [Static vs dynamic websites](https://about.gitlab.com/blog/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) | Static versus dynamic site overview. | +| [Modern static site generators](https://about.gitlab.com/blog/2016/06/10/ssg-overview-gitlab-pages-part-2/) | SSG overview. | +| [Build any SSG site with GitLab Pages](https://about.gitlab.com/blog/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) | Use SSGs for GitLab Pages. | + +## How it works -To use GitLab Pages, first you need to create a project in GitLab to upload your website's -files to. These projects can be either public, internal, or private, at your own choice. +To use GitLab Pages, you must create a project in GitLab to upload your website's +files to. These projects can be either public, internal, or private. -GitLab will always deploy your website from a very specific folder called `public` in your -repository. Note that when you create a new project in GitLab, a [repository](../repository/index.md) +GitLab always deploys your website from a very specific folder called `public` in your +repository. When you create a new project in GitLab, a [repository](../repository/index.md) becomes available automatically. -To deploy your site, GitLab will use its built-in tool called [GitLab CI/CD](../../../ci/README.md), +To deploy your site, GitLab uses its built-in tool called [GitLab CI/CD](../../../ci/README.md) to build your site and publish it to the GitLab Pages server. The sequence of scripts that GitLab CI/CD runs to accomplish this task is created from a file named `.gitlab-ci.yml`, which you can [create and modify](getting_started_part_four.md) at will. A specific `job` called `pages` in the configuration file will make GitLab aware that you are deploying a GitLab Pages website. @@ -59,11 +68,11 @@ You can either use GitLab's [default domain for GitLab Pages websites](getting_s `*.gitlab.io`, or your own domain (`example.com`). In that case, you'll need admin access to your domain's registrar (or control panel) to set it up with Pages. -### Getting started +## Getting started -To get started with GitLab Pages, you can either: +To get started with GitLab Pages, you can: -- [Use a bundled website template ready to go](getting_started/pages_bundled_template.md). +- [Use a bundled website template that's ready to go](getting_started/pages_bundled_template.md). - [Copy an existing sample](getting_started/fork_sample_project.md). - [Create a website from scratch or deploy an existing one](getting_started/new_or_existing_website.md). @@ -74,44 +83,26 @@ Optional features: - Use a [custom domain or subdomain](custom_domains_ssl_tls_certification/index.md#set-up-pages-with-a-custom-domain). - Add an [SSL/TLS certificate to secure your site under the HTTPS protocol](custom_domains_ssl_tls_certification/index.md#adding-an-ssltls-certificate-to-pages). -Note that, if you're using GitLab Pages default domain (`.gitlab.io`), +If you're using GitLab Pages default domain (`.gitlab.io`), your website will be automatically secure and available under HTTPS. If you're using your own custom domain, you can optionally secure it with SSL/TLS certificates. -## Availability +## Access to your Pages site If you're using GitLab.com, your website will be publicly available to the internet. To restrict access to your website, enable [GitLab Pages Access Control](pages_access_control.md). -If you're using self-managed instances (Core, Starter, Premium, or Ultimate), +If you're using a self-managed instance (Core, Starter, Premium, or Ultimate), your websites will be published on your own server, according to the [Pages admin settings](../../../administration/pages/index.md) chosen by your sysadmin, -who can opt for making them public or internal to your server. - -## Explore GitLab Pages +who can make them public or internal. -To learn more about configuration options for GitLab Pages, read the following: +## Pages examples -| Document | Description | -| --- | --- | -| [GitLab Pages domain names, URLs, and baseurls](getting_started_part_one.md) | Understand how GitLab Pages default domains work. | -| [GitLab CI/CD for GitLab Pages](getting_started_part_four.md) | Understand how to create your own `.gitlab-ci.yml` for your site. | -| [Exploring GitLab Pages](introduction.md) | Requirements, technical aspects, specific GitLab CI/CD's configuration options, Access Control, custom 404 pages, limitations, FAQ. | -|---+---| -| [Custom domains and SSL/TLS Certificates](custom_domains_ssl_tls_certification/index.md) | How to add custom domains and subdomains to your website, configure DNS records and SSL/TLS certificates. | -| [Let's Encrypt integration](custom_domains_ssl_tls_certification/lets_encrypt_integration.md) | Secure your Pages sites with Let's Encrypt certificates automatically obtained and renewed by GitLab. | -| [CloudFlare certificates](https://about.gitlab.com/blog/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/) | Secure your Pages site with CloudFlare certificates. | -|---+---| -| [Static vs dynamic websites](https://about.gitlab.com/blog/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/) | A conceptual overview on static versus dynamic sites. | -| [Modern static site generators](https://about.gitlab.com/blog/2016/06/10/ssg-overview-gitlab-pages-part-2/) | A conceptual overview on SSGs. | -| [Build any SSG site with GitLab Pages](https://about.gitlab.com/blog/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) | An overview on using SSGs for GitLab Pages. | - -## Advanced use - -There are quite some great examples of GitLab Pages websites built for some -specific reasons. These examples can teach you some advanced techniques +There are some great examples of GitLab Pages websites built for +specific reasons. These examples can teach you advanced techniques to use and adapt to your own needs: - [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/blog/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/). @@ -120,14 +111,9 @@ to use and adapt to your own needs: - [Building a new GitLab docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/blog/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/). - [Publish code coverage reports with GitLab Pages](https://about.gitlab.com/blog/2016/11/03/publish-code-coverage-report-with-gitlab-pages/). -## Admin GitLab Pages for self-managed instances +## Administer GitLab Pages for self-managed instances Enable and configure GitLab Pages on your own instance (GitLab Community Edition and Enterprise Editions) with the [admin guide](../../../administration/pages/index.md). **<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a [video tutorial](https://www.youtube.com/watch?v=dD8c7WNcc6s) for getting started with GitLab Pages admin!** - -## More information about GitLab Pages - -- Announcement (2016-12-24): ["We're bringing GitLab Pages to CE"](https://about.gitlab.com/releases/2016/12/24/were-bringing-gitlab-pages-to-community-edition/) -- Announcement (2017-03-06): ["We are changing the IP of GitLab Pages on GitLab.com"](https://about.gitlab.com/releases/2017/03/06/we-are-changing-the-ip-of-gitlab-pages-on-gitlab-com/) diff --git a/lib/api/search.rb b/lib/api/search.rb index 8ff9bf56f96..1eed92e8dec 100644 --- a/lib/api/search.rb +++ b/lib/api/search.rb @@ -21,8 +21,9 @@ module API }.freeze SCOPE_PRELOAD_METHOD = { - merge_requests: :with_api_entity_associations, - projects: :with_api_entity_associations + merge_requests: :with_api_entity_associations, + projects: :with_api_entity_associations, + issues: :with_api_entity_associations }.freeze def search(additional_params = {}) diff --git a/lib/gitlab.rb b/lib/gitlab.rb index f2bff51df38..43785d165fb 100644 --- a/lib/gitlab.rb +++ b/lib/gitlab.rb @@ -36,6 +36,7 @@ module Gitlab end COM_URL = 'https://gitlab.com' + STAGING_COM_URL = 'https://staging.gitlab.com' APP_DIRS_PATTERN = %r{^/?(app|config|ee|lib|spec|\(\w*\))}.freeze SUBDOMAIN_REGEX = %r{\Ahttps://[a-z0-9]+\.gitlab\.com\z}.freeze VERSION = File.read(root.join("VERSION")).strip.freeze @@ -47,6 +48,10 @@ module Gitlab Gitlab.config.gitlab.url == COM_URL || gl_subdomain? end + def self.staging? + Gitlab.config.gitlab.url == STAGING_COM_URL + end + def self.canary? Gitlab::Utils.to_boolean(ENV['CANARY']) end @@ -75,6 +80,10 @@ module Gitlab Rails.env.development? || com? end + def self.dev_or_test_env? + Rails.env.development? || Rails.env.test? + end + def self.ee? @is_ee ||= # We use this method when the Rails environment is not loaded. This diff --git a/lib/gitlab/metrics/samplers/base_sampler.rb b/lib/gitlab/metrics/samplers/base_sampler.rb index 90051f85f31..ff3e7be567f 100644 --- a/lib/gitlab/metrics/samplers/base_sampler.rb +++ b/lib/gitlab/metrics/samplers/base_sampler.rb @@ -6,8 +6,10 @@ module Gitlab module Metrics module Samplers class BaseSampler < Daemon + attr_reader :interval + # interval - The sampling interval in seconds. - def initialize(interval) + def initialize(interval = self.class::SAMPLING_INTERVAL_SECONDS) interval_half = interval.to_f / 2 @interval = interval diff --git a/lib/gitlab/metrics/samplers/puma_sampler.rb b/lib/gitlab/metrics/samplers/puma_sampler.rb index 98dd517ee3b..b5343d5e66a 100644 --- a/lib/gitlab/metrics/samplers/puma_sampler.rb +++ b/lib/gitlab/metrics/samplers/puma_sampler.rb @@ -4,6 +4,8 @@ module Gitlab module Metrics module Samplers class PumaSampler < BaseSampler + SAMPLING_INTERVAL_SECONDS = 5 + def metrics @metrics ||= init_metrics end diff --git a/lib/gitlab/metrics/samplers/ruby_sampler.rb b/lib/gitlab/metrics/samplers/ruby_sampler.rb index df59c06911b..dac9fbd1247 100644 --- a/lib/gitlab/metrics/samplers/ruby_sampler.rb +++ b/lib/gitlab/metrics/samplers/ruby_sampler.rb @@ -6,9 +6,10 @@ module Gitlab module Metrics module Samplers class RubySampler < BaseSampler + SAMPLING_INTERVAL_SECONDS = 60 GC_REPORT_BUCKETS = [0.005, 0.01, 0.02, 0.04, 0.07, 0.1, 0.5].freeze - def initialize(interval) + def initialize(*) GC::Profiler.clear metrics[:process_start_time_seconds].set(labels, Time.now.to_i) diff --git a/lib/gitlab/monitor/demo_projects.rb b/lib/gitlab/monitor/demo_projects.rb new file mode 100644 index 00000000000..c617f895e4c --- /dev/null +++ b/lib/gitlab/monitor/demo_projects.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Gitlab + module Monitor + # See Demo Project documentation + # https://about.gitlab.com/handbook/engineering/development/ops/monitor/#demo-environments + module DemoProjects + # [https://gitlab.com/gitlab-org/monitor/tanuki-inc, https://gitlab.com/gitlab-org/monitor/monitor-sandbox] + DOT_COM_IDS = [14986497, 12507547].freeze + # [https://staging.gitlab.com/gitlab-org/monitor/monitor-sandbox] + STAGING_IDS = [4422333].freeze + + def self.primary_keys + # .com? returns true for staging + if ::Gitlab.com? && !::Gitlab.staging? + DOT_COM_IDS + elsif ::Gitlab.staging? + STAGING_IDS + elsif ::Gitlab.dev_or_test_env? + Project.limit(100).pluck(:id) # rubocop: disable CodeReuse/ActiveRecord + else + [] + end + end + end + end +end diff --git a/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb index fdf3b5bd045..087a0bfbac5 100644 --- a/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb +++ b/spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb @@ -3,7 +3,17 @@ require 'spec_helper' describe Gitlab::Metrics::Samplers::DatabaseSampler do - subject { described_class.new(described_class::SAMPLING_INTERVAL_SECONDS) } + subject { described_class.new } + + describe '#interval' do + it 'samples every five seconds by default' do + expect(subject.interval).to eq(5) + end + + it 'samples at other intervals if requested' do + expect(described_class.new(11).interval).to eq(11) + end + end describe '#sample' do before do diff --git a/spec/lib/gitlab/metrics/samplers/puma_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/puma_sampler_spec.rb index 1097d26c320..df63f2ebe28 100644 --- a/spec/lib/gitlab/metrics/samplers/puma_sampler_spec.rb +++ b/spec/lib/gitlab/metrics/samplers/puma_sampler_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Gitlab::Metrics::Samplers::PumaSampler do - subject { described_class.new(5) } + subject { described_class.new } let(:null_metric) { double('null_metric', set: nil, observe: nil) } @@ -11,6 +11,16 @@ describe Gitlab::Metrics::Samplers::PumaSampler do allow(Gitlab::Metrics::NullMetric).to receive(:instance).and_return(null_metric) end + describe '#interval' do + it 'samples every five seconds by default' do + expect(subject.interval).to eq(5) + end + + it 'samples at other intervals if requested' do + expect(described_class.new(11).interval).to eq(11) + end + end + describe '#sample' do before do expect(subject).to receive(:puma_stats).and_return(puma_stats) diff --git a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb index ead650a27f0..9fc8dd10922 100644 --- a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb +++ b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Gitlab::Metrics::Samplers::RubySampler do - let(:sampler) { described_class.new(5) } + let(:sampler) { described_class.new } let(:null_metric) { double('null_metric', set: nil, observe: nil) } before do @@ -18,6 +18,16 @@ describe Gitlab::Metrics::Samplers::RubySampler do end end + describe '#interval' do + it 'samples every sixty seconds by default' do + expect(subject.interval).to eq(60) + end + + it 'samples at other intervals if requested' do + expect(described_class.new(11).interval).to eq(11) + end + end + describe '#sample' do it 'adds a metric containing the process resident memory bytes' do expect(Gitlab::Metrics::System).to receive(:memory_usage_rss).and_return(9000) diff --git a/spec/lib/gitlab/monitor/demo_projects_spec.rb b/spec/lib/gitlab/monitor/demo_projects_spec.rb new file mode 100644 index 00000000000..92024a3f9c1 --- /dev/null +++ b/spec/lib/gitlab/monitor/demo_projects_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Monitor::DemoProjects do + describe '#primary_keys' do + subject { described_class.primary_keys } + + it 'fetches primary_keys when on gitlab.com' do + allow(Gitlab).to receive(:com?).and_return(true) + allow(Gitlab).to receive(:staging?).and_return(false) + + expect(subject).to eq(Gitlab::Monitor::DemoProjects::DOT_COM_IDS) + end + + it 'fetches primary_keys when on staging' do + allow(Gitlab).to receive(:com?).and_return(true) + allow(Gitlab).to receive(:staging?).and_return(true) + + expect(subject).to eq(Gitlab::Monitor::DemoProjects::STAGING_IDS) + end + + it 'fetches all keys when in the dev or test env' do + project = create(:project) + allow(Gitlab).to receive(:dev_or_test_env?).and_return(true) + + expect(subject).to eq([project.id]) + end + + it 'falls back on empty array' do + stub_config_setting(url: 'https://helloworld') + allow(Gitlab).to receive(:dev_or_test_env?).and_return(false) + + expect(subject).to eq([]) + end + end +end diff --git a/spec/lib/gitlab_spec.rb b/spec/lib/gitlab_spec.rb index 9362ff72fbc..84d072a50ec 100644 --- a/spec/lib/gitlab_spec.rb +++ b/spec/lib/gitlab_spec.rb @@ -96,6 +96,28 @@ describe Gitlab do end end + describe '.staging?' do + subject { described_class.staging? } + + it 'is false when on GitLab.com' do + stub_config_setting(url: 'https://gitlab.com') + + expect(subject).to eq false + end + + it 'is true when on staging' do + stub_config_setting(url: 'https://staging.gitlab.com') + + expect(subject).to eq true + end + + it 'is false when not on staging' do + stub_config_setting(url: 'https://example.gitlab.com') + + expect(subject).to eq false + end + end + describe '.canary?' do it 'is true when CANARY env var is set to true' do stub_env('CANARY', '1') @@ -186,6 +208,26 @@ describe Gitlab do end end + describe '.dev_or_test_env?' do + subject { described_class.dev_or_test_env? } + + it 'is true when test env' do + expect(subject).to eq true + end + + it 'is true when dev env' do + allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('development')) + + expect(subject).to eq true + end + + it 'is false when env is not dev or test' do + allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('production')) + + expect(subject).to eq false + end + end + describe '.ee?' do before do stub_env('FOSS_ONLY', nil) # Make sure the ENV is clean diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb index 521ed98f637..ed3fe5f5fd8 100644 --- a/spec/models/clusters/cluster_spec.rb +++ b/spec/models/clusters/cluster_spec.rb @@ -172,6 +172,41 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do end end + describe '.with_application_prometheus' do + subject { described_class.with_application_prometheus } + + let!(:cluster) { create(:cluster) } + + context 'cluster has prometheus application' do + let!(:application) { create(:clusters_applications_prometheus, :installed, cluster: cluster) } + + it { is_expected.to include(cluster) } + end + + context 'cluster does not have prometheus application' do + let(:cluster) { create(:cluster) } + + it { is_expected.not_to include(cluster) } + end + end + + describe '.with_project_alert_service_data' do + subject { described_class.with_project_alert_service_data(project_id) } + + let!(:cluster) { create(:cluster, :project) } + let!(:project_id) { cluster.first_project.id } + + context 'project has alert service data' do + let!(:alerts_service) { create(:alerts_service, project: cluster.clusterable) } + + it { is_expected.to include(cluster) } + end + + context 'project has no alert service data' do + it { is_expected.not_to include(cluster) } + end + end + describe '.for_project_namespace' do subject { described_class.for_project_namespace(namespace_id) } diff --git a/spec/workers/clusters/applications/check_prometheus_health_worker_spec.rb b/spec/workers/clusters/applications/check_prometheus_health_worker_spec.rb new file mode 100644 index 00000000000..a09b9ec4165 --- /dev/null +++ b/spec/workers/clusters/applications/check_prometheus_health_worker_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Clusters::Applications::CheckPrometheusHealthWorker, '#perform' do + subject { described_class.new.perform } + + it 'triggers health service' do + cluster = create(:cluster) + allow(Gitlab::Monitor::DemoProjects).to receive(:primary_keys) + allow(Clusters::Cluster).to receive_message_chain(:with_application_prometheus, :with_project_alert_service_data).and_return([cluster]) + + service_instance = instance_double(Clusters::Applications::PrometheusHealthCheckService) + expect(Clusters::Applications::PrometheusHealthCheckService).to receive(:new).with(cluster).and_return(service_instance) + expect(service_instance).to receive(:execute) + + subject + end +end |