Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
a3596259bc
commit
764ecdaf4d
|
@ -1,9 +1,9 @@
|
|||
<script>
|
||||
import { GlBanner } from '@gitlab/ui';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import { setCookie } from '~/lib/utils/common_utils';
|
||||
import { s__ } from '~/locale';
|
||||
import Tracking from '~/tracking';
|
||||
import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
|
||||
import { EVENT_LABEL, DISMISS_EVENT, CLICK_EVENT } from '../constants';
|
||||
|
||||
const trackingMixin = Tracking.mixin({ label: EVENT_LABEL });
|
||||
|
@ -19,24 +19,19 @@ export default {
|
|||
},
|
||||
components: {
|
||||
GlBanner,
|
||||
UserCalloutDismisser,
|
||||
},
|
||||
mixins: [trackingMixin],
|
||||
inject: ['terraformImagePath', 'bannerDismissedKey'],
|
||||
data() {
|
||||
return {
|
||||
isVisible: true,
|
||||
};
|
||||
},
|
||||
inject: ['terraformImagePath'],
|
||||
computed: {
|
||||
docsUrl() {
|
||||
return helpPagePath('user/infrastructure/terraform_state');
|
||||
return helpPagePath('user/infrastructure/iac/terraform_state.md');
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleClose() {
|
||||
setCookie(this.bannerDismissedKey, true);
|
||||
this.isVisible = false;
|
||||
this.track(DISMISS_EVENT);
|
||||
this.$refs.calloutDismisser.dismiss();
|
||||
},
|
||||
buttonClick() {
|
||||
this.track(CLICK_EVENT);
|
||||
|
@ -45,17 +40,21 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<div v-if="isVisible" class="gl-py-5">
|
||||
<gl-banner
|
||||
:title="$options.i18n.title"
|
||||
:button-text="$options.i18n.buttonText"
|
||||
:button-link="docsUrl"
|
||||
:svg-path="terraformImagePath"
|
||||
variant="promotion"
|
||||
@primary="buttonClick"
|
||||
@close="handleClose"
|
||||
>
|
||||
<p>{{ $options.i18n.description }}</p>
|
||||
</gl-banner>
|
||||
</div>
|
||||
<user-callout-dismisser ref="calloutDismisser" feature-name="terraform_notification_dismissed">
|
||||
<template #default="{ shouldShowCallout }">
|
||||
<div v-if="shouldShowCallout" class="gl-py-5">
|
||||
<gl-banner
|
||||
:title="$options.i18n.title"
|
||||
:button-text="$options.i18n.buttonText"
|
||||
:button-link="docsUrl"
|
||||
:svg-path="terraformImagePath"
|
||||
variant="promotion"
|
||||
@primary="buttonClick"
|
||||
@close="handleClose"
|
||||
>
|
||||
<p>{{ $options.i18n.description }}</p>
|
||||
</gl-banner>
|
||||
</div>
|
||||
</template>
|
||||
</user-callout-dismisser>
|
||||
</template>
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
import Vue from 'vue';
|
||||
import { parseBoolean, getCookie } from '~/lib/utils/common_utils';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import TerraformNotification from './components/terraform_notification.vue';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
||||
const apolloProvider = new VueApollo({
|
||||
defaultClient: createDefaultClient(),
|
||||
});
|
||||
|
||||
export default () => {
|
||||
const el = document.querySelector('.js-terraform-notification');
|
||||
const bannerDismissedKey = 'terraform_notification_dismissed';
|
||||
|
||||
if (!el || parseBoolean(getCookie(bannerDismissedKey))) {
|
||||
if (!el) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -14,9 +20,9 @@ export default () => {
|
|||
|
||||
return new Vue({
|
||||
el,
|
||||
apolloProvider,
|
||||
provide: {
|
||||
terraformImagePath,
|
||||
bannerDismissedKey,
|
||||
},
|
||||
render: (createElement) => createElement(TerraformNotification),
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ import Vue from 'vue';
|
|||
import VueApollo from 'vue-apollo';
|
||||
import MrWidgetOptions from 'ee_else_ce/vue_merge_request_widget/mr_widget_options.vue';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import Translate from '../vue_shared/translate';
|
||||
|
||||
Vue.use(Translate);
|
||||
|
@ -31,6 +32,8 @@ export default () => {
|
|||
provide: {
|
||||
artifactsEndpoint: gl.mrWidgetData.artifacts_endpoint,
|
||||
artifactsEndpointPlaceholder: gl.mrWidgetData.artifacts_endpoint_placeholder,
|
||||
falsePositiveDocUrl: gl.mrWidgetData.false_positive_doc_url,
|
||||
canViewFalsePositive: parseBoolean(gl.mrWidgetData.can_view_false_positive),
|
||||
},
|
||||
...MrWidgetOptions,
|
||||
apolloProvider,
|
||||
|
|
|
@ -148,6 +148,7 @@ 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_name, -> (name) { where(name: name) }
|
||||
|
||||
# with_application_prometheus scope is deprecated, and scheduled for removal
|
||||
# in %14.0. See https://gitlab.com/groups/gitlab-org/-/epics/4280
|
||||
|
|
|
@ -137,6 +137,14 @@ module Clusters
|
|||
kubeclient.patch_ingress(ingress.name, data, namespace)
|
||||
end
|
||||
|
||||
def kubeconfig(namespace)
|
||||
to_kubeconfig(
|
||||
url: api_url,
|
||||
namespace: namespace,
|
||||
token: token,
|
||||
ca_pem: ca_pem)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def default_namespace(project, environment_name:)
|
||||
|
@ -154,14 +162,6 @@ module Clusters
|
|||
).execute
|
||||
end
|
||||
|
||||
def kubeconfig(namespace)
|
||||
to_kubeconfig(
|
||||
url: api_url,
|
||||
namespace: namespace,
|
||||
token: token,
|
||||
ca_pem: ca_pem)
|
||||
end
|
||||
|
||||
def read_pods(namespace)
|
||||
kubeclient.get_pods(namespace: namespace).as_json
|
||||
rescue Kubeclient::ResourceNotFoundError
|
||||
|
|
|
@ -18,5 +18,7 @@
|
|||
window.gl.mrWidgetData.approvals_help_path = '#{help_page_path("user/project/merge_requests/merge_request_approvals")}';
|
||||
window.gl.mrWidgetData.pipelines_empty_svg_path = '#{image_path('illustrations/pipelines_empty.svg')}';
|
||||
window.gl.mrWidgetData.codequality_help_path = '#{help_page_path("user/project/merge_requests/code_quality", anchor: "code-quality-reports")}';
|
||||
window.gl.mrWidgetData.false_positive_doc_url = '#{help_page_path('user/application_security/vulnerabilities/index')}';
|
||||
window.gl.mrWidgetData.can_view_false_positive = '#{(Feature.enabled?(:vulnerability_flags, default_enabled: :yaml) && @merge_request.project.licensed_feature_available?(:sast_fp_reduction)).to_s}';
|
||||
|
||||
#js-vue-mr-widget.mr-widget
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: vulnerability_flags
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66775
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340203
|
||||
milestone: '14.2'
|
||||
type: development
|
||||
group: group::static analysis
|
||||
default_enabled: false
|
|
@ -17,3 +17,6 @@ ActionCable::SubscriptionAdapter::Redis.redis_connector = lambda do |config|
|
|||
|
||||
::Redis.new(args)
|
||||
end
|
||||
|
||||
Gitlab::ActionCable::RequestStoreCallbacks.install
|
||||
Gitlab::Database::LoadBalancing::ActionCableCallbacks.install if Gitlab::Database::LoadBalancing.enable?
|
||||
|
|
|
@ -12088,7 +12088,7 @@ Represents vulnerability finding of a security report on the pipeline.
|
|||
| ---- | ---- | ----------- |
|
||||
| <a id="pipelinesecurityreportfindingconfidence"></a>`confidence` | [`String`](#string) | Type of the security report that found the vulnerability. |
|
||||
| <a id="pipelinesecurityreportfindingdescription"></a>`description` | [`String`](#string) | Description of the vulnerability finding. |
|
||||
| <a id="pipelinesecurityreportfindingfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. Available only when feature flag `vulnerability_flags` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
|
||||
| <a id="pipelinesecurityreportfindingfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. |
|
||||
| <a id="pipelinesecurityreportfindingidentifiers"></a>`identifiers` | [`[VulnerabilityIdentifier!]!`](#vulnerabilityidentifier) | Identifiers of the vulnerabilit finding. |
|
||||
| <a id="pipelinesecurityreportfindinglocation"></a>`location` | [`VulnerabilityLocation`](#vulnerabilitylocation) | Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability. |
|
||||
| <a id="pipelinesecurityreportfindingname"></a>`name` | [`String`](#string) | Name of the vulnerability finding. |
|
||||
|
@ -14452,7 +14452,7 @@ Represents a vulnerability.
|
|||
| <a id="vulnerabilitydismissedat"></a>`dismissedAt` | [`Time`](#time) | Timestamp of when the vulnerability state was changed to dismissed. |
|
||||
| <a id="vulnerabilitydismissedby"></a>`dismissedBy` | [`UserCore`](#usercore) | User that dismissed the vulnerability. |
|
||||
| <a id="vulnerabilityexternalissuelinks"></a>`externalIssueLinks` | [`VulnerabilityExternalIssueLinkConnection!`](#vulnerabilityexternalissuelinkconnection) | List of external issue links related to the vulnerability. (see [Connections](#connections)) |
|
||||
| <a id="vulnerabilityfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. Available only when feature flag `vulnerability_flags` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
|
||||
| <a id="vulnerabilityfalsepositive"></a>`falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. |
|
||||
| <a id="vulnerabilityhassolutions"></a>`hasSolutions` | [`Boolean`](#boolean) | Indicates whether there is a solution available for this vulnerability. |
|
||||
| <a id="vulnerabilityid"></a>`id` | [`ID!`](#id) | GraphQL ID of the vulnerability. |
|
||||
| <a id="vulnerabilityidentifiers"></a>`identifiers` | [`[VulnerabilityIdentifier!]!`](#vulnerabilityidentifier) | Identifiers of the vulnerability. |
|
||||
|
|
|
@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
Interact with [labels](../user/project/labels.md) using the REST API.
|
||||
|
||||
NOTE:
|
||||
The `description_html` - was added to response JSON in [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413).
|
||||
The `description_html` - was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21413) to response JSON in GitLab 12.7.
|
||||
|
||||
## List labels
|
||||
|
||||
|
@ -24,7 +24,7 @@ GET /projects/:id/labels
|
|||
| Attribute | Type | Required | Description |
|
||||
| --------- | ------- | -------- | --------------------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `with_counts` | boolean | no | Whether or not to include issue and merge request counts. Defaults to `false`. _([Introduced in GitLab 12.2](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31543))_ |
|
||||
| `with_counts` | boolean | no | Whether or not to include issue and merge request counts. Defaults to `false`. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31543) in GitLab 12.2)_ |
|
||||
| `include_ancestor_groups` | boolean | no | Include ancestor groups. Defaults to `true`. |
|
||||
| `search` | string | no | Keyword to filter labels by. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259024) in GitLab 13.6 |
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ microservice_a:
|
|||
include: path/to/microservice_a.yml
|
||||
```
|
||||
|
||||
You can include multiple files when composing a child pipeline:
|
||||
You can include multiple files when defining a child pipeline. The child pipeline's
|
||||
configuration is composed of all configuration files merged together:
|
||||
|
||||
```yaml
|
||||
microservice_a:
|
||||
|
|
|
@ -1,178 +0,0 @@
|
|||
---
|
||||
stage: Verify
|
||||
group: Runner
|
||||
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/#assignments
|
||||
---
|
||||
|
||||
# Set up macOS runners
|
||||
|
||||
To run a CI/CD job on a macOS runner, complete the following steps in order.
|
||||
|
||||
When you're done, GitLab Runner will be running on your macOS machine
|
||||
and an individual runner will be ready to process jobs.
|
||||
|
||||
- Change the system shell to Bash.
|
||||
- Install Homebrew, rbenv, and GitLab Runner.
|
||||
- Configure rbenv and install Ruby.
|
||||
- Install Xcode.
|
||||
- Register a runner.
|
||||
- Configure CI/CD.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin:
|
||||
|
||||
- Install a recent version of macOS. This guide was developed on 11.4.
|
||||
- Ensure you have terminal or SSH access to the machine.
|
||||
|
||||
## Change the system shell to Bash
|
||||
|
||||
Newer versions of macOS ship with Zsh as the default shell.
|
||||
You must change it to Bash.
|
||||
|
||||
1. Connect to your machine and determine the default shell:
|
||||
|
||||
```shell
|
||||
echo $shell
|
||||
```
|
||||
|
||||
1. If the result is not `/bin/bash`, change the shell by running:
|
||||
|
||||
```shell
|
||||
chsh -s /bin/bash
|
||||
```
|
||||
|
||||
1. Enter your password.
|
||||
1. Restart your terminal or reconnect by using SSH.
|
||||
1. Run `echo $SHELL` again. The result should be `/bin/bash`.
|
||||
|
||||
## Install Homebrew, rbenv, and GitLab Runner
|
||||
|
||||
The runner needs certain environment options to connect to the machine and run a job.
|
||||
|
||||
1. Install the [Homebrew package manager](https://brew.sh/):
|
||||
|
||||
```shell
|
||||
/bin/bash -c "$(curl "https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh")"
|
||||
```
|
||||
|
||||
1. Set up [`rbenv`](https://github.com/rbenv/rbenv), which is a Ruby version manager, and GitLab Runner:
|
||||
|
||||
```shell
|
||||
brew install rbenv gitlab-runner
|
||||
brew services start gitlab-runner
|
||||
```
|
||||
|
||||
## Configure rbenv and install Ruby
|
||||
|
||||
Now configure rbenv and install Ruby.
|
||||
|
||||
1. Add rbenv to the Bash environment:
|
||||
|
||||
```shell
|
||||
echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile
|
||||
source ~/.bash_profile
|
||||
```
|
||||
|
||||
1. Install Ruby 2.74 and set it as the machine's global default:
|
||||
|
||||
```shell
|
||||
rbenv install 2.7.4
|
||||
rbenv global 2.7.4
|
||||
```
|
||||
|
||||
## Install Xcode
|
||||
|
||||
Now install and configure Xcode.
|
||||
|
||||
1. Go to one of these locations and install Xcode:
|
||||
|
||||
- The Apple App Store.
|
||||
- The [Apple Developer Portal](https://developer.apple.com/download/all/?q=xcode).
|
||||
- [`xcode-install`](https://github.com/xcpretty/xcode-install). This project aims to make it easier to download various
|
||||
Apple dependencies from the command line.
|
||||
|
||||
1. Agree to the license and install the recommended additional components.
|
||||
You can do this by opening Xcode and following the prompts, or by running the following command in the terminal:
|
||||
|
||||
```shell
|
||||
sudo xcodebuild -runFirstLaunch
|
||||
```
|
||||
|
||||
1. Update the active developer directory so that Xcode loads the proper command line tools during your build:
|
||||
|
||||
```shell
|
||||
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
|
||||
```
|
||||
|
||||
### Register a runner
|
||||
|
||||
Now register a runner to start picking up your CI/CD jobs.
|
||||
|
||||
1. In GitLab, on the top bar, select **Menu > Projects** or **Menu > Group** to find your project or group.
|
||||
1. On the left sidebar, select **Settings > CI/CD**.
|
||||
1. Expand **Runners**.
|
||||
1. Note the URL and registration token.
|
||||
1. In a terminal, start the interactive setup:
|
||||
|
||||
```shell
|
||||
gitlab-runner register
|
||||
```
|
||||
|
||||
1. Enter the GitLab URL.
|
||||
1. Enter the registration token.
|
||||
1. Enter a description for the runner.
|
||||
You will use the description to identify the runner in GitLab, and the name is associated with jobs executed on this instance.
|
||||
|
||||
1. Enter tags, which direct specific jobs to specific instances. You will use these tags later to ensure macOS jobs
|
||||
run on this macOS machine. In this example, enter:
|
||||
|
||||
```shell
|
||||
macos
|
||||
```
|
||||
|
||||
1. Type `shell` to select the shell [executor](https://docs.gitlab.com/runner/executors/).
|
||||
|
||||
A success message is displayed:
|
||||
|
||||
```shell
|
||||
> Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
|
||||
```
|
||||
|
||||
To view the runner, go to **Settings > CI/CD** and expand **Runners**.
|
||||
|
||||
### Configure CI/CD
|
||||
|
||||
In your GitLab project, configure CI/CD and start a build. You can use this sample `.gitlab-ci.yml` file.
|
||||
Notice the tags match the tags you used to register the runner.
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
|
||||
variables:
|
||||
LANG: "en_US.UTF-8"
|
||||
|
||||
before_script:
|
||||
- gem install bundler
|
||||
- bundle install
|
||||
- gem install cocoapods
|
||||
- pod install
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- bundle exec fastlane build
|
||||
tags:
|
||||
- macos
|
||||
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- bundle exec fastlane test
|
||||
tags:
|
||||
- macos
|
||||
```
|
||||
|
||||
The macOS runner should now build your project.
|
|
@ -209,7 +209,7 @@ Try to avoid. Be as specific as you can. Do not use **and so on** as a replaceme
|
|||
|
||||
## expand
|
||||
|
||||
Use instead of **open** when you are talking about expanding or collapsing a section in the UI.
|
||||
Use **expand** instead of **open** when you are talking about expanding or collapsing a section in the UI.
|
||||
|
||||
## field
|
||||
|
||||
|
|
|
@ -256,6 +256,12 @@ of [legacy Rugged code](../administration/gitaly/index.md#direct-access-to-git-i
|
|||
higher, due to how [Ruby MRI multi-threading](https://en.wikipedia.org/wiki/Global_interpreter_lock)
|
||||
works.
|
||||
|
||||
### Puma per worker maximum memory
|
||||
|
||||
By default, each Puma worker will be limited to 1024 MB of memory.
|
||||
This setting [can be adjusted](../administration/operations/puma.md#puma-worker-killer) and should be considered
|
||||
if you need to increase the number of Puma workers.
|
||||
|
||||
## Redis and Sidekiq
|
||||
|
||||
Redis stores all user sessions and the background task queue.
|
||||
|
|
|
@ -287,6 +287,16 @@ This rule enforces the defined actions and schedules a scan on the provided date
|
|||
| `type` | `string` | `schedule` | The rule's type. |
|
||||
| `branches` | `array` of `string` | `*` or the branch's name | The branch the given policy applies to (supports wildcard). |
|
||||
| `cadence` | `string` | CRON expression (for example, `0 0 * * *`) | A whitespace-separated string containing five fields that represents the scheduled time. |
|
||||
| `clusters` | `object` | | The cluster where the given policy will enforce running selected scans (only for `container_scanning`/`cluster_image_scanning` scans). The key of the object is the name of the Kubernetes cluster configured for your project in GitLab. In the optionally provided value of the object, you can precisely select Kubernetes resources that will be scanned. |
|
||||
|
||||
#### `cluster` schema
|
||||
|
||||
| Field | Type | Possible values | Description |
|
||||
|--------------|---------------------|--------------------------|-------------|
|
||||
| `containers` | `array` of `string` | | The container name that will be scanned (only the first value is currently supported). |
|
||||
| `resources` | `array` of `string` | | The resource name that will be scanned (only the first value is currently supported). |
|
||||
| `namespaces` | `array` of `string` | | The namespace that will be scanned (only the first value is currently supported). |
|
||||
| `kinds` | `array` of `string` | `deployment`/`daemonset` | The resource kind that should be scanned (only the first value is currently supported). |
|
||||
|
||||
### `scan` action type
|
||||
|
||||
|
@ -315,6 +325,9 @@ Note the following:
|
|||
- A secret detection scan runs in `normal` mode when executed as part of a pipeline, and in
|
||||
[`historic`](../secret_detection/index.md#full-history-secret-scan)
|
||||
mode when executed as part of a scheduled scan.
|
||||
- A container scanning and cluster image scanning scans configured for the `pipeline` rule type will ignore the cluster defined in the `clusters` object.
|
||||
They will use predefined CI/CD variables defined for your project. Cluster selection with the `clusters` object is supported for the `schedule` rule type.
|
||||
Cluster with name provided in `clusters` object must be created and configured for the project. To be able to successfully perform the `container_scanning`/`cluster_image_scanning` scans for the cluster you must follow instructions for the [Cluster Image Scanning feature](../cluster_image_scanning/index.md#prerequisites).
|
||||
|
||||
Here's an example:
|
||||
|
||||
|
@ -345,8 +358,8 @@ scan_execution_policy:
|
|||
scanner_profile: Scanner Profile C
|
||||
site_profile: Site Profile D
|
||||
- scan: secret_detection
|
||||
- name: Enforce Secret Detection in every default branch pipeline
|
||||
description: This policy enforces pipeline configuration to have a job with Secret Detection scan for the default branch
|
||||
- name: Enforce Secret Detection and Container Scanning in every default branch pipeline
|
||||
description: This policy enforces pipeline configuration to have a job with Secret Detection and Container Scanning scans for the default branch
|
||||
enabled: true
|
||||
rules:
|
||||
- type: pipeline
|
||||
|
@ -354,7 +367,25 @@ scan_execution_policy:
|
|||
- main
|
||||
actions:
|
||||
- scan: secret_detection
|
||||
```
|
||||
- scan: container_scanning
|
||||
- name: Enforce Cluster Image Scanning on production-cluster every 24h
|
||||
description: This policy enforces Cluster Image Scanning scan to run every 24 hours
|
||||
enabled: true
|
||||
rules:
|
||||
- type: schedule
|
||||
cadence: '15 3 * * *'
|
||||
clusters:
|
||||
production-cluster:
|
||||
containers:
|
||||
- database
|
||||
resources:
|
||||
- production-application
|
||||
namespaces:
|
||||
- production-namespace
|
||||
kinds:
|
||||
- deployment
|
||||
actions:
|
||||
- scan: cluster_image_scanning
|
||||
|
||||
In this example:
|
||||
|
||||
|
@ -362,7 +393,9 @@ In this example:
|
|||
`release/v1.2.1`), DAST scans run with `Scanner Profile A` and `Site Profile B`.
|
||||
- DAST and secret detection scans run every 10 minutes. The DAST scan runs with `Scanner Profile C`
|
||||
and `Site Profile D`.
|
||||
- Secret detection scans run for every pipeline executed on the `main` branch.
|
||||
- Secret detection and container scanning scans run for every pipeline executed on the `main` branch.
|
||||
- Cluster Image Scanning scan runs every 24h. The scan runs on the `production-cluster` cluster and fetches vulnerabilities
|
||||
from the container with the name `database` configured for deployment with the name `production-application` in the `production-namepsace` namespace.
|
||||
|
||||
## Roadmap
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module ActionCable
|
||||
module RequestStoreCallbacks
|
||||
def self.install
|
||||
::ActionCable::Server::Worker.set_callback :work, :around, &wrapper
|
||||
::ActionCable::Channel::Base.set_callback :subscribe, :around, &wrapper
|
||||
::ActionCable::Channel::Base.set_callback :unsubscribe, :around, &wrapper
|
||||
end
|
||||
|
||||
def self.wrapper
|
||||
lambda do |_, inner|
|
||||
::Gitlab::WithRequestStore.with_request_store do
|
||||
inner.call
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Database
|
||||
module LoadBalancing
|
||||
module ActionCableCallbacks
|
||||
def self.install
|
||||
::ActionCable::Server::Worker.set_callback :work, :around, &wrapper
|
||||
::ActionCable::Channel::Base.set_callback :subscribe, :around, &wrapper
|
||||
::ActionCable::Channel::Base.set_callback :unsubscribe, :around, &wrapper
|
||||
end
|
||||
|
||||
def self.wrapper
|
||||
lambda do |_, inner|
|
||||
::Gitlab::Database::LoadBalancing::Session.current.use_primary!
|
||||
|
||||
inner.call
|
||||
ensure
|
||||
::Gitlab::Database::LoadBalancing.proxy.load_balancer.release_host
|
||||
::Gitlab::Database::LoadBalancing::Session.clear_session
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@ module Gitlab
|
|||
|
||||
# Creates a configuration object for the given ActiveRecord model.
|
||||
def self.for_model(model)
|
||||
cfg = model.connection_db_config.configuration_hash
|
||||
cfg = model.connection_db_config.configuration_hash.deep_symbolize_keys
|
||||
lb_cfg = cfg[:load_balancing] || {}
|
||||
config = new(model)
|
||||
|
||||
|
@ -35,7 +35,7 @@ module Gitlab
|
|||
config.hosts = hosts
|
||||
end
|
||||
|
||||
discover = (lb_cfg[:discover] || {}).symbolize_keys
|
||||
discover = lb_cfg[:discover] || {}
|
||||
|
||||
# We iterate over the known/default keys so we don't end up with
|
||||
# random keys in our configuration hash.
|
||||
|
|
|
@ -37377,6 +37377,9 @@ msgstr ""
|
|||
msgid "Vulnerability|Evidence"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|False positive detected"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|File"
|
||||
msgstr ""
|
||||
|
||||
|
@ -37419,6 +37422,9 @@ msgstr ""
|
|||
msgid "Vulnerability|Status"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|The scanner determined this vulnerability to be a false positive. Verify the evaluation before changing its status. %{linkStart}Learn more about false positive detection.%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|The unmodified response is the original response that had no mutations done to the request"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
"@gitlab/favicon-overlay": "2.0.0",
|
||||
"@gitlab/svgs": "1.211.0",
|
||||
"@gitlab/tributejs": "1.0.0",
|
||||
"@gitlab/ui": "32.9.1",
|
||||
"@gitlab/ui": "32.10.0",
|
||||
"@gitlab/visual-review-tools": "1.6.1",
|
||||
"@rails/actioncable": "6.1.3-2",
|
||||
"@rails/ujs": "6.1.3-2",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { GlBanner } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
|
||||
import { setCookie, parseBoolean } from '~/lib/utils/common_utils';
|
||||
import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisser';
|
||||
import { mockTracking } from 'helpers/tracking_helper';
|
||||
import TerraformNotification from '~/projects/terraform_notification/components/terraform_notification.vue';
|
||||
import {
|
||||
EVENT_LABEL,
|
||||
|
@ -9,64 +9,77 @@ import {
|
|||
CLICK_EVENT,
|
||||
} from '~/projects/terraform_notification/constants';
|
||||
|
||||
jest.mock('~/lib/utils/common_utils');
|
||||
|
||||
const terraformImagePath = '/path/to/image';
|
||||
const bannerDismissedKey = 'terraform_notification_dismissed';
|
||||
|
||||
describe('TerraformNotificationBanner', () => {
|
||||
let wrapper;
|
||||
let trackingSpy;
|
||||
let userCalloutDismissSpy;
|
||||
|
||||
const provideData = {
|
||||
terraformImagePath,
|
||||
bannerDismissedKey,
|
||||
};
|
||||
const findBanner = () => wrapper.findComponent(GlBanner);
|
||||
|
||||
beforeEach(() => {
|
||||
const createComponent = ({ shouldShowCallout = true } = {}) => {
|
||||
userCalloutDismissSpy = jest.fn();
|
||||
|
||||
wrapper = shallowMount(TerraformNotification, {
|
||||
provide: provideData,
|
||||
stubs: { GlBanner },
|
||||
stubs: {
|
||||
GlBanner,
|
||||
UserCalloutDismisser: makeMockUserCalloutDismisser({
|
||||
dismiss: userCalloutDismissSpy,
|
||||
shouldShowCallout,
|
||||
}),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
parseBoolean.mockReturnValue(false);
|
||||
unmockTracking();
|
||||
});
|
||||
|
||||
describe('when the dismiss cookie is not set', () => {
|
||||
describe('when user has already dismissed the banner', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
shouldShowCallout: false,
|
||||
});
|
||||
});
|
||||
it('should not render the banner', () => {
|
||||
expect(findBanner().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when user hasn't yet dismissed the banner", () => {
|
||||
it('should render the banner', () => {
|
||||
expect(findBanner().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when close button is clicked', () => {
|
||||
beforeEach(async () => {
|
||||
await findBanner().vm.$emit('close');
|
||||
beforeEach(() => {
|
||||
wrapper.vm.$refs.calloutDismisser.dismiss = userCalloutDismissSpy;
|
||||
findBanner().vm.$emit('close');
|
||||
});
|
||||
|
||||
it('should set the cookie with the bannerDismissedKey', () => {
|
||||
expect(setCookie).toHaveBeenCalledWith(bannerDismissedKey, true);
|
||||
});
|
||||
|
||||
it('should send the dismiss event', () => {
|
||||
expect(trackingSpy).toHaveBeenCalledWith(undefined, DISMISS_EVENT, {
|
||||
label: EVENT_LABEL,
|
||||
});
|
||||
});
|
||||
|
||||
it('should remove the banner', () => {
|
||||
expect(findBanner().exists()).toBe(false);
|
||||
it('should call the dismiss callback', () => {
|
||||
expect(userCalloutDismissSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when docs link is clicked', () => {
|
||||
beforeEach(async () => {
|
||||
await findBanner().vm.$emit('primary');
|
||||
beforeEach(() => {
|
||||
findBanner().vm.$emit('primary');
|
||||
});
|
||||
|
||||
it('should send button click event', () => {
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Gitlab::ActionCable::RequestStoreCallbacks do
|
||||
describe '.wrapper' do
|
||||
it 'enables RequestStore in the inner block' do
|
||||
expect(RequestStore.active?).to eq(false)
|
||||
|
||||
described_class.wrapper.call(
|
||||
nil,
|
||||
lambda do
|
||||
expect(RequestStore.active?).to eq(true)
|
||||
end
|
||||
)
|
||||
|
||||
expect(RequestStore.active?).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Gitlab::Database::LoadBalancing::ActionCableCallbacks, :request_store do
|
||||
describe '.wrapper' do
|
||||
it 'uses primary and then releases the connection and clears the session' do
|
||||
expect(Gitlab::Database::LoadBalancing).to receive_message_chain(:proxy, :load_balancer, :release_host)
|
||||
expect(Gitlab::Database::LoadBalancing::Session).to receive(:clear_session)
|
||||
|
||||
described_class.wrapper.call(
|
||||
nil,
|
||||
lambda do
|
||||
expect(Gitlab::Database::LoadBalancing::Session.current.use_primary?).to eq(true)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
context 'with an exception' do
|
||||
it 'releases the connection and clears the session' do
|
||||
expect(Gitlab::Database::LoadBalancing).to receive_message_chain(:proxy, :load_balancer, :release_host)
|
||||
expect(Gitlab::Database::LoadBalancing::Session).to receive(:clear_session)
|
||||
|
||||
expect do
|
||||
described_class.wrapper.call(nil, lambda { raise 'test_exception' })
|
||||
end.to raise_error('test_exception')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -69,6 +69,42 @@ RSpec.describe Gitlab::Database::LoadBalancing::Configuration do
|
|||
expect(config.pool_size).to eq(4)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the load balancing configuration uses strings as the keys' do
|
||||
let(:configuration_hash) do
|
||||
{
|
||||
pool: 4,
|
||||
load_balancing: {
|
||||
'max_replication_difference' => 1,
|
||||
'max_replication_lag_time' => 2,
|
||||
'replica_check_interval' => 3,
|
||||
'hosts' => %w[foo bar],
|
||||
'discover' => {
|
||||
'record' => 'foo.example.com'
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'uses the custom configuration settings' do
|
||||
config = described_class.for_model(model)
|
||||
|
||||
expect(config.hosts).to eq(%w[foo bar])
|
||||
expect(config.max_replication_difference).to eq(1)
|
||||
expect(config.max_replication_lag_time).to eq(2.0)
|
||||
expect(config.replica_check_interval).to eq(3.0)
|
||||
expect(config.service_discovery).to eq(
|
||||
nameserver: 'localhost',
|
||||
port: 8600,
|
||||
record: 'foo.example.com',
|
||||
record_type: 'A',
|
||||
interval: 60,
|
||||
disconnect_timeout: 120,
|
||||
use_tcp: false
|
||||
)
|
||||
expect(config.pool_size).to eq(4)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#load_balancing_enabled?' do
|
||||
|
|
|
@ -268,6 +268,16 @@ RSpec.describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
|
|||
it { is_expected.to contain_exactly(cluster) }
|
||||
end
|
||||
|
||||
describe '.with_name' do
|
||||
subject { described_class.with_name(name) }
|
||||
|
||||
let(:name) { 'this-cluster' }
|
||||
let!(:cluster) { create(:cluster, :project, name: name) }
|
||||
let!(:another_cluster) { create(:cluster, :project) }
|
||||
|
||||
it { is_expected.to contain_exactly(cluster) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
subject { cluster.valid? }
|
||||
|
||||
|
|
|
@ -974,10 +974,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
|
||||
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
|
||||
|
||||
"@gitlab/ui@32.9.1":
|
||||
version "32.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.9.1.tgz#a02a21c772cd1b9bb7f929764d587082724f8d4c"
|
||||
integrity sha512-Cx9BGC5KJ1KPphRC+J90GPxDATTf3s1y01VMgXngXPB2ZJMl75aue3swBOsAmgre91NL4RUqiG+TJMmMCs3xuA==
|
||||
"@gitlab/ui@32.10.0":
|
||||
version "32.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.10.0.tgz#7c6ff39d2dc0b770237289dedf2eee46a618021b"
|
||||
integrity sha512-Kr4sDomMmxOr/PgQsfJ45HCHdTjbb9UISYxwtugAGKJKha/zHmpSEtZFu0R1cLhnVUqS0Y+FSgkq2nAw3NuxIA==
|
||||
dependencies:
|
||||
"@babel/standalone" "^7.0.0"
|
||||
bootstrap-vue "2.18.1"
|
||||
|
|
Loading…
Reference in New Issue