Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
930ff68c1e
commit
274ea604fc
|
@ -100,7 +100,7 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="prometheus-graph col-12 col-lg-6">
|
<div class="prometheus-graph">
|
||||||
<div class="prometheus-graph-header">
|
<div class="prometheus-graph-header">
|
||||||
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphData.title }}</h5>
|
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphData.title }}</h5>
|
||||||
<div ref="graphWidgets" class="prometheus-graph-widgets"><slot></slot></div>
|
<div ref="graphWidgets" class="prometheus-graph-widgets"><slot></slot></div>
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="prometheus-graph col-12 col-lg-6 d-flex flex-column justify-content-center">
|
<div class="prometheus-graph d-flex flex-column justify-content-center">
|
||||||
<div class="prometheus-graph-header">
|
<div class="prometheus-graph-header">
|
||||||
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphTitle }}</h5>
|
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphTitle }}</h5>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,7 +29,7 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="prometheus-graph col-12 col-lg-6">
|
<div class="prometheus-graph">
|
||||||
<div class="prometheus-graph-header">
|
<div class="prometheus-graph-header">
|
||||||
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphTitle }}</h5>
|
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphTitle }}</h5>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -43,11 +43,6 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
showBorder: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
singleEmbed: {
|
singleEmbed: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -272,71 +267,66 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div class="prometheus-graph">
|
||||||
class="prometheus-graph col-12"
|
<div class="prometheus-graph-header">
|
||||||
:class="[showBorder ? 'p-2' : 'p-0', { 'col-lg-6': !singleEmbed }]"
|
<h5 class="prometheus-graph-title js-graph-title">{{ graphData.title }}</h5>
|
||||||
>
|
<gl-button
|
||||||
<div :class="{ 'prometheus-graph-embed w-100 p-3': showBorder }">
|
v-if="exportMetricsToCsvEnabled"
|
||||||
<div class="prometheus-graph-header">
|
:href="downloadLink"
|
||||||
<h5 class="prometheus-graph-title js-graph-title">{{ graphData.title }}</h5>
|
:title="__('Download CSV')"
|
||||||
<gl-button
|
:aria-label="__('Download CSV')"
|
||||||
v-if="exportMetricsToCsvEnabled"
|
style="margin-left: 200px;"
|
||||||
:href="downloadLink"
|
download="chart_metrics.csv"
|
||||||
:title="__('Download CSV')"
|
|
||||||
:aria-label="__('Download CSV')"
|
|
||||||
style="margin-left: 200px;"
|
|
||||||
download="chart_metrics.csv"
|
|
||||||
>
|
|
||||||
{{ __('Download CSV') }}
|
|
||||||
</gl-button>
|
|
||||||
<div class="prometheus-graph-widgets js-graph-widgets">
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<component
|
|
||||||
:is="glChartComponent"
|
|
||||||
ref="chart"
|
|
||||||
v-bind="$attrs"
|
|
||||||
:data="chartData"
|
|
||||||
:option="chartOptions"
|
|
||||||
:format-tooltip-text="formatTooltipText"
|
|
||||||
:thresholds="thresholds"
|
|
||||||
:width="width"
|
|
||||||
:height="height"
|
|
||||||
@updated="onChartUpdated"
|
|
||||||
>
|
>
|
||||||
<template v-if="tooltip.isDeployment">
|
{{ __('Download CSV') }}
|
||||||
<template slot="tooltipTitle">
|
</gl-button>
|
||||||
{{ __('Deployed') }}
|
<div class="prometheus-graph-widgets js-graph-widgets">
|
||||||
</template>
|
<slot></slot>
|
||||||
<div slot="tooltipContent" class="d-flex align-items-center">
|
</div>
|
||||||
<icon name="commit" class="mr-2" />
|
</div>
|
||||||
<gl-link :href="tooltip.commitUrl">{{ tooltip.sha }}</gl-link>
|
|
||||||
|
<component
|
||||||
|
:is="glChartComponent"
|
||||||
|
ref="chart"
|
||||||
|
v-bind="$attrs"
|
||||||
|
:data="chartData"
|
||||||
|
:option="chartOptions"
|
||||||
|
:format-tooltip-text="formatTooltipText"
|
||||||
|
:thresholds="thresholds"
|
||||||
|
:width="width"
|
||||||
|
:height="height"
|
||||||
|
@updated="onChartUpdated"
|
||||||
|
>
|
||||||
|
<template v-if="tooltip.isDeployment">
|
||||||
|
<template slot="tooltipTitle">
|
||||||
|
{{ __('Deployed') }}
|
||||||
|
</template>
|
||||||
|
<div slot="tooltipContent" class="d-flex align-items-center">
|
||||||
|
<icon name="commit" class="mr-2" />
|
||||||
|
<gl-link :href="tooltip.commitUrl">{{ tooltip.sha }}</gl-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<template slot="tooltipTitle">
|
||||||
|
<div class="text-nowrap">
|
||||||
|
{{ tooltip.title }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template slot="tooltipContent">
|
||||||
<template slot="tooltipTitle">
|
<div
|
||||||
<div class="text-nowrap">
|
v-for="(content, key) in tooltip.content"
|
||||||
{{ tooltip.title }}
|
:key="key"
|
||||||
|
class="d-flex justify-content-between"
|
||||||
|
>
|
||||||
|
<gl-chart-series-label :color="isMultiSeries ? content.color : ''">
|
||||||
|
{{ content.name }}
|
||||||
|
</gl-chart-series-label>
|
||||||
|
<div class="prepend-left-32">
|
||||||
|
{{ content.value }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</div>
|
||||||
<template slot="tooltipContent">
|
|
||||||
<div
|
|
||||||
v-for="(content, key) in tooltip.content"
|
|
||||||
:key="key"
|
|
||||||
class="d-flex justify-content-between"
|
|
||||||
>
|
|
||||||
<gl-chart-series-label :color="isMultiSeries ? content.color : ''">
|
|
||||||
{{ content.name }}
|
|
||||||
</gl-chart-series-label>
|
|
||||||
<div class="prepend-left-32">
|
|
||||||
{{ content.value }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
</component>
|
</template>
|
||||||
</div>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -456,6 +456,7 @@ export default {
|
||||||
<panel-type
|
<panel-type
|
||||||
v-for="(graphData, graphIndex) in groupData.metrics"
|
v-for="(graphData, graphIndex) in groupData.metrics"
|
||||||
:key="`panel-type-${graphIndex}`"
|
:key="`panel-type-${graphIndex}`"
|
||||||
|
class="col-12 col-lg-6 pb-3"
|
||||||
:clipboard-text="generateLink(groupData.group, graphData.title, graphData.y_label)"
|
:clipboard-text="generateLink(groupData.group, graphData.title, graphData.y_label)"
|
||||||
:graph-data="graphData"
|
:graph-data="graphData"
|
||||||
:dashboard-width="elWidth"
|
:dashboard-width="elWidth"
|
||||||
|
@ -468,6 +469,7 @@ export default {
|
||||||
<monitor-time-series-chart
|
<monitor-time-series-chart
|
||||||
v-for="(graphData, graphIndex) in chartsWithData(groupData.metrics)"
|
v-for="(graphData, graphIndex) in chartsWithData(groupData.metrics)"
|
||||||
:key="graphIndex"
|
:key="graphIndex"
|
||||||
|
class="col-12 col-lg-6 pb-3"
|
||||||
:graph-data="graphData"
|
:graph-data="graphData"
|
||||||
:deployment-data="deploymentData"
|
:deployment-data="deploymentData"
|
||||||
:thresholds="getGraphAlertValues(graphData.queries)"
|
:thresholds="getGraphAlertValues(graphData.queries)"
|
||||||
|
|
|
@ -95,6 +95,7 @@ export default {
|
||||||
<monitor-time-series-chart
|
<monitor-time-series-chart
|
||||||
v-for="graphData in charts"
|
v-for="graphData in charts"
|
||||||
:key="graphData.title"
|
:key="graphData.title"
|
||||||
|
class="w-100"
|
||||||
:graph-data="graphData"
|
:graph-data="graphData"
|
||||||
:container-width="elWidth"
|
:container-width="elWidth"
|
||||||
group-id="monitor-area-chart"
|
group-id="monitor-area-chart"
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
import Vue from 'vue';
|
|
||||||
import _ from 'underscore';
|
|
||||||
import axios from '../../lib/utils/axios_utils';
|
import axios from '../../lib/utils/axios_utils';
|
||||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||||
|
|
||||||
let vueResourceInterceptor;
|
|
||||||
|
|
||||||
export default class PerformanceBarService {
|
export default class PerformanceBarService {
|
||||||
static fetchRequestDetails(peekUrl, requestId) {
|
static fetchRequestDetails(peekUrl, requestId) {
|
||||||
return axios.get(peekUrl, { params: { request_id: requestId } });
|
return axios.get(peekUrl, { params: { request_id: requestId } });
|
||||||
|
@ -24,16 +20,11 @@ export default class PerformanceBarService {
|
||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
|
|
||||||
vueResourceInterceptor = (request, next) => next(interceptor);
|
|
||||||
|
|
||||||
Vue.http.interceptors.push(vueResourceInterceptor);
|
|
||||||
|
|
||||||
return axios.interceptors.response.use(interceptor);
|
return axios.interceptors.response.use(interceptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static removeInterceptor(interceptor) {
|
static removeInterceptor(interceptor) {
|
||||||
axios.interceptors.response.eject(interceptor);
|
axios.interceptors.response.eject(interceptor);
|
||||||
Vue.http.interceptors = _.without(Vue.http.interceptors, vueResourceInterceptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static callbackParams(response, peekUrl) {
|
static callbackParams(response, peekUrl) {
|
||||||
|
|
|
@ -29,10 +29,6 @@
|
||||||
.author-link {
|
.author-link {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.issuable-comments {
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-merge-request-unmerged {
|
.icon-merge-request-unmerged {
|
||||||
|
|
|
@ -461,10 +461,6 @@
|
||||||
.author-link {
|
.author-link {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.issuable-comments {
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.merge-request-title {
|
.merge-request-title {
|
||||||
|
|
|
@ -6,15 +6,16 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
||||||
before_action :set_application_setting
|
before_action :set_application_setting
|
||||||
before_action :whitelist_query_limiting, only: [:usage_data]
|
before_action :whitelist_query_limiting, only: [:usage_data]
|
||||||
|
|
||||||
VALID_SETTING_PANELS = %w(show integrations repository templates
|
VALID_SETTING_PANELS = %w(general integrations repository templates
|
||||||
ci_cd reporting metrics_and_profiling
|
ci_cd reporting metrics_and_profiling
|
||||||
network geo preferences).freeze
|
network geo preferences).freeze
|
||||||
|
|
||||||
def show
|
VALID_SETTING_PANELS.each do |action|
|
||||||
|
define_method(action) { perform_update if submitted? }
|
||||||
end
|
end
|
||||||
|
|
||||||
(VALID_SETTING_PANELS - %w(show)).each do |action|
|
def show
|
||||||
define_method(action) { perform_update if submitted? }
|
render :general
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
@ -144,7 +145,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_update_error
|
def render_update_error
|
||||||
action = VALID_SETTING_PANELS.include?(action_name) ? action_name : :show
|
action = VALID_SETTING_PANELS.include?(action_name) ? action_name : :general
|
||||||
|
|
||||||
render action
|
render action
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= form_for @application_setting, url: admin_application_settings_path(anchor: 'js-account-settings'), html: { class: 'fieldset-form' } do |f|
|
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-account-settings'), html: { class: 'fieldset-form' } do |f|
|
||||||
= form_errors(@application_setting)
|
= form_errors(@application_setting)
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= form_for @application_setting, url: admin_application_settings_path(anchor: 'js-merge-request-settings'), html: { class: 'fieldset-form' } do |f|
|
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-merge-request-settings'), html: { class: 'fieldset-form' } do |f|
|
||||||
= form_errors(@application_setting)
|
= form_errors(@application_setting)
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
= _('External Classification Policy Authorization')
|
= _('External Classification Policy Authorization')
|
||||||
.settings-content
|
.settings-content
|
||||||
|
|
||||||
= form_for @application_setting, url: admin_application_settings_path(anchor: 'js-external-auth-settings'), html: { class: 'fieldset-form' } do |f|
|
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-external-auth-settings'), html: { class: 'fieldset-form' } do |f|
|
||||||
= form_errors(@application_setting)
|
= form_errors(@application_setting)
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= form_for @application_setting, url: admin_application_settings_path(anchor: 'js-signin-settings'), html: { class: 'fieldset-form' } do |f|
|
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-signin-settings'), html: { class: 'fieldset-form' } do |f|
|
||||||
= form_errors(@application_setting)
|
= form_errors(@application_setting)
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= form_for @application_setting, url: admin_application_settings_path(anchor: 'js-signup-settings'), html: { class: 'fieldset-form' } do |f|
|
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-signup-settings'), html: { class: 'fieldset-form' } do |f|
|
||||||
= form_errors(@application_setting)
|
= form_errors(@application_setting)
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= form_for @application_setting, url: admin_application_settings_path(anchor: 'js-terminal-settings'), html: { class: 'fieldset-form' } do |f|
|
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-terminal-settings'), html: { class: 'fieldset-form' } do |f|
|
||||||
= form_errors(@application_setting)
|
= form_errors(@application_setting)
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= form_for @application_setting, url: admin_application_settings_path(anchor: 'js-terms-settings'), html: { class: 'fieldset-form' } do |f|
|
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-terms-settings'), html: { class: 'fieldset-form' } do |f|
|
||||||
= form_errors(@application_setting)
|
= form_errors(@application_setting)
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= form_for @application_setting, url: admin_application_settings_path(anchor: 'js-visibility-settings'), html: { class: 'fieldset-form' } do |f|
|
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-visibility-settings'), html: { class: 'fieldset-form' } do |f|
|
||||||
= form_errors(@application_setting)
|
= form_errors(@application_setting)
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- breadcrumb_title _("Settings")
|
- breadcrumb_title _("General")
|
||||||
- page_title _("Settings")
|
- page_title _("General")
|
||||||
- @content_class = "limit-container-width" unless fluid_layout
|
- @content_class = "limit-container-width" unless fluid_layout
|
||||||
|
|
||||||
%section.settings.as-visibility-access.no-animate#js-visibility-settings{ class: ('expanded' if expanded_by_default?) }
|
%section.settings.as-visibility-access.no-animate#js-visibility-settings{ class: ('expanded' if expanded_by_default?) }
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
%p
|
%p
|
||||||
= _('Manage Web IDE features')
|
= _('Manage Web IDE features')
|
||||||
.settings-content
|
.settings-content
|
||||||
= form_for @application_setting, url: admin_application_settings_path(anchor: "#js-web-ide-settings"), html: { class: 'fieldset-form' } do |f|
|
= form_for @application_setting, url: general_admin_application_settings_path(anchor: "#js-web-ide-settings"), html: { class: 'fieldset-form' } do |f|
|
||||||
= form_errors(@application_setting)
|
= form_errors(@application_setting)
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
|
@ -232,7 +232,7 @@
|
||||||
= _('Settings')
|
= _('Settings')
|
||||||
%li.divider.fly-out-top-item
|
%li.divider.fly-out-top-item
|
||||||
= nav_link(path: 'application_settings#show') do
|
= nav_link(path: 'application_settings#show') do
|
||||||
= link_to admin_application_settings_path, title: _('General'), class: 'qa-admin-settings-general-item' do
|
= link_to general_admin_application_settings_path, title: _('General'), class: 'qa-admin-settings-general-item' do
|
||||||
%span
|
%span
|
||||||
= _('General')
|
= _('General')
|
||||||
= nav_link(path: 'application_settings#integrations') do
|
= nav_link(path: 'application_settings#integrations') do
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
.col-lg-3
|
.col-lg-3
|
||||||
%h4.prepend-top-0
|
%h4.prepend-top-0
|
||||||
= @service.title
|
= @service.title
|
||||||
= boolean_to_icon @service.activated?
|
- [true, false].each do |value|
|
||||||
|
- hide_class = 'd-none' if @service.activated? != value
|
||||||
|
%span.js-service-active-status{ class: hide_class, data: { value: value.to_s } }
|
||||||
|
= boolean_to_icon value
|
||||||
%p= #{@service.description}.
|
%p= #{@service.description}.
|
||||||
|
|
||||||
- if @service.respond_to?(:detailed_description)
|
- if @service.respond_to?(:detailed_description)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Remove vue-resource from PerformanceBarService
|
||||||
|
merge_request: 32428
|
||||||
|
author: Lee Tickett
|
||||||
|
type: other
|
|
@ -110,7 +110,7 @@ namespace :admin do
|
||||||
put :reset_registration_token
|
put :reset_registration_token
|
||||||
put :reset_health_check_token
|
put :reset_health_check_token
|
||||||
put :clear_repository_check_states
|
put :clear_repository_check_states
|
||||||
match :integrations, :repository, :templates, :ci_cd, :reporting, :metrics_and_profiling, :network, :geo, :preferences, via: [:get, :patch]
|
match :general, :integrations, :repository, :templates, :ci_cd, :reporting, :metrics_and_profiling, :network, :geo, :preferences, via: [:get, :patch]
|
||||||
get :lets_encrypt_terms_of_service
|
get :lets_encrypt_terms_of_service
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,8 @@ GET /groups/:id/epics?state=opened
|
||||||
| `created_before` | datetime | no | Return epics created on or before the given time |
|
| `created_before` | datetime | no | Return epics created on or before the given time |
|
||||||
| `updated_after` | datetime | no | Return epics updated on or after the given time |
|
| `updated_after` | datetime | no | Return epics updated on or after the given time |
|
||||||
| `updated_before` | datetime | no | Return epics updated on or before the given time |
|
| `updated_before` | datetime | no | Return epics updated on or before the given time |
|
||||||
|
| `include_ancestor_groups` | boolean | no | Include epics from the requested group's ancestors. Default is `false` |
|
||||||
|
| `include_descendant_groups` | boolean | no | Include epics from the requested group's descendants. Default is `true` |
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics
|
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/1/epics
|
||||||
|
|
|
@ -11,7 +11,7 @@ in [GitLab Ultimate](https://about.gitlab.com/pricing/) 10.4.
|
||||||
|
|
||||||
If you are using [GitLab CI/CD](../../../ci/README.md), you can check your Docker
|
If you are using [GitLab CI/CD](../../../ci/README.md), you can check your Docker
|
||||||
images (or more precisely the containers) for known vulnerabilities by using
|
images (or more precisely the containers) for known vulnerabilities by using
|
||||||
[Clair](https://github.com/coreos/clair) and [clair-scanner](https://github.com/arminc/clair-scanner),
|
[Clair](https://github.com/coreos/clair) and [klar](https://github.com/optiopay/klar),
|
||||||
two open source tools for Vulnerability Static Analysis for containers.
|
two open source tools for Vulnerability Static Analysis for containers.
|
||||||
|
|
||||||
You can take advantage of Container Scanning by either [including the CI job](#configuration) in
|
You can take advantage of Container Scanning by either [including the CI job](#configuration) in
|
||||||
|
@ -90,10 +90,6 @@ artifact available. Behind the scenes, the
|
||||||
[GitLab Container Scanning analyzer](https://gitlab.com/gitlab-org/security-products/container-scanning)
|
[GitLab Container Scanning analyzer](https://gitlab.com/gitlab-org/security-products/container-scanning)
|
||||||
is used and runs the scans.
|
is used and runs the scans.
|
||||||
|
|
||||||
If you want to whitelist some specific vulnerabilities, you can do so by defining
|
|
||||||
them in a YAML file named `clair-whitelist.yml`. Read more in the
|
|
||||||
[Clair documentation](https://github.com/arminc/clair-scanner/blob/master/README.md#example-whitelist-yaml-file).
|
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
The following is a sample `.gitlab-ci.yml` that will build your Docker Image, push it to the container registry and run Container Scanning.
|
The following is a sample `.gitlab-ci.yml` that will build your Docker Image, push it to the container registry and run Container Scanning.
|
||||||
|
@ -124,6 +120,31 @@ build:
|
||||||
- docker push $IMAGE
|
- docker push $IMAGE
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Vulnerability Whitelisting
|
||||||
|
|
||||||
|
If you want to whitelist specific vulnerabilities, you'll need to:
|
||||||
|
|
||||||
|
1. Set `GIT_STRATEGY: fetch` in your `.gitlab-ci.yml` file by following the instructions described in the
|
||||||
|
[overriding the Container Scanning template](#overriding-the-container-scanning-template) section of this document.
|
||||||
|
1. Define the whitelisted vulnerabilities in a YAML file named `clair-whitelist.yml` which must use the format described
|
||||||
|
in the [following whitelist example file](https://github.com/arminc/clair-scanner/blob/v12/example-whitelist.yaml).
|
||||||
|
1. Add the `clair-whitelist.yml` file to the git repository of your project
|
||||||
|
|
||||||
|
### Overriding the Container Scanning template
|
||||||
|
|
||||||
|
If you want to override the job definition (for example, change properties like
|
||||||
|
`variables`), you need to declare a `container_scanning` job after the
|
||||||
|
template inclusion and specify any additional keys under it. For example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
include:
|
||||||
|
- template: Container-Scanning.gitlab-ci.yml
|
||||||
|
|
||||||
|
container_scanning:
|
||||||
|
variables:
|
||||||
|
GIT_STRATEGY: fetch
|
||||||
|
```
|
||||||
|
|
||||||
## Security Dashboard
|
## Security Dashboard
|
||||||
|
|
||||||
The Security Dashboard is a good place to get an overview of all the security
|
The Security Dashboard is a good place to get an overview of all the security
|
||||||
|
|
|
@ -120,6 +120,8 @@ A feature flag may be enabled for a list of target users. It is implemented
|
||||||
using the Unleash [`userWithId`](https://unleash.github.io/docs/activation_strategy#userwithid)
|
using the Unleash [`userWithId`](https://unleash.github.io/docs/activation_strategy#userwithid)
|
||||||
activation strategy.
|
activation strategy.
|
||||||
|
|
||||||
|
The feature will always be enabled for all users in the list across all environments even if the matching environment spec **Status** is disabled.
|
||||||
|
|
||||||
![Feature flag target users](img/target_users_v12_2.png)
|
![Feature flag target users](img/target_users_v12_2.png)
|
||||||
|
|
||||||
CAUTION: **Caution:**
|
CAUTION: **Caution:**
|
||||||
|
|
|
@ -7,7 +7,7 @@ module QA
|
||||||
class General < Page::Base
|
class General < Page::Base
|
||||||
include QA::Page::Settings::Common
|
include QA::Page::Settings::Common
|
||||||
|
|
||||||
view 'app/views/admin/application_settings/show.html.haml' do
|
view 'app/views/admin/application_settings/general.html.haml' do
|
||||||
element :account_and_limit_settings
|
element :account_and_limit_settings
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -118,32 +118,7 @@ describe Admin::ApplicationSettingsController do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'verify panel actions' do
|
describe 'verify panel actions' do
|
||||||
shared_examples 'renders correct panels' do
|
(Admin::ApplicationSettingsController::VALID_SETTING_PANELS - %w(templates geo)).each do |valid_action|
|
||||||
it 'renders correct action on error' do
|
|
||||||
expect_next_instance_of(ApplicationSettings::UpdateService) do |service|
|
|
||||||
allow(service).to receive(:execute).and_return(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
patch action, params: { application_setting: { unused_param: true } }
|
|
||||||
|
|
||||||
expect(subject).to render_template(action)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'redirects to same panel on success' do
|
|
||||||
expect_next_instance_of(ApplicationSettings::UpdateService) do |service|
|
|
||||||
allow(service).to receive(:execute).and_return(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
referer_path = public_send("#{action}_admin_application_settings_path")
|
|
||||||
request.env["HTTP_REFERER"] = referer_path
|
|
||||||
|
|
||||||
patch action, params: { application_setting: { unused_param: true } }
|
|
||||||
|
|
||||||
expect(subject).to redirect_to(referer_path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
(Admin::ApplicationSettingsController::VALID_SETTING_PANELS - %w(show templates geo)).each do |valid_action|
|
|
||||||
it_behaves_like 'renders correct panels' do
|
it_behaves_like 'renders correct panels' do
|
||||||
let(:action) { valid_action }
|
let(:action) { valid_action }
|
||||||
end
|
end
|
||||||
|
|
|
@ -76,6 +76,7 @@ describe 'Admin disables Git access protocol', :js do
|
||||||
context 'with nothing disabled' do
|
context 'with nothing disabled' do
|
||||||
before do
|
before do
|
||||||
create(:personal_key, user: admin)
|
create(:personal_key, user: admin)
|
||||||
|
allow_all_protocols
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows default SSH url and protocol selection dropdown' do
|
it 'shows default SSH url and protocol selection dropdown' do
|
||||||
|
@ -107,6 +108,10 @@ describe 'Admin disables Git access protocol', :js do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def allow_all_protocols
|
||||||
|
switch_git_protocol(1)
|
||||||
|
end
|
||||||
|
|
||||||
def disable_http_protocol
|
def disable_http_protocol
|
||||||
switch_git_protocol(2)
|
switch_git_protocol(2)
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,7 +15,7 @@ describe 'Admin updates settings' do
|
||||||
|
|
||||||
context 'General page' do
|
context 'General page' do
|
||||||
before do
|
before do
|
||||||
visit admin_application_settings_path
|
visit general_admin_application_settings_path
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'Change visibility settings' do
|
it 'Change visibility settings' do
|
||||||
|
|
|
@ -26,7 +26,7 @@ describe Admin::ApplicationSettingsController, '(JavaScript fixtures)', type: :c
|
||||||
it 'application_settings/accounts_and_limit.html' do
|
it 'application_settings/accounts_and_limit.html' do
|
||||||
stub_application_setting(user_default_external: false)
|
stub_application_setting(user_default_external: false)
|
||||||
|
|
||||||
get :show
|
get :general
|
||||||
|
|
||||||
expect(response).to be_successful
|
expect(response).to be_successful
|
||||||
end
|
end
|
||||||
|
|
|
@ -210,7 +210,7 @@ if (process.env.BABEL_ENV === 'coverage') {
|
||||||
'./terminal/terminal_bundle.js',
|
'./terminal/terminal_bundle.js',
|
||||||
'./users/users_bundle.js',
|
'./users/users_bundle.js',
|
||||||
'./issue_show/index.js',
|
'./issue_show/index.js',
|
||||||
'./pages/admin/application_settings/show/index.js',
|
'./pages/admin/application_settings/general/index.js',
|
||||||
];
|
];
|
||||||
|
|
||||||
describe('Uncovered files', function() {
|
describe('Uncovered files', function() {
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
shared_examples 'renders correct panels' do
|
||||||
|
it 'renders correct action on error' do
|
||||||
|
expect_next_instance_of(ApplicationSettings::UpdateService) do |service|
|
||||||
|
allow(service).to receive(:execute).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
patch action, params: { application_setting: { unused_param: true } }
|
||||||
|
|
||||||
|
expect(subject).to render_template(action)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'redirects to same panel on success' do
|
||||||
|
expect_next_instance_of(ApplicationSettings::UpdateService) do |service|
|
||||||
|
allow(service).to receive(:execute).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
referer_path = public_send("#{action}_admin_application_settings_path")
|
||||||
|
request.env["HTTP_REFERER"] = referer_path
|
||||||
|
|
||||||
|
patch action, params: { application_setting: { unused_param: true } }
|
||||||
|
|
||||||
|
expect(subject).to redirect_to(referer_path)
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue