提交 20bd3b7d 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 90156f52
6730c101d0be2db5155b6e2c4de689dc906337f4 187f550dce577f1fb39503976a30a73a58b2b8e1
...@@ -14,8 +14,6 @@ module Clusters ...@@ -14,8 +14,6 @@ module Clusters
end end
def execute(artifact) def execute(artifact)
return success unless Feature.enabled?(:cluster_applications_artifact, project)
raise ArgumentError, 'Artifact is not cluster_applications file type' unless artifact&.cluster_applications? raise ArgumentError, 'Artifact is not cluster_applications file type' unless artifact&.cluster_applications?
return error(too_big_error_message, :bad_request) unless artifact.file.size < MAX_ACCEPTABLE_ARTIFACT_SIZE return error(too_big_error_message, :bad_request) unless artifact.file.size < MAX_ACCEPTABLE_ARTIFACT_SIZE
......
---
title: Enable state tracking for managed applications installed via the management project
merge_request: 38759
author:
type: added
...@@ -2907,6 +2907,56 @@ type DastSiteProfilePermissions { ...@@ -2907,6 +2907,56 @@ type DastSiteProfilePermissions {
createOnDemandDastScan: Boolean! createOnDemandDastScan: Boolean!
} }
"""
Autogenerated input type of DastSiteProfileUpdate
"""
input DastSiteProfileUpdateInput {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
The project the site profile belongs to.
"""
fullPath: ID!
"""
ID of the site profile to be updated.
"""
id: DastSiteProfileID!
"""
The name of the site profile.
"""
profileName: String!
"""
The URL of the target to be scanned.
"""
targetUrl: String
}
"""
Autogenerated return type of DastSiteProfileUpdate
"""
type DastSiteProfileUpdatePayload {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Errors encountered during execution of the mutation.
"""
errors: [String!]!
"""
ID of the site profile.
"""
id: DastSiteProfileID
}
enum DastSiteProfileValidationStatusEnum { enum DastSiteProfileValidationStatusEnum {
""" """
Site validation process finished but failed Site validation process finished but failed
...@@ -9349,6 +9399,7 @@ type Mutation { ...@@ -9349,6 +9399,7 @@ type Mutation {
dastScannerProfileCreate(input: DastScannerProfileCreateInput!): DastScannerProfileCreatePayload dastScannerProfileCreate(input: DastScannerProfileCreateInput!): DastScannerProfileCreatePayload
dastSiteProfileCreate(input: DastSiteProfileCreateInput!): DastSiteProfileCreatePayload dastSiteProfileCreate(input: DastSiteProfileCreateInput!): DastSiteProfileCreatePayload
dastSiteProfileDelete(input: DastSiteProfileDeleteInput!): DastSiteProfileDeletePayload dastSiteProfileDelete(input: DastSiteProfileDeleteInput!): DastSiteProfileDeletePayload
dastSiteProfileUpdate(input: DastSiteProfileUpdateInput!): DastSiteProfileUpdatePayload
deleteAnnotation(input: DeleteAnnotationInput!): DeleteAnnotationPayload deleteAnnotation(input: DeleteAnnotationInput!): DeleteAnnotationPayload
designManagementDelete(input: DesignManagementDeleteInput!): DesignManagementDeletePayload designManagementDelete(input: DesignManagementDeleteInput!): DesignManagementDeletePayload
designManagementMove(input: DesignManagementMoveInput!): DesignManagementMovePayload designManagementMove(input: DesignManagementMoveInput!): DesignManagementMovePayload
......
...@@ -7876,6 +7876,146 @@ ...@@ -7876,6 +7876,146 @@
"enumValues": null, "enumValues": null,
"possibleTypes": null "possibleTypes": null
}, },
{
"kind": "INPUT_OBJECT",
"name": "DastSiteProfileUpdateInput",
"description": "Autogenerated input type of DastSiteProfileUpdate",
"fields": null,
"inputFields": [
{
"name": "fullPath",
"description": "The project the site profile belongs to.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "id",
"description": "ID of the site profile to be updated.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "DastSiteProfileID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "profileName",
"description": "The name of the site profile.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "targetUrl",
"description": "The URL of the target to be scanned.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
}
],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "DastSiteProfileUpdatePayload",
"description": "Autogenerated return type of DastSiteProfileUpdate",
"fields": [
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "errors",
"description": "Errors encountered during execution of the mutation.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "id",
"description": "ID of the site profile.",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "DastSiteProfileID",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{ {
"kind": "ENUM", "kind": "ENUM",
"name": "DastSiteProfileValidationStatusEnum", "name": "DastSiteProfileValidationStatusEnum",
...@@ -26800,6 +26940,33 @@ ...@@ -26800,6 +26940,33 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "dastSiteProfileUpdate",
"description": null,
"args": [
{
"name": "input",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "DastSiteProfileUpdateInput",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "DastSiteProfileUpdatePayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "deleteAnnotation", "name": "deleteAnnotation",
"description": null, "description": null,
...@@ -487,6 +487,16 @@ Check permissions for the current user on site profile ...@@ -487,6 +487,16 @@ Check permissions for the current user on site profile
| --- | ---- | ---------- | | --- | ---- | ---------- |
| `createOnDemandDastScan` | Boolean! | Indicates the user can perform `create_on_demand_dast_scan` on this resource | | `createOnDemandDastScan` | Boolean! | Indicates the user can perform `create_on_demand_dast_scan` on this resource |
## DastSiteProfileUpdatePayload
Autogenerated return type of DastSiteProfileUpdate
| Name | Type | Description |
| --- | ---- | ---------- |
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
| `id` | DastSiteProfileID | ID of the site profile. |
## DeleteAnnotationPayload ## DeleteAnnotationPayload
Autogenerated return type of DeleteAnnotation Autogenerated return type of DeleteAnnotation
......
...@@ -423,7 +423,10 @@ In the following example: ...@@ -423,7 +423,10 @@ In the following example:
#### Custom collapsible sections #### Custom collapsible sections
You can create collapsible sections in job logs by manually outputting special codes > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/14664) in GitLab 12.0.
You can create [collapsible sections in job logs](../pipelines/index.md#expand-and-collapse-job-log-sections)
by manually outputting special codes
that GitLab uses to determine what sections to collapse: that GitLab uses to determine what sections to collapse:
- Section start marker: `section_start:UNIX_TIMESTAMP:SECTION_NAME\r\e[0K` + `TEXT_OF_SECTION_HEADER` - Section start marker: `section_start:UNIX_TIMESTAMP:SECTION_NAME\r\e[0K` + `TEXT_OF_SECTION_HEADER`
......
...@@ -828,6 +828,10 @@ $ tr a-z A-Z << END_TEXT # collapsed multi-line command ...@@ -828,6 +828,10 @@ $ tr a-z A-Z << END_TEXT # collapsed multi-line command
FOUR FIVE SIX FOUR FIVE SIX
``` ```
#### Custom collapsible sections
See [custom collapsible sections](../pipelines/index.md#custom-collapsible-sections).
### `stage` ### `stage`
`stage` is defined per-job and relies on [`stages`](#stages) which is defined `stage` is defined per-job and relies on [`stages`](#stages) which is defined
......
...@@ -946,6 +946,11 @@ management project. Refer to the ...@@ -946,6 +946,11 @@ management project. Refer to the
[Cilium chart](https://github.com/cilium/cilium/tree/master/install/kubernetes/cilium) [Cilium chart](https://github.com/cilium/cilium/tree/master/install/kubernetes/cilium)
for the available configuration options. for the available configuration options.
You can check Cilium's installation status on the cluster management page:
- [Project-level cluster](../project/clusters/index.md): Navigate to your project's **Operations > Kubernetes** page.
- [Group-level cluster](../group/clusters/index.md): Navigate to your group's **Kubernetes** page.
CAUTION: **Caution:** CAUTION: **Caution:**
Installation and removal of the Cilium requires a **manual** Installation and removal of the Cilium requires a **manual**
[restart](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-gke/#restart-unmanaged-pods) [restart](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-gke/#restart-unmanaged-pods)
......
...@@ -130,6 +130,67 @@ definition they will be able to execute privileged Docker commands on the Runner ...@@ -130,6 +130,67 @@ definition they will be able to execute privileged Docker commands on the Runner
host. Having proper access control policies mitigates this attack vector by host. Having proper access control policies mitigates this attack vector by
allowing access only to trusted actors. allowing access only to trusted actors.
### Disabling the code quality job
The `code_quality` job will not run if the `$CODE_QUALITY_DISABLED` environment
variable is present. Please refer to the environment variables [documentation](../../../ci/variables/README.md)
to learn more about how to define one.
To disable the `code_quality` job, add `CODE_QUALITY_DISABLED` as a custom environment
variable. This can be done:
- For the whole project, [in the project settings](../../../ci/variables/README.md#create-a-custom-variable-in-the-ui)
or [CI/CD configuration](../../../ci/variables/README.md#create-a-custom-variable-in-the-ui).
- For a single pipeline run:
1. Go to **CI/CD > Pipelines**
1. Click **Run Pipeline**
1. Add `CODE_QUALITY_DISABLED` as the variable key, with any value.
### Using with merge request pipelines
The configuration provided by the Code Quality template does not let the `code_quality` job
run on [pipelines for merge requests](../../../ci/merge_request_pipelines/index.md).
If pipelines for merge requests is enabled, the `code_quality:rules` must be redefined.
The template has these [`rules`](../../../ci/yaml/README.md#rules) for the `code quality` job:
```yaml
code_quality:
rules:
- if: '$CODE_QUALITY_DISABLED'
when: never
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
```
If you are using merge request pipelines, your `rules` (or [`workflow: rules`](../../../ci/yaml/README.md#workflowrules))
might look like this example:
```yaml
job1:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # Run job1 in merge request pipelines
- if: '$CI_COMMIT_BRANCH == "master"' # Run job1 in pipelines on the master branch (but not in other branch pipelines)
- if: '$CI_COMMIT_TAG' # Run job1 in pipelines for tags
```
To make these work together, you will need to overwrite the code quality `rules`
so that they match your current `rules`. From the example above, it could look like:
```yaml
include:
- template: Code-Quality.gitlab-ci.yml
code_quality:
rules:
- if: '$CODE_QUALITY_DISABLED'
when: never
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # Run code quality job in merge request pipelines
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' # Run code quality job in pipelines on the master branch (but not in other branch pipelines)
- if: '$CI_COMMIT_TAG' # Run code quality job in pipelines for tags
```
## Configuring jobs using variables ## Configuring jobs using variables
The Code Quality job supports environment variables that users can set to The Code Quality job supports environment variables that users can set to
......
# frozen_string_literal: true
module Gitlab
class SidekiqLogger < Gitlab::Logger
def self.file_name_noext
'sidekiq'
end
end
end
...@@ -36,105 +36,89 @@ RSpec.describe Clusters::ParseClusterApplicationsArtifactService do ...@@ -36,105 +36,89 @@ RSpec.describe Clusters::ParseClusterApplicationsArtifactService do
let(:job) { deployment.deployable } let(:job) { deployment.deployable }
let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job) } let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job) }
context 'when cluster_applications_artifact feature flag is disabled' do it 'calls Gitlab::Kubernetes::Helm::Parsers::ListV2' do
before do expect(Gitlab::Kubernetes::Helm::Parsers::ListV2).to receive(:new).and_call_original
stub_feature_flags(cluster_applications_artifact: false)
end
it 'does not call Gitlab::Kubernetes::Helm::Parsers::ListV2 and returns success immediately' do
expect(Gitlab::Kubernetes::Helm::Parsers::ListV2).not_to receive(:new)
result = described_class.new(job, user).execute(artifact) result = described_class.new(job, user).execute(artifact)
expect(result[:status]).to eq(:success) expect(result[:status]).to eq(:success)
end
end end
context 'when cluster_applications_artifact feature flag is enabled for project' do context 'artifact is not of cluster_applications type' do
before do let(:artifact) { create(:ci_job_artifact, :archive) }
stub_feature_flags(cluster_applications_artifact: job.project) let(:job) { artifact.job }
it 'raise ArgumentError' do
expect do
described_class.new(job, user).execute(artifact)
end.to raise_error(ArgumentError, 'Artifact is not cluster_applications file type')
end end
end
it 'calls Gitlab::Kubernetes::Helm::Parsers::ListV2' do context 'artifact exceeds acceptable size' do
expect(Gitlab::Kubernetes::Helm::Parsers::ListV2).to receive(:new).and_call_original it 'returns an error' do
stub_const("#{described_class}::MAX_ACCEPTABLE_ARTIFACT_SIZE", 1.byte)
result = described_class.new(job, user).execute(artifact) result = described_class.new(job, user).execute(artifact)
expect(result[:status]).to eq(:success) expect(result[:status]).to eq(:error)
expect(result[:message]).to eq('Cluster_applications artifact too big. Maximum allowable size: 1 Byte')
end end
end
context 'artifact is not of cluster_applications type' do context 'job has no deployment' do
let(:artifact) { create(:ci_job_artifact, :archive) } let(:job) { build(:ci_build) }
let(:job) { artifact.job }
it 'raise ArgumentError' do it 'returns an error' do
expect do result = described_class.new(job, user).execute(artifact)
described_class.new(job, user).execute(artifact)
end.to raise_error(ArgumentError, 'Artifact is not cluster_applications file type') expect(result[:status]).to eq(:error)
end expect(result[:message]).to eq('No deployment found for this job')
end end
end
context 'artifact exceeds acceptable size' do context 'job has no deployment cluster' do
it 'returns an error' do let(:deployment) { create(:deployment) }
stub_const("#{described_class}::MAX_ACCEPTABLE_ARTIFACT_SIZE", 1.byte) let(:job) { deployment.deployable }
result = described_class.new(job, user).execute(artifact) it 'returns an error' do
result = described_class.new(job, user).execute(artifact)
expect(result[:status]).to eq(:error) expect(result[:status]).to eq(:error)
expect(result[:message]).to eq('Cluster_applications artifact too big. Maximum allowable size: 1 Byte') expect(result[:message]).to eq('No deployment cluster found for this job')
end
end end
end
context 'job has no deployment' do context 'blob is empty' do
let(:job) { build(:ci_build) } let(:file) { fixture_file_upload(Rails.root.join("spec/fixtures/helm/helm_list_v2_empty_blob.json.gz")) }
let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job, file: file) }
it 'returns an error' do it 'returns success' do
result = described_class.new(job, user).execute(artifact) result = described_class.new(job, user).execute(artifact)
expect(result[:status]).to eq(:error) expect(result[:status]).to eq(:success)
expect(result[:message]).to eq('No deployment found for this job')
end
end end
end
context 'job has no deployment cluster' do context 'job has deployment cluster' do
let(:deployment) { create(:deployment) } context 'current user does not have access to deployment cluster' do
let(:job) { deployment.deployable } let(:other_user) { create(:user) }
it 'returns an error' do it 'returns an error' do
result = described_class.new(job, user).execute(artifact) result = described_class.new(job, other_user).execute(artifact)
expect(result[:status]).to eq(:error) expect(result[:status]).to eq(:error)
expect(result[:message]).to eq('No deployment cluster found for this job') expect(result[:message]).to eq('No deployment cluster found for this job')
end end
end end
context 'blob is empty' do it 'does not affect unpermitted cluster applications' do
let(:file) { fixture_file_upload(Rails.root.join("spec/fixtures/helm/helm_list_v2_empty_blob.json.gz")) } expect(Clusters::ParseClusterApplicationsArtifactService::RELEASE_NAMES).to contain_exactly('cilium')
let(:artifact) { create(:ci_job_artifact, :cluster_applications, job: job, file: file) }
it 'returns success' do
result = described_class.new(job, user).execute(artifact)
expect(result[:status]).to eq(:success)
end
end end
context 'job has deployment cluster' do Clusters::ParseClusterApplicationsArtifactService::RELEASE_NAMES.each do |release_name|
context 'current user does not have access to deployment cluster' do context release_name do
let(:other_user) { create(:user) } include_examples 'parse cluster applications artifact', release_name
it 'returns an error' do
result = described_class.new(job, other_user).execute(artifact)
expect(result[:status]).to eq(:error)
expect(result[:message]).to eq('No deployment cluster found for this job')
end
end
Clusters::ParseClusterApplicationsArtifactService::RELEASE_NAMES.each do |release_name|
context release_name do
include_examples 'parse cluster applications artifact', release_name
end
end end
end end
end end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册