Commit 8078bd18 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 8f210aeb
<script>
import { GlHeatmap } from '@gitlab/ui/dist/charts';
import dateformat from 'dateformat';
import PrometheusHeader from '../shared/prometheus_header.vue';
import ResizableChartContainer from '~/vue_shared/components/resizable_chart/resizable_chart_container.vue';
import { graphDataValidatorForValues } from '../../utils';
export default {
components: {
GlHeatmap,
ResizableChartContainer,
PrometheusHeader,
},
props: {
graphData: {
type: Object,
required: true,
validator: graphDataValidatorForValues.bind(null, false),
},
containerWidth: {
type: Number,
required: true,
},
},
computed: {
chartData() {
return this.queries.result.reduce(
(acc, result, i) => [...acc, ...result.values.map((value, j) => [i, j, value[1]])],
[],
);
},
xAxisName() {
return this.graphData.x_label || '';
},
yAxisName() {
return this.graphData.y_label || '';
},
xAxisLabels() {
return this.queries.result.map(res => Object.values(res.metric)[0]);
},
yAxisLabels() {
return this.result.values.map(val => {
const [yLabel] = val;
return dateformat(new Date(yLabel), 'HH:MM:ss');
});
},
result() {
return this.queries.result[0];
},
queries() {
return this.graphData.queries[0];
},
},
};
</script>
<template>
<div class="prometheus-graph col-12 col-lg-6">
<prometheus-header :graph-title="graphData.title" />
<resizable-chart-container>
<gl-heatmap
ref="heatmapChart"
v-bind="$attrs"
:data-series="chartData"
:x-axis-name="xAxisName"
:y-axis-name="yAxisName"
:x-axis-labels="xAxisLabels"
:y-axis-labels="yAxisLabels"
:width="containerWidth"
/>
</resizable-chart-container>
</div>
</template>
...@@ -13,6 +13,7 @@ import Icon from '~/vue_shared/components/icon.vue'; ...@@ -13,6 +13,7 @@ import Icon from '~/vue_shared/components/icon.vue';
import MonitorTimeSeriesChart from './charts/time_series.vue'; import MonitorTimeSeriesChart from './charts/time_series.vue';
import MonitorAnomalyChart from './charts/anomaly.vue'; import MonitorAnomalyChart from './charts/anomaly.vue';
import MonitorSingleStatChart from './charts/single_stat.vue'; import MonitorSingleStatChart from './charts/single_stat.vue';
import MonitorHeatmapChart from './charts/heatmap.vue';
import MonitorEmptyChart from './charts/empty_chart.vue'; import MonitorEmptyChart from './charts/empty_chart.vue';
import TrackEventDirective from '~/vue_shared/directives/track_event'; import TrackEventDirective from '~/vue_shared/directives/track_event';
import { downloadCSVOptions, generateLinkToChartOptions } from '../utils'; import { downloadCSVOptions, generateLinkToChartOptions } from '../utils';
...@@ -20,6 +21,7 @@ import { downloadCSVOptions, generateLinkToChartOptions } from '../utils'; ...@@ -20,6 +21,7 @@ import { downloadCSVOptions, generateLinkToChartOptions } from '../utils';
export default { export default {
components: { components: {
MonitorSingleStatChart, MonitorSingleStatChart,
MonitorHeatmapChart,
MonitorEmptyChart, MonitorEmptyChart,
Icon, Icon,
GlDropdown, GlDropdown,
...@@ -99,6 +101,11 @@ export default { ...@@ -99,6 +101,11 @@ export default {
v-if="isPanelType('single-stat') && graphDataHasMetrics" v-if="isPanelType('single-stat') && graphDataHasMetrics"
:graph-data="graphData" :graph-data="graphData"
/> />
<monitor-heatmap-chart
v-else-if="isPanelType('heatmap') && graphDataHasMetrics"
:graph-data="graphData"
:container-width="dashboardWidth"
/>
<component <component
:is="monitorChartComponent" :is="monitorChartComponent"
v-else-if="graphDataHasMetrics" v-else-if="graphDataHasMetrics"
......
<script>
export default {
props: {
graphTitle: {
type: String,
required: true,
},
},
};
</script>
<template>
<div class="prometheus-graph-header">
<h5 class="prometheus-graph-title js-graph-title">{{ graphTitle }}</h5>
</div>
</template>
...@@ -4,7 +4,7 @@ class Ldap::OmniauthCallbacksController < OmniauthCallbacksController ...@@ -4,7 +4,7 @@ class Ldap::OmniauthCallbacksController < OmniauthCallbacksController
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
def self.define_providers! def self.define_providers!
return unless Gitlab::Auth::LDAP::Config.enabled? return unless Gitlab::Auth::LDAP::Config.sign_in_enabled?
Gitlab::Auth::LDAP::Config.available_servers.each do |server| Gitlab::Auth::LDAP::Config.available_servers.each do |server|
alias_method server['provider_name'], :ldap alias_method server['provider_name'], :ldap
...@@ -14,6 +14,8 @@ class Ldap::OmniauthCallbacksController < OmniauthCallbacksController ...@@ -14,6 +14,8 @@ class Ldap::OmniauthCallbacksController < OmniauthCallbacksController
# We only find ourselves here # We only find ourselves here
# if the authentication to LDAP was successful. # if the authentication to LDAP was successful.
def ldap def ldap
return unless Gitlab::Auth::LDAP::Config.sign_in_enabled?
sign_in_user_flow(Gitlab::Auth::LDAP::User) sign_in_user_flow(Gitlab::Auth::LDAP::User)
end end
......
...@@ -270,7 +270,13 @@ class SessionsController < Devise::SessionsController ...@@ -270,7 +270,13 @@ class SessionsController < Devise::SessionsController
end end
def ldap_servers def ldap_servers
@ldap_servers ||= Gitlab::Auth::LDAP::Config.available_servers @ldap_servers ||= begin
if Gitlab::Auth::LDAP::Config.sign_in_enabled?
Gitlab::Auth::LDAP::Config.available_servers
else
[]
end
end
end end
def unverified_anonymous_user? def unverified_anonymous_user?
......
...@@ -8,6 +8,10 @@ module AuthHelper ...@@ -8,6 +8,10 @@ module AuthHelper
Gitlab::Auth::LDAP::Config.enabled? Gitlab::Auth::LDAP::Config.enabled?
end end
def ldap_sign_in_enabled?
Gitlab::Auth::LDAP::Config.sign_in_enabled?
end
def omniauth_enabled? def omniauth_enabled?
Gitlab::Auth.omniauth_enabled? Gitlab::Auth.omniauth_enabled?
end end
...@@ -56,6 +60,16 @@ module AuthHelper ...@@ -56,6 +60,16 @@ module AuthHelper
auth_providers.select { |provider| form_based_provider?(provider) } auth_providers.select { |provider| form_based_provider?(provider) }
end end
def any_form_based_providers_enabled?
form_based_providers.any? { |provider| form_enabled_for_sign_in?(provider) }
end
def form_enabled_for_sign_in?(provider)
return true unless provider.to_s.match?(LDAP_PROVIDER)
ldap_sign_in_enabled?
end
def crowd_enabled? def crowd_enabled?
auth_providers.include? :crowd auth_providers.include? :crowd
end end
......
- if form_based_providers.any? - if any_form_based_providers_enabled?
- if password_authentication_enabled_for_web? - if password_authentication_enabled_for_web?
.login-box.tab-pane{ id: 'login-pane', role: 'tabpanel' } .login-box.tab-pane{ id: 'login-pane', role: 'tabpanel' }
......
- page_title "Sign in" - page_title "Sign in"
#signin-container #signin-container
- if form_based_providers.any? - if any_form_based_providers_enabled?
= render 'devise/shared/tabs_ldap' = render 'devise/shared/tabs_ldap'
- else - else
- unless experiment_enabled?(:signup_flow) - unless experiment_enabled?(:signup_flow)
= render 'devise/shared/tabs_normal' = render 'devise/shared/tabs_normal'
.tab-content .tab-content
- if password_authentication_enabled_for_web? || ldap_enabled? || crowd_enabled? - if password_authentication_enabled_for_web? || ldap_sign_in_enabled? || crowd_enabled?
= render 'devise/shared/signin_box' = render 'devise/shared/signin_box'
-# Signup only makes sense if you can also sign-in -# Signup only makes sense if you can also sign-in
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
= render 'devise/shared/signup_box' = render 'devise/shared/signup_box'
-# Show a message if none of the mechanisms above are enabled -# Show a message if none of the mechanisms above are enabled
- if !password_authentication_enabled_for_web? && !ldap_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?) - if !password_authentication_enabled_for_web? && !ldap_sign_in_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?)
%div %div
No authentication methods configured. No authentication methods configured.
......
- if form_based_providers.any? - if any_form_based_providers_enabled?
- if crowd_enabled? - if crowd_enabled?
.login-box.tab-pane{ id: "crowd", role: 'tabpanel', class: active_when(form_based_auth_provider_has_active_class?(:crowd)) } .login-box.tab-pane{ id: "crowd", role: 'tabpanel', class: active_when(form_based_auth_provider_has_active_class?(:crowd)) }
.login-body .login-body
......
%ul.nav-links.new-session-tabs.nav-tabs.nav{ class: ('custom-provider-tabs' if form_based_providers.any?) } %ul.nav-links.new-session-tabs.nav-tabs.nav{ class: ('custom-provider-tabs' if any_form_based_providers_enabled?) }
- if crowd_enabled? - if crowd_enabled?
%li.nav-item %li.nav-item
= link_to "Crowd", "#crowd", class: "nav-link #{active_when(form_based_auth_provider_has_active_class?(:crowd))}", 'data-toggle' => 'tab' = link_to "Crowd", "#crowd", class: "nav-link #{active_when(form_based_auth_provider_has_active_class?(:crowd))}", 'data-toggle' => 'tab'
......
...@@ -73,5 +73,19 @@ class StuckCiJobsWorker ...@@ -73,5 +73,19 @@ class StuckCiJobsWorker
Gitlab::OptimisticLocking.retry_lock(build, 3) do |b| Gitlab::OptimisticLocking.retry_lock(build, 3) do |b|
b.drop(reason) b.drop(reason)
end end
rescue => ex
build.doom!
track_exception_for_build(ex, build)
end
def track_exception_for_build(ex, build)
Gitlab::Sentry.track_acceptable_exception(ex, extra: {
build_id: build.id,
build_name: build.name,
build_stage: build.stage,
pipeline_id: build.pipeline_id,
project_id: build.project_id
})
end end
end end
---
title: 'Updated Auto-DevOps to kubectl v1.13.12 and helm v2.15.1'
merge_request: 19054
author: Leo Antunes
type: changed
---
title: Properly handle exceptions in StuckCiJobsWorker
merge_request: 19465
author:
type: fixed
---
title: Add prevent_ldap_sign_in option so LDAP can be used exclusively for sync
merge_request: 18749
author:
type: added
---
title: Add heatmap chart support
merge_request: 32424
author:
type: added
...@@ -494,6 +494,7 @@ production: &base ...@@ -494,6 +494,7 @@ production: &base
# bundle exec rake gitlab:ldap:check RAILS_ENV=production # bundle exec rake gitlab:ldap:check RAILS_ENV=production
ldap: ldap:
enabled: false enabled: false
prevent_ldap_sign_in: false
# This setting controls the number of seconds between LDAP permission checks # This setting controls the number of seconds between LDAP permission checks
# for each user. After this time has expired for a given user, their next # for each user. After this time has expired for a given user, their next
......
...@@ -5,6 +5,7 @@ require_relative '../smime_signature_settings' ...@@ -5,6 +5,7 @@ require_relative '../smime_signature_settings'
# Default settings # Default settings
Settings['ldap'] ||= Settingslogic.new({}) Settings['ldap'] ||= Settingslogic.new({})
Settings.ldap['enabled'] = false if Settings.ldap['enabled'].nil? Settings.ldap['enabled'] = false if Settings.ldap['enabled'].nil?
Settings.ldap['prevent_ldap_sign_in'] = false if Settings.ldap['prevent_ldap_sign_in'].blank?
Gitlab.ee do Gitlab.ee do
Settings.ldap['sync_time'] = 3600 if Settings.ldap['sync_time'].nil? Settings.ldap['sync_time'] = 3600 if Settings.ldap['sync_time'].nil?
......
...@@ -13,7 +13,7 @@ def override_omniauth(provider, controller, path_prefix = '/users/auth') ...@@ -13,7 +13,7 @@ def override_omniauth(provider, controller, path_prefix = '/users/auth')
end end
# Use custom controller for LDAP omniauth callback # Use custom controller for LDAP omniauth callback
if Gitlab::Auth::LDAP::Config.enabled? if Gitlab::Auth::LDAP::Config.sign_in_enabled?
devise_scope :user do devise_scope :user do
Gitlab::Auth::LDAP::Config.available_servers.each do |server| Gitlab::Auth::LDAP::Config.available_servers.each do |server|
override_omniauth(server['provider_name'], 'ldap/omniauth_callbacks') override_omniauth(server['provider_name'], 'ldap/omniauth_callbacks')
......
...@@ -118,6 +118,7 @@ LDAP users must have an email address set, regardless of whether it is used to l ...@@ -118,6 +118,7 @@ LDAP users must have an email address set, regardless of whether it is used to l
```ruby ```ruby
gitlab_rails['ldap_enabled'] = true gitlab_rails['ldap_enabled'] = true
gitlab_rails['prevent_ldap_sign_in'] = false
gitlab_rails['ldap_servers'] = YAML.load <<-EOS # remember to close this block with 'EOS' below gitlab_rails['ldap_servers'] = YAML.load <<-EOS # remember to close this block with 'EOS' below
## ##
## 'main' is the GitLab 'provider ID' of this LDAP server ## 'main' is the GitLab 'provider ID' of this LDAP server
...@@ -357,6 +358,7 @@ production: ...@@ -357,6 +358,7 @@ production:
# snip... # snip...
ldap: ldap:
enabled: false enabled: false
prevent_ldap_sign_in: false
servers: servers:
## ##
## 'main' is the GitLab 'provider ID' of this LDAP server ## 'main' is the GitLab 'provider ID' of this LDAP server
...@@ -493,6 +495,38 @@ the configuration option `lowercase_usernames`. By default, this configuration o ...@@ -493,6 +495,38 @@ the configuration option `lowercase_usernames`. By default, this configuration o
1. [Restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect. 1. [Restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
## Disable LDAP web sign in
It can be be useful to prevent using LDAP credentials through the web UI when
an alternative such as SAML is preferred. This allows LDAP to be used for group
sync, while also allowing your SAML identity provider to handle additional
checks like custom 2FA.
When LDAP web sign in is disabled, users will not see a **LDAP** tab on the sign in page.
This does not disable [using LDAP credentials for Git access](#git-password-authentication).
**Omnibus configuration**
1. Edit `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_rails['prevent_ldap_sign_in'] = true
```
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
**Source configuration**
1. Edit `config/gitlab.yaml`:
```yaml
production:
ldap:
prevent_ldap_sign_in: true
```
1. [Restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect.
## Encryption ## Encryption
### TLS Server Authentication ### TLS Server Authentication
......
...@@ -101,15 +101,16 @@ it's successful, we replace the main repo with the newly cloned one. ...@@ -101,15 +101,16 @@ it's successful, we replace the main repo with the newly cloned one.
### Uploads replication ### Uploads replication
File uploads are also being replicated to the **secondary** node. To File uploads are also being replicated to the **secondary** node. To
track the state of syncing, the `Geo::FileRegistry` model is used. track the state of syncing, the `Geo::UploadRegistry` model is used.
#### File Registry #### Upload Registry
Similar to the [Project Registry](#project-registry), there is a Similar to the [Project Registry](#project-registry), there is a
`Geo::FileRegistry` model that tracks the synced uploads. `Geo::UploadRegistry` model that tracks the synced uploads.
CI Job Artifacts are synced in a similar way as uploads or LFS CI Job Artifacts and LFS objects are synced in a similar way as uploads,
objects, but they are tracked by `Geo::JobArtifactRegistry` model. but they are tracked by `Geo::JobArtifactRegistry`, and `Geo::LfsObjectRegistry`
models respectively.
#### File Download Dispatch worker #### File Download Dispatch worker
......
...@@ -21,6 +21,14 @@ module Gitlab ...@@ -21,6 +21,14 @@ module Gitlab
Gitlab.config.ldap.enabled Gitlab.config.ldap.enabled
end end
def self.sign_in_enabled?
enabled? && !prevent_ldap_sign_in?
end
def self.prevent_ldap_sign_in?
Gitlab.config.ldap.prevent_ldap_sign_in
end
def self.servers def self.servers
Gitlab.config.ldap['servers']&.values || [] Gitlab.config.ldap['servers']&.values || []
end end
......
.auto-deploy: .auto-deploy:
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.1.0" image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.4.0"
dast_environment_deploy: dast_environment_deploy:
extends: .auto-deploy extends: .auto-deploy
......
.auto-deploy: .auto-deploy:
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.3.0" image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.4.0"
review: review:
extends: .auto-deploy extends: .auto-deploy
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
module Gitlab module Gitlab
module Kubernetes module Kubernetes
module Helm module Helm
HELM_VERSION = '2.14.3' HELM_VERSION = '2.15.1'
KUBECTL_VERSION = '1.11.10' KUBECTL_VERSION = '1.13.12'
NAMESPACE = 'gitlab-managed-apps' NAMESPACE = 'gitlab-managed-apps'
SERVICE_ACCOUNT = 'tiller' SERVICE_ACCOUNT = 'tiller'
CLUSTER_ROLE_BINDING = 'tiller-admin' CLUSTER_ROLE_BINDING = 'tiller-admin'
......
...@@ -11,6 +11,14 @@ describe Ldap::OmniauthCallbacksController do ...@@ -11,6 +11,14 @@ describe Ldap::OmniauthCallbacksController do
expect(request.env['warden']).to be_authenticated expect(request.env['warden']).to be_authenticated
end end
context 'with sign in prevented' do
let(:ldap_settings) { ldap_setting_defaults.merge(prevent_ldap_sign_in: true) }
it 'does not allow sign in' do
expect { post provider }.to raise_error(ActionController::UrlGenerationError)
end
end
it 'respects remember me checkbox' do it 'respects remember me checkbox' do
expect do expect do
post provider, params: { remember_me: '1' } post provider, params: { remember_me: '1' }
......
...@@ -4,6 +4,7 @@ require 'spec_helper' ...@@ -4,6 +4,7 @@ require 'spec_helper'
describe SessionsController do describe SessionsController do
include DeviseHelpers include DeviseHelpers
include LdapHelpers
describe '#new' do describe '#new' do
before do before do
...@@ -35,6 +36,30 @@ describe SessionsController do ...@@ -35,6 +36,30 @@ describe SessionsController do
end end
end end
context 'with LDAP enabled' do
before do
stub_ldap_setting(enabled: true)
end
it 'assigns ldap_servers' do
get(:new)
expect(assigns[:ldap_servers].first.to_h).to include('label' => 'ldap', 'provider_name' => 'ldapmain')
end
context 'with sign_in disabled' do
before do
stub_ldap_setting(prevent_ldap_sign_in: true)
end
it 'assigns no ldap_servers' do
get(:new)
expect(assigns[:ldap_servers]).to eq []
end
end
end
describe 'tracking data' do describe 'tracking data' do
context 'when the user is part of the experimental group' do context 'when the user is part of the experimental group' do
before do before do
......
...@@ -54,6 +54,23 @@ describe AuthHelper do ...@@ -54,6 +54,23 @@ describe AuthHelper do
end end
end end
describe 'any_form_based_providers_enabled?' do
before do
allow(Gitlab::Auth::LDAP::Config).to receive(:enabled?).and_return(true)
end
it 'detects form-based providers' do
allow(helper).to receive(:auth_providers) { [:twitter, :ldapmain] }
expect(helper.any_form_based_providers_enabled?).to be(true)
end
it 'ignores ldap providers when ldap web sign in is disabled' do
allow(helper).to receive(:auth_providers) { [:twitter, :ldapmain] }
allow(helper).to receive(:ldap_sign_in_enabled?).and_return(false)
expect(helper.any_form_based_providers_enabled?).to be(false)
end
end
describe 'enabled_button_based_providers' do describe 'enabled_button_based_providers' do
before do before do
allow(helper).to receive(:auth_providers) { [:twitter, :github] } allow(helper).to receive(:auth_providers) { [:twitter, :github] }
......
import { shallowMount } from '@vue/test-utils';
import { GlHeatmap } from '@gitlab/ui/dist/charts';
import Heatmap from '~/monitoring/components/charts/heatmap.vue';
import { graphDataPrometheusQueryRangeMultiTrack } from '../mock_data';
describe('Heatmap component', () => {
let heatmapChart;
let store;
beforeEach(() => {
heatmapChart = shallowMount(Heatmap, {
propsData: {
graphData: graphDataPrometheusQueryRangeMultiTrack,
containerWidth: 100,
},
store,
});
});
afterEach(() => {
heatmapChart.destroy();
});
describe('wrapped components', () => {
describe('GitLab UI heatmap chart', () => {
let glHeatmapChart;
beforeEach(() => {
glHeatmapChart = heatmapChart.find(GlHeatmap);
});
it('is a Vue instance', () => {
expect(glHeatmapChart.isVueInstance()).toBe(true);
});
it('should display a label on the x axis', () => {
expect(heatmapChart.vm.xAxisName).toBe(graphDataPrometheusQueryRangeMultiTrack.x_label);
});
it('should display a label on the y axis', () => {
expect(heatmapChart.vm.yAxisName).toBe(graphDataPrometheusQueryRangeMultiTrack.y_label);
});
// According to the echarts docs https://echarts.apache.org/en/option.html#series-heatmap.data
// each row of the heatmap chart is represented by an array inside another parent array
// e.g. [[0, 0, 10]], the format represents the column, the row and finally the value
// corresponding to the cell
it('should return chartData with a length of x by y, with a length of 3 per array', () => {
const row = heatmapChart.vm.chartData[0];
expect(row.length).toBe(3);
expect(heatmapChart.vm.chartData.length).toBe(30);
});
it('returns a series of labels for the x axis', () => {
const { xAxisLabels } = heatmapChart.vm;
expect(xAxisLabels.length).toBe(5);
});
it('returns a series of labels for the y axis', () => {
const { yAxisLabels } = heatmapChart.vm;
expect(yAxisLabels.length).toBe(6);
});
});
});
});
...@@ -1013,3 +1013,82 @@ export const graphDataPrometheusQueryRange = { ...@@ -1013,3 +1013,82 @@ export const graphDataPrometheusQueryRange = {
}, },
], ],
}; };
export const graphDataPrometheusQueryRangeMultiTrack = {
title: 'Super Chart A3',
type: 'heatmap',
weight: 3,
x_label: 'Status Code',
y_label: 'Time',
metrics: [],
queries: [
{
metricId: '1',
id: 'response_metrics_nginx_ingress_throughput_status_code',
query_range:
'sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[60m])) by (status_code)',
unit: 'req / sec',
label: 'Status Code',
metric_id: 1,
prometheus_endpoint_path:
'/root/rails_nodb/environments/3/prometheus/api/v1/query_range?query=sum%28rate%28nginx_upstream_responses_total%7Bupstream%3D~%22%25%7Bkube_namespace%7D-%25%7Bci_environment_slug%7D-.%2A%22%7D%5B2m%5D%29%29+by+%28status_code%29',
result: [
{
metric: { status_code: '1xx' },
values: [
['2019-08-30T15:00:00.000Z', 0],
['2019-08-30T16:00:00.000Z', 2],
['2019-08-30T17:00:00.000Z', 0],
['2019-08-30T18:00:00.000Z', 0],
['2019-08-30T19:00:00.000Z', 0],
['2019-08-30T20:00:00.000Z', 3],
],
},
{
metric: { status_code: '2xx' },
values: [
['2019-08-30T15:00:00.000Z', 1],
['2019-08-30T16:00:00.000Z', 3],
['2019-08-30T17:00:00.000Z', 6],
['2019-08-30T18:00:00.000Z', 10],
['2019-08-30T19:00:00.000Z', 8],
['2019-08-30T20:00:00.000Z', 6],
],
},
{
metric: { status_code: '3xx' },
values: [
['2019-08-30T15:00:00.000Z', 1],
['2019-08-30T16:00:00.000Z', 2],
['2019-08-30T17:00:00.000Z', 3],
['2019-08-30T18:00:00.000Z', 3],
['2019-08-30T19:00:00.000Z', 2],
['2019-08-30T20:00:00.000Z', 1],
],
},
{
metric: { status_code: '4xx' },
values: [
['2019-08-30T15:00:00.000Z', 2],
['2019-08-30T16:00:00.000Z', 0],
['2019-08-30T17:00:00.000Z', 0],
['2019-08-30T18:00:00.000Z', 2],
['2019-08-30T19:00:00.000Z', 0],
['2019-08-30T20:00:00.000Z', 2],
],
},
{
metric: { status_code: '5xx' },
values: [
['2019-08-30T15:00:00.000Z', 0],
['2019-08-30T16:00:00.000Z', 1],
['2019-08-30T17:00:00.000Z', 0],
['2019-08-30T18:00:00.000Z', 0],
['2019-08-30T19:00:00.000Z', 0],
['2019-08-30T20:00:00.000Z', 2],
],
},
],
},
],
};
import { shallowMount } from '@vue/test-utils';
import PrometheusHeader from '~/monitoring/components/shared/prometheus_header.vue';
describe('Prometheus Header component', () => {
let prometheusHeader;
beforeEach(() => {
prometheusHeader = shallowMount(PrometheusHeader, {
propsData: {
graphTitle: 'graph header',
},
});
});
afterEach(() => {
prometheusHeader.destroy();
});
describe('Prometheus header component', () => {
it('should show a title', () => {
const title = prometheusHeader.vm.$el.querySelector('.js-graph-title').textContent;
expect(title).toBe('graph header');
});
});
});
...@@ -535,4 +535,23 @@ AtlErSqafbECNDSwS5BX8yDpu5yRBJ4xegO/rNlmb8ICRYkuJapD1xXicFOsmfUK ...@@ -535,4 +535,23 @@ AtlErSqafbECNDSwS5BX8yDpu5yRBJ4xegO/rNlmb8ICRYkuJapD1xXicFOsmfUK
end end
end end
end end
describe 'sign_in_enabled?' do
using RSpec::Parameterized::TableSyntax
where(:enabled, :prevent_ldap_sign_in, :result) do
true | false | true
'true' | false | true
true | true | false
false | nil | false
end
with_them do
it do
stub_ldap_setting(enabled: enabled, prevent_ldap_sign_in: prevent_ldap_sign_in)
expect(described_class.sign_in_enabled?).to eq(result)
end
end
end
end end
...@@ -30,7 +30,7 @@ describe Gitlab::Kubernetes::Helm::Pod do ...@@ -30,7 +30,7 @@ describe Gitlab::Kubernetes::Helm::Pod do
it 'generates the appropriate specifications for the container' do it 'generates the appropriate specifications for the container' do
container = subject.generate.spec.containers.first container = subject.generate.spec.containers.first
expect(container.name).to eq('helm') expect(container.name).to eq('helm')
expect(container.image).to eq('registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/2.14.3-kube-1.11.10') expect(container.image).to eq('registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/2.15.1-kube-1.13.12')
expect(container.env.count).to eq(3) expect(container.env.count).to eq(3)
expect(container.env.map(&:name)).to match_array([:HELM_VERSION, :TILLER_NAMESPACE, :COMMAND_SCRIPT]) expect(container.env.map(&:name)).to match_array([:HELM_VERSION, :TILLER_NAMESPACE, :COMMAND_SCRIPT])
expect(container.command).to match_array(["/bin/sh"]) expect(container.command).to match_array(["/bin/sh"])
......
...@@ -277,6 +277,33 @@ describe "Authentication", "routing" do ...@@ -277,6 +277,33 @@ describe "Authentication", "routing" do
it "PUT /users/password" do it "PUT /users/password" do
expect(put("/users/password")).to route_to('passwords#update') expect(put("/users/password")).to route_to('passwords#update')
end end
context 'with LDAP configured' do
include LdapHelpers
let(:ldap_settings) { { enabled: true } }
before do
stub_ldap_setting(ldap_settings)
Rails.application.reload_routes!
end
after(:all) do
Rails.application.reload_routes!
end
it 'POST /users/auth/ldapmain/callback' do
expect(post("/users/auth/ldapmain/callback")).to route_to('ldap/omniauth_callbacks#ldapmain')
end
context 'with LDAP sign-in disabled' do
let(:ldap_settings) { { enabled: true, prevent_ldap_sign_in: true } }
it 'prevents POST /users/auth/ldapmain/callback' do
expect(post("/users/auth/ldapmain/callback")).not_to be_routable
end
end
end
end end
describe HealthCheckController, 'routing' do describe HealthCheckController, 'routing' do
......
...@@ -10,6 +10,8 @@ shared_context 'Ldap::OmniauthCallbacksController' do ...@@ -10,6 +10,8 @@ shared_context 'Ldap::OmniauthCallbacksController' do
let(:provider) { 'ldapmain' } let(:provider) { 'ldapmain' }
let(:valid_login?) { true } let(:valid_login?) { true }
let(:user) { create(:omniauth_user, extern_uid: uid, provider: provider) } let(:user) { create(:omniauth_user, extern_uid: uid, provider: provider) }
let(:ldap_setting_defaults) { { enabled: true, servers: ldap_server_config } }
let(:ldap_settings) { ldap_setting_defaults }
let(:ldap_server_config) do let(:ldap_server_config) do
{ main: ldap_config_defaults(:main) } { main: ldap_config_defaults(:main) }
end end
...@@ -23,7 +25,7 @@ shared_context 'Ldap::OmniauthCallbacksController' do ...@@ -23,7 +25,7 @@ shared_context 'Ldap::OmniauthCallbacksController' do
end end
before do before do
stub_ldap_setting(enabled: true, servers: ldap_server_config) stub_ldap_setting(ldap_settings)
described_class.define_providers! described_class.define_providers!
Rails.application.reload_routes! Rails.application.reload_routes!
...@@ -36,4 +38,8 @@ shared_context 'Ldap::OmniauthCallbacksController' do ...@@ -36,4 +38,8 @@ shared_context 'Ldap::OmniauthCallbacksController' do
after do after do
Rails.application.env_config['omniauth.auth'] = @original_env_config_omniauth_auth Rails.application.env_config['omniauth.auth'] = @original_env_config_omniauth_auth
end end
after(:all) do
Rails.application.reload_routes!
end
end end
# frozen_string_literal: true
require 'spec_helper'
describe 'devise/sessions/new' do
describe 'ldap' do
include LdapHelpers
let(:server) { { provider_name: 'ldapmain', label: 'LDAP' }.with_indifferent_access }
before do
enable_ldap
stub_devise
disable_captcha
disable_sign_up
disable_other_signin_methods
allow(view).to receive(:experiment_enabled?).and_return(false)
end
it 'is shown when enabled' do
render
expect(rendered).to have_selector('.new-session-tabs')
expect(rendered).to have_selector('[data-qa-selector="ldap_tab"]')
expect(rendered).to have_field('LDAP Username')
end
it 'is not shown when LDAP sign in is disabled' do
disable_ldap_sign_in
render
expect(rendered).to have_content('No authentication methods configured')
expect(rendered).not_to have_selector('[data-qa-selector="ldap_tab"]')
expect(rendered).not_to have_field('LDAP Username')
end
end
def disable_other_signin_methods
allow(view).to receive(:password_authentication_enabled_for_web?).and_return(false)
allow(view).to receive(:omniauth_enabled?).and_return(false)
end
def disable_sign_up
allow(view).to receive(:allow_signup?).and_return(false)
end
def stub_devise
allow(view).to receive(:devise_mapping).and_return(Devise.mappings[:user])
allow(view).to receive(:resource).and_return(spy)
allow(view).to receive(:resource_name).and_return(:user)
end
def enable_ldap
stub_ldap_setting(enabled: true)
assign(:ldap_servers, [server])
allow(view).to receive(:form_based_providers).and_return([:ldapmain])
allow(view).to receive(:omniauth_callback_path).with(:user, 'ldapmain').and_return('/ldapmain')
end
def disable_ldap_sign_in
allow(view).to receive(:ldap_sign_in_enabled?).and_return(false)
assign(:ldap_servers, [])
end
def disable_captcha
allow(view).to receive(:captcha_enabled?).and_return(false)
allow(view).to receive(:captcha_on_login_required?).and_return(false)
end
end
...@@ -18,15 +18,30 @@ describe StuckCiJobsWorker do ...@@ -18,15 +18,30 @@ describe StuckCiJobsWorker do
end end
shared_examples 'job is dropped' do shared_examples 'job is dropped' do
before do it "changes status" do
worker.perform worker.perform
job.reload job.reload
end
it "changes status" do
expect(job).to be_failed expect(job).to be_failed
expect(job).to be_stuck_or_timeout_failure expect(job).to be_stuck_or_timeout_failure
end end
context 'when job have data integrity problem' do
it "does drop the job and logs the reason" do
job.update_columns(yaml_variables: '[{"key" => "value"}]')
expect(Gitlab::Sentry).to receive(:track_acceptable_exception)
.with(anything, a_hash_including(extra: a_hash_including(build_id: job.id)))
.once
.and_call_original
worker.perform
job.reload
expect(job).to be_failed
expect(job).to be_data_integrity_failure
end
end
end end
shared_examples 'job is unchanged' do shared_examples 'job is unchanged' 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