Commit 6a4f265c authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@13-0-stable-ee

parent cba45395
...@@ -218,13 +218,16 @@ export const fetchPrometheusMetric = ( ...@@ -218,13 +218,16 @@ export const fetchPrometheusMetric = (
{ commit, state, getters }, { commit, state, getters },
{ metric, defaultQueryParams }, { metric, defaultQueryParams },
) => { ) => {
const queryParams = { ...defaultQueryParams }; let queryParams = { ...defaultQueryParams };
if (metric.step) { if (metric.step) {
queryParams.step = metric.step; queryParams.step = metric.step;
} }
if (Object.keys(state.promVariables).length > 0) { if (Object.keys(state.promVariables).length > 0) {
queryParams.variables = getters.getCustomVariablesArray; queryParams = {
...queryParams,
...getters.getCustomVariablesParams,
};
} }
commit(types.REQUEST_METRIC_RESULT, { metricId: metric.metricId }); commit(types.REQUEST_METRIC_RESULT, { metricId: metric.metricId });
......
import { flatMap } from 'lodash';
import { NOT_IN_DB_PREFIX } from '../constants'; import { NOT_IN_DB_PREFIX } from '../constants';
import { addPrefixToCustomVariableParams } from './utils';
const metricsIdsInPanel = panel => const metricsIdsInPanel = panel =>
panel.metrics.filter(metric => metric.metricId && metric.result).map(metric => metric.metricId); panel.metrics.filter(metric => metric.metricId && metric.result).map(metric => metric.metricId);
...@@ -116,13 +116,27 @@ export const filteredEnvironments = state => ...@@ -116,13 +116,27 @@ export const filteredEnvironments = state =>
* Maps an variables object to an array along with stripping * Maps an variables object to an array along with stripping
* the variable prefix. * the variable prefix.
* *
* This method outputs an object in the below format
*
* {
* variables[key1]=value1,
* variables[key2]=value2,
* }
*
* This is done so that the backend can identify the custom
* user-defined variables coming through the URL and differentiate
* from other variables used for Prometheus API endpoint.
*
* @param {Object} variables - Custom variables provided by the user * @param {Object} variables - Custom variables provided by the user
* @returns {Array} The custom variables array to be send to the API * @returns {Array} The custom variables array to be send to the API
* in the format of [variable1, variable1_value] * in the format of {variables[key1]=value1, variables[key2]=value2}
*/ */
export const getCustomVariablesArray = state => export const getCustomVariablesParams = state =>
flatMap(state.promVariables, (variable, key) => [key, variable.value]); Object.keys(state.promVariables).reduce((acc, variable) => {
acc[addPrefixToCustomVariableParams(variable)] = state.promVariables[variable]?.value;
return acc;
}, {});
// prevent babel-plugin-rewire from generating an invalid default during karma tests // prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {}; export default () => {};
...@@ -229,3 +229,19 @@ export const normalizeQueryResult = timeSeries => { ...@@ -229,3 +229,19 @@ export const normalizeQueryResult = timeSeries => {
return normalizedResult; return normalizedResult;
}; };
/**
* Custom variables defined in the dashboard yml file are
* eventually passed over the wire to the backend Prometheus
* API proxy.
*
* This method adds a prefix to the URL param keys so that
* the backend can differential these variables from the other
* variables.
*
* This is currently only used by getters/getCustomVariablesParams
*
* @param {String} key Variable key that needs to be prefixed
* @returns {String}
*/
export const addPrefixToCustomVariableParams = key => `variables[${key}]`;
...@@ -113,7 +113,7 @@ class Projects::ArtifactsController < Projects::ApplicationController ...@@ -113,7 +113,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
def build def build
@build ||= begin @build ||= begin
build = build_from_id || build_from_ref build = build_from_id || build_from_sha || build_from_ref
build&.present(current_user: current_user) build&.present(current_user: current_user)
end end
end end
...@@ -127,7 +127,8 @@ class Projects::ArtifactsController < Projects::ApplicationController ...@@ -127,7 +127,8 @@ class Projects::ArtifactsController < Projects::ApplicationController
project.builds.find_by_id(params[:job_id]) if params[:job_id] project.builds.find_by_id(params[:job_id]) if params[:job_id]
end end
def build_from_ref def build_from_sha
return if params[:job].blank?
return unless @ref_name return unless @ref_name
commit = project.commit(@ref_name) commit = project.commit(@ref_name)
...@@ -136,6 +137,13 @@ class Projects::ArtifactsController < Projects::ApplicationController ...@@ -136,6 +137,13 @@ class Projects::ArtifactsController < Projects::ApplicationController
project.latest_successful_build_for_sha(params[:job], commit.id) project.latest_successful_build_for_sha(params[:job], commit.id)
end end
def build_from_ref
return if params[:job].blank?
return unless @ref_name
project.latest_successful_build_for_ref(params[:job], @ref_name)
end
def artifacts_file def artifacts_file
@artifacts_file ||= build&.artifacts_file_for_type(params[:file_type] || :archive) @artifacts_file ||= build&.artifacts_file_for_type(params[:file_type] || :archive)
end end
......
...@@ -32,8 +32,8 @@ module Prometheus ...@@ -32,8 +32,8 @@ module Prometheus
def validate_variables(_result) def validate_variables(_result)
return success unless variables return success unless variables
unless variables.is_a?(Array) && variables.size.even? unless variables.is_a?(ActionController::Parameters)
return error(_('Optional parameter "variables" must be an array of keys and values. Ex: [key1, value1, key2, value2]')) return error(_('Optional parameter "variables" must be a Hash. Ex: variables[key1]=value1'))
end end
success success
...@@ -88,12 +88,7 @@ module Prometheus ...@@ -88,12 +88,7 @@ module Prometheus
end end
def variables_hash def variables_hash
# .each_slice(2) converts ['key1', 'value1', 'key2', 'value2'] into variables.to_h
# [['key1', 'value1'], ['key2', 'value2']] which is then converted into
# a hash by to_h: {'key1' => 'value1', 'key2' => 'value2'}
# to_h will raise an ArgumentError if the number of elements in the original
# array is not even.
variables&.each_slice(2).to_h
end end
def query(result) def query(result)
......
...@@ -70,7 +70,7 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker ...@@ -70,7 +70,7 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
def send_new_branch(project, repo_name, committer, branch) def send_new_branch(project, repo_name, committer, branch)
repo_path = project.full_path repo_path = project.full_path
newbranch = "#{Gitlab.config.gitlab.url}/#{repo_path}/branches" newbranch = "#{Gitlab.config.gitlab.url}/#{repo_path}/-/branches"
newbranch = "\x0302\x1f#{newbranch}\x0f" if @colors newbranch = "\x0302\x1f#{newbranch}\x0f" if @colors
privmsg = "[#{repo_name}] #{committer} has created a new branch " \ privmsg = "[#{repo_name}] #{committer} has created a new branch " \
...@@ -124,7 +124,7 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker ...@@ -124,7 +124,7 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
def compare_url(data, repo_path) def compare_url(data, repo_path)
sha1 = Commit.truncate_sha(data['before']) sha1 = Commit.truncate_sha(data['before'])
sha2 = Commit.truncate_sha(data['after']) sha2 = Commit.truncate_sha(data['after'])
compare_url = "#{Gitlab.config.gitlab.url}/#{repo_path}/compare" \ compare_url = "#{Gitlab.config.gitlab.url}/#{repo_path}/-/compare" \
"/#{sha1}...#{sha2}" "/#{sha1}...#{sha2}"
colorize_url compare_url colorize_url compare_url
end end
......
---
title: Change format of variables parameter in Prometheus proxy API for metrics dashboard
merge_request: 33062
author:
type: fixed
---
title: Fix Geo replication for design thumbnails
merge_request: 32703
author:
type: fixed
---
title: Fix Auto DevOps manual rollout jobs not being allowed to fail
merge_request: 32865
author:
type: fixed
---
title: Fixed redirection to project snippets
merge_request: 32530
author:
type: fixed
---
title: Update deprecated routes in irker integration
merge_request: 32923
author: Marc Jeanmougin
type: fixed
---
title: Fix 404s downloading build artifacts
merge_request: 32741
author:
type: fixed
...@@ -453,7 +453,7 @@ DAST can be [configured](#customizing-the-dast-settings) using environment varia ...@@ -453,7 +453,7 @@ DAST can be [configured](#customizing-the-dast-settings) using environment varia
| `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` | no | Requires [domain validation](#domain-validation) when running DAST full scans. Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. Not supported for API scans. | | `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` | no | Requires [domain validation](#domain-validation) when running DAST full scans. Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. Not supported for API scans. |
| `DAST_AUTO_UPDATE_ADDONS` | no | By default the versions of ZAP add-ons are pinned to those provided with the DAST image. Set to `true` to allow ZAP to download the latest versions. | | `DAST_AUTO_UPDATE_ADDONS` | no | By default the versions of ZAP add-ons are pinned to those provided with the DAST image. Set to `true` to allow ZAP to download the latest versions. |
| `DAST_API_HOST_OVERRIDE` | no | Used to override domains defined in API specification files. | | `DAST_API_HOST_OVERRIDE` | no | Used to override domains defined in API specification files. |
| `DAST_EXCLUDE_RULES` | no | Set to a comma-separated list of Vulnerability Rule IDs to exclude them from scans. Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://github.com/zaproxy/zaproxy/blob/master/docs/scanners.md). For example, `HTTP Parameter Override` has a rule ID of `10026`. | | `DAST_EXCLUDE_RULES` | no | Set to a comma-separated list of Vulnerability Rule IDs to exclude them from the scan report. Currently, excluded rules will get executed but the alerts from them will be suppressed. Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://github.com/zaproxy/zaproxy/blob/develop/docs/scanners.md). For example, `HTTP Parameter Override` has a rule ID of `10026`. |
| `DAST_REQUEST_HEADERS` | no | Set to a comma-separated list of request header names and values. For example, `Cache-control: no-cache,User-Agent: DAST/1.0` | | `DAST_REQUEST_HEADERS` | no | Set to a comma-separated list of request header names and values. For example, `Cache-control: no-cache,User-Agent: DAST/1.0` |
| `DAST_ZAP_USE_AJAX_SPIDER` | no | Use the AJAX spider in addition to the traditional spider, useful for crawling sites that require JavaScript. Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. | | `DAST_ZAP_USE_AJAX_SPIDER` | no | Use the AJAX spider in addition to the traditional spider, useful for crawling sites that require JavaScript. Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. |
......
...@@ -88,6 +88,23 @@ or more users or by the `@name` of one or more groups that should ...@@ -88,6 +88,23 @@ or more users or by the `@name` of one or more groups that should
be owners of the file. Groups must be added as [members of the project](members/index.md), be owners of the file. Groups must be added as [members of the project](members/index.md),
or they will be ignored. or they will be ignored.
Starting in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/32432), you can now specify
groups or subgroups from the project's group hierarchy as potential code owners.
For example, consider the following hierarchy for a given project:
```text
group >> sub-group >> sub-subgroup >> myproject >> file.md
```
Any of the following groups would be eligible to be specified as code owners:
- `@group`
- `@group/sub-group`
- `@group/sub-group/sub-subgroup`
In addition, any groups that have been invited to the project using the **Settings > Members** tool will also be recognized as eligible code owners.
The order in which the paths are defined is significant: the last The order in which the paths are defined is significant: the last
pattern that matches a given path will be used to find the code pattern that matches a given path will be used to find the code
owners. owners.
......
...@@ -86,6 +86,7 @@ staging: ...@@ -86,6 +86,7 @@ staging:
canary: canary:
extends: .auto-deploy extends: .auto-deploy
stage: canary stage: canary
allow_failure: true
script: script:
- auto-deploy check_kube_domain - auto-deploy check_kube_domain
- auto-deploy download_chart - auto-deploy download_chart
...@@ -176,6 +177,7 @@ production_manual: ...@@ -176,6 +177,7 @@ production_manual:
.manual_rollout_template: &manual_rollout_template .manual_rollout_template: &manual_rollout_template
<<: *rollout_template <<: *rollout_template
stage: production stage: production
allow_failure: true
rules: rules:
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""' - if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
when: never when: never
......
...@@ -14881,7 +14881,7 @@ msgstr "" ...@@ -14881,7 +14881,7 @@ msgstr ""
msgid "Optional" msgid "Optional"
msgstr "" msgstr ""
msgid "Optional parameter \"variables\" must be an array of keys and values. Ex: [key1, value1, key2, value2]" msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr "" msgstr ""
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab." msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
require 'spec_helper' require 'spec_helper'
describe Projects::ArtifactsController do describe Projects::ArtifactsController do
include RepoHelpers
let(:user) { project.owner } let(:user) { project.owner }
let_it_be(:project) { create(:project, :repository, :public) } let_it_be(:project) { create(:project, :repository, :public) }
...@@ -481,6 +483,22 @@ describe Projects::ArtifactsController do ...@@ -481,6 +483,22 @@ describe Projects::ArtifactsController do
expect(response).to redirect_to(path) expect(response).to redirect_to(path)
end end
end end
context 'with a failed pipeline on an updated master' do
before do
create_file_in_repo(project, 'master', 'master', 'test.txt', 'This is test')
create(:ci_pipeline,
project: project,
sha: project.commit.sha,
ref: project.default_branch,
status: 'failed')
get :latest_succeeded, params: params_from_ref(project.default_branch)
end
it_behaves_like 'redirect to the job'
end
end end
end end
end end
...@@ -84,12 +84,12 @@ describe Projects::Environments::PrometheusApiController do ...@@ -84,12 +84,12 @@ describe Projects::Environments::PrometheusApiController do
before do before do
expected_params[:query] = %{up{pod_name="#{pod_name}"}} expected_params[:query] = %{up{pod_name="#{pod_name}"}}
expected_params[:variables] = ['pod_name', pod_name] expected_params[:variables] = { 'pod_name' => pod_name }
end end
it 'replaces variables with values' do it 'replaces variables with values' do
get :proxy, params: environment_params.merge( get :proxy, params: environment_params.merge(
query: 'up{pod_name="{{pod_name}}"}', variables: ['pod_name', pod_name] query: 'up{pod_name="{{pod_name}}"}', variables: { 'pod_name' => pod_name }
) )
expect(response).to have_gitlab_http_status(:success) expect(response).to have_gitlab_http_status(:success)
......
...@@ -32,5 +32,11 @@ describe "User downloads artifacts" do ...@@ -32,5 +32,11 @@ describe "User downloads artifacts" do
it_behaves_like "downloading" it_behaves_like "downloading"
end end
context "via SHA" do
let(:url) { latest_succeeded_project_artifacts_path(project, "#{pipeline.sha}/download", job: job.name) }
it_behaves_like "downloading"
end
end end
end end
...@@ -329,7 +329,7 @@ describe('Monitoring store Getters', () => { ...@@ -329,7 +329,7 @@ describe('Monitoring store Getters', () => {
}); });
}); });
describe('getCustomVariablesArray', () => { describe('getCustomVariablesParams', () => {
let state; let state;
beforeEach(() => { beforeEach(() => {
...@@ -340,25 +340,21 @@ describe('Monitoring store Getters', () => { ...@@ -340,25 +340,21 @@ describe('Monitoring store Getters', () => {
it('transforms the promVariables object to an array in the [variable, variable_value] format for all variable types', () => { it('transforms the promVariables object to an array in the [variable, variable_value] format for all variable types', () => {
mutations[types.SET_VARIABLES](state, mockTemplatingDataResponses.allVariableTypes); mutations[types.SET_VARIABLES](state, mockTemplatingDataResponses.allVariableTypes);
const variablesArray = getters.getCustomVariablesArray(state); const variablesArray = getters.getCustomVariablesParams(state);
expect(variablesArray).toEqual([ expect(variablesArray).toEqual({
'simpleText', 'variables[advCustomNormal]': 'value2',
'Simple text', 'variables[advText]': 'default',
'advText', 'variables[simpleCustom]': 'value1',
'default', 'variables[simpleText]': 'Simple text',
'simpleCustom', });
'value1',
'advCustomNormal',
'value2',
]);
}); });
it('transforms the promVariables object to an empty array when no keys are present', () => { it('transforms the promVariables object to an empty array when no keys are present', () => {
mutations[types.SET_VARIABLES](state, {}); mutations[types.SET_VARIABLES](state, {});
const variablesArray = getters.getCustomVariablesArray(state); const variablesArray = getters.getCustomVariablesParams(state);
expect(variablesArray).toEqual([]); expect(variablesArray).toEqual({});
}); });
}); });
......
...@@ -64,7 +64,7 @@ describe Prometheus::ProxyVariableSubstitutionService do ...@@ -64,7 +64,7 @@ describe Prometheus::ProxyVariableSubstitutionService do
let(:params_keys) do let(:params_keys) do
{ {
query: 'up{pod_name="{{pod_name}}"}', query: 'up{pod_name="{{pod_name}}"}',
variables: ['pod_name', pod_name] variables: { 'pod_name' => pod_name }
} }
end end
...@@ -76,7 +76,7 @@ describe Prometheus::ProxyVariableSubstitutionService do ...@@ -76,7 +76,7 @@ describe Prometheus::ProxyVariableSubstitutionService do
let(:params_keys) do let(:params_keys) do
{ {
query: 'up{pod_name="{{pod_name}}",env="{{ci_environment_slug}}"}', query: 'up{pod_name="{{pod_name}}",env="{{ci_environment_slug}}"}',
variables: ['pod_name', pod_name, 'ci_environment_slug', 'custom_value'] variables: { 'pod_name' => pod_name, 'ci_environment_slug' => 'custom_value' }
} }
end end
...@@ -95,8 +95,7 @@ describe Prometheus::ProxyVariableSubstitutionService do ...@@ -95,8 +95,7 @@ describe Prometheus::ProxyVariableSubstitutionService do
} }
end end
it_behaves_like 'error', 'Optional parameter "variables" must be an ' \ it_behaves_like 'error', 'Optional parameter "variables" must be a Hash. Ex: variables[key1]=value1'
'array of keys and values. Ex: [key1, value1, key2, value2]'
end end
context 'with nil variables' do context 'with nil variables' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment