Commit 9f7754b1 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-02-06

# Conflicts:
#	.flayignore
#	app/controllers/projects/issues_controller.rb
#	app/controllers/projects/merge_requests_controller.rb
#	app/models/namespace.rb
#	app/models/wiki_page.rb
#	config/routes/group.rb
#	db/schema.rb
#	doc/administration/auth/ldap.md
#	doc/user/group/index.md
#	locale/gitlab.pot
#	spec/factories/uploads.rb
#	spec/models/namespace_spec.rb
#	spec/uploaders/file_uploader_spec.rb

[ci skip]
parents cbaa5ced 9483cbab
...@@ -11,7 +11,10 @@ app/models/concerns/relative_positioning.rb ...@@ -11,7 +11,10 @@ app/models/concerns/relative_positioning.rb
app/workers/stuck_merge_jobs_worker.rb app/workers/stuck_merge_jobs_worker.rb
lib/gitlab/redis/*.rb lib/gitlab/redis/*.rb
lib/gitlab/gitaly_client/operation_service.rb lib/gitlab/gitaly_client/operation_service.rb
<<<<<<< HEAD
app/models/project_services/packagist_service.rb app/models/project_services/packagist_service.rb
lib/gitlab/background_migration/normalize_ldap_extern_uids_range.rb lib/gitlab/background_migration/normalize_ldap_extern_uids_range.rb
=======
>>>>>>> upstream/master
lib/gitlab/background_migration/* lib/gitlab/background_migration/*
app/models/project_services/kubernetes_service.rb app/models/project_services/kubernetes_service.rb
...@@ -652,6 +652,8 @@ codequality: ...@@ -652,6 +652,8 @@ codequality:
sast: sast:
<<: *except-docs <<: *except-docs
image: registry.gitlab.com/gitlab-org/gl-sast:latest image: registry.gitlab.com/gitlab-org/gl-sast:latest
variables:
CONFIDENCE_LEVEL: 2
before_script: [] before_script: []
script: script:
- /app/bin/run . - /app/bin/run .
......
import _ from 'underscore'; import _ from 'underscore';
import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { __ } from '~/locale';
export default function initBroadcastMessagesForm() { export default function initBroadcastMessagesForm() {
$('input#broadcast_message_color').on('input', function onMessageColorInput() { $('input#broadcast_message_color').on('input', function onMessageColorInput() {
...@@ -18,13 +21,15 @@ export default function initBroadcastMessagesForm() { ...@@ -18,13 +21,15 @@ export default function initBroadcastMessagesForm() {
if (message === '') { if (message === '') {
$('.js-broadcast-message-preview').text('Your message here'); $('.js-broadcast-message-preview').text('Your message here');
} else { } else {
$.ajax({ axios.post(previewPath, {
url: previewPath, broadcast_message: {
type: 'POST', message,
data: {
broadcast_message: { message },
}, },
}); })
.then(({ data }) => {
$('.js-broadcast-message-preview').html(data.message);
})
.catch(() => flash(__('An error occurred while rendering preview broadcast message')));
} }
}, 250)); }, 250));
} }
/* eslint-disable comma-dangle, consistent-return, class-methods-use-this, arrow-parens, no-param-reassign, max-len */ /* eslint-disable comma-dangle, consistent-return, class-methods-use-this, arrow-parens, no-param-reassign, max-len */
import _ from 'underscore'; import _ from 'underscore';
import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { __ } from '~/locale';
const debounceTimeoutDuration = 1000; const debounceTimeoutDuration = 1000;
const invalidInputClass = 'gl-field-error-outline'; const invalidInputClass = 'gl-field-error-outline';
...@@ -77,12 +80,9 @@ export default class UsernameValidator { ...@@ -77,12 +80,9 @@ export default class UsernameValidator {
this.state.pending = true; this.state.pending = true;
this.state.available = false; this.state.available = false;
this.renderState(); this.renderState();
return $.ajax({ axios.get(`${gon.relative_url_root}/users/${username}/exists`)
type: 'GET', .then(({ data }) => this.setAvailabilityState(data.exists))
url: `${gon.relative_url_root}/users/${username}/exists`, .catch(() => flash(__('An error occurred while validating username')));
dataType: 'json',
success: (res) => this.setAvailabilityState(res.exists)
});
} }
} }
......
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
// more than `x` users are referenced. // more than `x` users are referenced.
// //
import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { __ } from '~/locale';
var lastTextareaPreviewed; var lastTextareaPreviewed;
var lastTextareaHeight = null; var lastTextareaHeight = null;
var markdownPreview; var markdownPreview;
...@@ -62,21 +66,17 @@ MarkdownPreview.prototype.fetchMarkdownPreview = function (text, url, success) { ...@@ -62,21 +66,17 @@ MarkdownPreview.prototype.fetchMarkdownPreview = function (text, url, success) {
success(this.ajaxCache.response); success(this.ajaxCache.response);
return; return;
} }
$.ajax({ axios.post(url, {
type: 'POST', text,
url: url, })
data: { .then(({ data }) => {
text: text this.ajaxCache = {
}, text: text,
dataType: 'json', response: data,
success: (function (response) { };
this.ajaxCache = { success(data);
text: text, })
response: response .catch(() => flash(__('An error occurred while fetching markdown preview')));
};
success(response);
}).bind(this)
});
}; };
MarkdownPreview.prototype.hideReferencedUsers = function ($form) { MarkdownPreview.prototype.hideReferencedUsers = function ($form) {
......
import { __ } from './locale';
import axios from './lib/utils/axios_utils';
import flash from './flash';
export default class ProjectLabelSubscription { export default class ProjectLabelSubscription {
constructor(container) { constructor(container) {
this.$container = $(container); this.$container = $(container);
...@@ -17,10 +21,7 @@ export default class ProjectLabelSubscription { ...@@ -17,10 +21,7 @@ export default class ProjectLabelSubscription {
$btn.addClass('disabled'); $btn.addClass('disabled');
$span.toggleClass('hidden'); $span.toggleClass('hidden');
$.ajax({ axios.post(url).then(() => {
type: 'POST',
url,
}).done(() => {
let newStatus; let newStatus;
let newAction; let newAction;
...@@ -45,6 +46,6 @@ export default class ProjectLabelSubscription { ...@@ -45,6 +46,6 @@ export default class ProjectLabelSubscription {
return button; return button;
}); });
}); }).catch(() => flash(__('There was an error subscribing to this label.')));
} }
} }
import axios from '../lib/utils/axios_utils';
import PANEL_STATE from './constants'; import PANEL_STATE from './constants';
import { backOff } from '../lib/utils/common_utils'; import { backOff } from '../lib/utils/common_utils';
...@@ -81,24 +82,20 @@ export default class PrometheusMetrics { ...@@ -81,24 +82,20 @@ export default class PrometheusMetrics {
loadActiveMetrics() { loadActiveMetrics() {
this.showMonitoringMetricsPanelState(PANEL_STATE.LOADING); this.showMonitoringMetricsPanelState(PANEL_STATE.LOADING);
backOff((next, stop) => { backOff((next, stop) => {
$.ajax({ axios.get(this.activeMetricsEndpoint)
url: this.activeMetricsEndpoint, .then(({ data }) => {
dataType: 'json', if (data && data.success) {
global: false, stop(data);
})
.done((res) => {
if (res && res.success) {
stop(res);
} else { } else {
this.backOffRequestCounter = this.backOffRequestCounter += 1; this.backOffRequestCounter = this.backOffRequestCounter += 1;
if (this.backOffRequestCounter < 3) { if (this.backOffRequestCounter < 3) {
next(); next();
} else { } else {
stop(res); stop(data);
} }
} }
}) })
.fail(stop); .catch(stop);
}) })
.then((res) => { .then((res) => {
if (res && res.data && res.data.length) { if (res && res.data && res.data.length) {
......
/* eslint-disable no-new */ import flash from '../flash';
import Flash from '../flash'; import axios from '../lib/utils/axios_utils';
import ProtectedBranchAccessDropdown from './protected_branch_access_dropdown'; import ProtectedBranchAccessDropdown from './protected_branch_access_dropdown';
export default class ProtectedBranchEdit { export default class ProtectedBranchEdit {
...@@ -38,29 +38,25 @@ export default class ProtectedBranchEdit { ...@@ -38,29 +38,25 @@ export default class ProtectedBranchEdit {
this.$allowedToMergeDropdown.disable(); this.$allowedToMergeDropdown.disable();
this.$allowedToPushDropdown.disable(); this.$allowedToPushDropdown.disable();
$.ajax({ axios.patch(this.$wrap.data('url'), {
type: 'POST', protected_branch: {
url: this.$wrap.data('url'), merge_access_levels_attributes: [{
dataType: 'json', id: this.$allowedToMergeDropdown.data('access-level-id'),
data: { access_level: $allowedToMergeInput.val(),
_method: 'PATCH', }],
protected_branch: { push_access_levels_attributes: [{
merge_access_levels_attributes: [{ id: this.$allowedToPushDropdown.data('access-level-id'),
id: this.$allowedToMergeDropdown.data('access-level-id'), access_level: $allowedToPushInput.val(),
access_level: $allowedToMergeInput.val(), }],
}],
push_access_levels_attributes: [{
id: this.$allowedToPushDropdown.data('access-level-id'),
access_level: $allowedToPushInput.val(),
}],
},
}, },
error() { }).then(() => {
new Flash('Failed to update branch!', 'alert', document.querySelector('.js-protected-branches-list')); this.$allowedToMergeDropdown.enable();
}, this.$allowedToPushDropdown.enable();
}).always(() => { }).catch(() => {
this.$allowedToMergeDropdown.enable(); this.$allowedToMergeDropdown.enable();
this.$allowedToPushDropdown.enable(); this.$allowedToPushDropdown.enable();
flash('Failed to update branch!', 'alert', document.querySelector('.js-protected-branches-list'));
}); });
} }
} }
/* eslint-disable no-new */ import flash from '../flash';
import Flash from '../flash'; import axios from '../lib/utils/axios_utils';
import ProtectedTagAccessDropdown from './protected_tag_access_dropdown'; import ProtectedTagAccessDropdown from './protected_tag_access_dropdown';
export default class ProtectedTagEdit { export default class ProtectedTagEdit {
...@@ -28,24 +28,19 @@ export default class ProtectedTagEdit { ...@@ -28,24 +28,19 @@ export default class ProtectedTagEdit {
this.$allowedToCreateDropdownButton.disable(); this.$allowedToCreateDropdownButton.disable();
$.ajax({ axios.patch(this.$wrap.data('url'), {
type: 'POST', protected_tag: {
url: this.$wrap.data('url'), create_access_levels_attributes: [{
dataType: 'json', id: this.$allowedToCreateDropdownButton.data('access-level-id'),
data: { access_level: $allowedToCreateInput.val(),
_method: 'PATCH', }],
protected_tag: {
create_access_levels_attributes: [{
id: this.$allowedToCreateDropdownButton.data('access-level-id'),
access_level: $allowedToCreateInput.val(),
}],
},
}, },
error() { }).then(() => {
new Flash('Failed to update tag!', 'alert', document.querySelector('.js-protected-tags-list')); this.$allowedToCreateDropdownButton.enable();
}, }).catch(() => {
}).always(() => {
this.$allowedToCreateDropdownButton.enable(); this.$allowedToCreateDropdownButton.enable();
flash('Failed to update tag!', 'alert', document.querySelector('.js-protected-tags-list'));
}); });
} }
} }
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
import _ from 'underscore'; import _ from 'underscore';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import flash from './flash';
import axios from './lib/utils/axios_utils';
function Sidebar(currentUser) { function Sidebar(currentUser) {
this.toggleTodo = this.toggleTodo.bind(this); this.toggleTodo = this.toggleTodo.bind(this);
...@@ -62,7 +64,7 @@ Sidebar.prototype.sidebarToggleClicked = function (e, triggered) { ...@@ -62,7 +64,7 @@ Sidebar.prototype.sidebarToggleClicked = function (e, triggered) {
Sidebar.prototype.toggleTodo = function(e) { Sidebar.prototype.toggleTodo = function(e) {
var $btnText, $this, $todoLoading, ajaxType, url; var $btnText, $this, $todoLoading, ajaxType, url;
$this = $(e.currentTarget); $this = $(e.currentTarget);
ajaxType = $this.attr('data-delete-path') ? 'DELETE' : 'POST'; ajaxType = $this.attr('data-delete-path') ? 'delete' : 'post';
if ($this.attr('data-delete-path')) { if ($this.attr('data-delete-path')) {
url = "" + ($this.attr('data-delete-path')); url = "" + ($this.attr('data-delete-path'));
} else { } else {
...@@ -71,25 +73,14 @@ Sidebar.prototype.toggleTodo = function(e) { ...@@ -71,25 +73,14 @@ Sidebar.prototype.toggleTodo = function(e) {
$this.tooltip('hide'); $this.tooltip('hide');
return $.ajax({ $('.js-issuable-todo').disable().addClass('is-loading');
url: url,
type: ajaxType, axios[ajaxType](url, {
dataType: 'json', issuable_id: $this.data('issuable-id'),
data: { issuable_type: $this.data('issuable-type'),
issuable_id: $this.data('issuable-id'), }).then(({ data }) => {
issuable_type: $this.data('issuable-type') this.todoUpdateDone(data);
}, }).catch(() => flash(`There was an error ${ajaxType === 'post' ? 'adding a' : 'deleting the'} todo.`));
beforeSend: (function(_this) {
return function() {
$('.js-issuable-todo').disable()
.addClass('is-loading');
};
})(this)
}).done((function(_this) {
return function(data) {
return _this.todoUpdateDone(data);
};
})(this));
}; };
Sidebar.prototype.todoUpdateDone = function(data) { Sidebar.prototype.todoUpdateDone = function(data) {
......
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import Mousetrap from 'mousetrap'; import Mousetrap from 'mousetrap';
import axios from './lib/utils/axios_utils';
import { refreshCurrentPage, visitUrl } from './lib/utils/url_utility'; import { refreshCurrentPage, visitUrl } from './lib/utils/url_utility';
import findAndFollowLink from './shortcuts_dashboard_navigation'; import findAndFollowLink from './shortcuts_dashboard_navigation';
...@@ -85,21 +86,21 @@ export default class Shortcuts { ...@@ -85,21 +86,21 @@ export default class Shortcuts {
$modal.modal('toggle'); $modal.modal('toggle');
} }
$.ajax({ return axios.get(gon.shortcuts_path, {
url: gon.shortcuts_path, responseType: 'text',
dataType: 'script', }).then(({ data }) => {
success() { $.globalEval(data);
if (location && location.length > 0) {
const results = []; if (location && location.length > 0) {
for (let i = 0, len = location.length; i < len; i += 1) { const results = [];
results.push($(location[i]).show()); for (let i = 0, len = location.length; i < len; i += 1) {
} results.push($(location[i]).show());
return results;
} }
return results;
}
$('.hidden-shortcut').show(); $('.hidden-shortcut').show();
return $('.js-more-help-button').remove(); return $('.js-more-help-button').remove();
},
}); });
} }
......
import 'deckar01-task_list'; import 'deckar01-task_list';
import axios from './lib/utils/axios_utils';
import Flash from './flash'; import Flash from './flash';
export default class TaskList { export default class TaskList {
...@@ -7,11 +8,11 @@ export default class TaskList { ...@@ -7,11 +8,11 @@ export default class TaskList {
this.dataType = options.dataType; this.dataType = options.dataType;
this.fieldName = options.fieldName; this.fieldName = options.fieldName;
this.onSuccess = options.onSuccess || (() => {}); this.onSuccess = options.onSuccess || (() => {});
this.onError = function showFlash(response) { this.onError = function showFlash(e) {
let errorMessages = ''; let errorMessages = '';
if (response.responseJSON) { if (e.response.data && typeof e.response.data === 'object') {
errorMessages = response.responseJSON.errors.join(' '); errorMessages = e.response.data.errors.join(' ');
} }
return new Flash(errorMessages || 'Update failed', 'alert'); return new Flash(errorMessages || 'Update failed', 'alert');
...@@ -38,12 +39,9 @@ export default class TaskList { ...@@ -38,12 +39,9 @@ export default class TaskList {
patchData[this.dataType] = { patchData[this.dataType] = {
[this.fieldName]: $target.val(), [this.fieldName]: $target.val(),
}; };
return $.ajax({
type: 'PATCH', return axios.patch($target.data('update-url') || $('form.js-issuable-update').attr('action'), patchData)
url: $target.data('update-url') || $('form.js-issuable-update').attr('action'), .then(({ data }) => this.onSuccess(data))
data: patchData, .catch(err => this.onError(err));
success: this.onSuccess,
error: this.onError,
});
} }
} }
import axios from '../lib/utils/axios_utils';
import Activities from '../activities'; import Activities from '../activities';
import ActivityCalendar from './activity_calendar'; import ActivityCalendar from './activity_calendar';
import { localTimeAgo } from '../lib/utils/datetime_utility'; import { localTimeAgo } from '../lib/utils/datetime_utility';
import { __ } from '../locale';
import flash from '../flash';
/** /**
* UserTabs * UserTabs
...@@ -131,18 +134,20 @@ export default class UserTabs { ...@@ -131,18 +134,20 @@ export default class UserTabs {
} }
loadTab(action, endpoint) { loadTab(action, endpoint) {
return $.ajax({ this.toggleLoading(true);
beforeSend: () => this.toggleLoading(true),
complete: () => this.toggleLoading(false), return axios.get(endpoint)
dataType: 'json', .then(({ data }) => {
url: endpoint,
success: (data) => {
const tabSelector = `div#${action}`; const tabSelector = `div#${action}`;
this.$parentEl.find(tabSelector).html(data.html); this.$parentEl.find(tabSelector).html(data.html);
this.loaded[action] = true; this.loaded[action] = true;
localTimeAgo($('.js-timeago', tabSelector)); localTimeAgo($('.js-timeago', tabSelector));
},
}); this.toggleLoading(false);
})
.catch(() => {
this.toggleLoading(false);
});
} }
loadActivities() { loadActivities() {
...@@ -158,17 +163,15 @@ export default class UserTabs { ...@@ -158,17 +163,15 @@ export default class UserTabs {
utcFormatted = `UTC${utcOffset > 0 ? '+' : ''}${(utcOffset / 3600)}`; utcFormatted = `UTC${utcOffset > 0 ? '+' : ''}${(utcOffset / 3600)}`;
} }
$.ajax({ axios.get(calendarPath)
dataType: 'json', .then(({ data }) => {
url: calendarPath,
success: (activityData) => {
$calendarWrap.html(CALENDAR_TEMPLATE); $calendarWrap.html(CALENDAR_TEMPLATE);
$calendarWrap.find('.calendar-hint').append(`(Timezone: ${utcFormatted})`); $calendarWrap.find('.calendar-hint').append(`(Timezone: ${utcFormatted})`);
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new ActivityCalendar('.js-contrib-calendar', activityData, calendarActivitiesPath, utcOffset); new ActivityCalendar('.js-contrib-calendar', data, calendarActivitiesPath, utcOffset);
}, })
}); .catch(() => flash(__('There was an error loading users activity calendar.')));
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new Activities(); new Activities();
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
/* global Issuable */ /* global Issuable */
/* global emitSidebarEvent */ /* global emitSidebarEvent */
import _ from 'underscore'; import _ from 'underscore';
import axios from './lib/utils/axios_utils';
// TODO: remove eventHub hack after code splitting refactor // TODO: remove eventHub hack after code splitting refactor
window.emitSidebarEvent = window.emitSidebarEvent || $.noop; window.emitSidebarEvent = window.emitSidebarEvent || $.noop;
...@@ -177,32 +178,28 @@ function UsersSelect(currentUser, els, options = {}) { ...@@ -177,32 +178,28 @@ function UsersSelect(currentUser, els, options = {}) {
$loading.removeClass('hidden').fadeIn(); $loading.removeClass('hidden').fadeIn();
$dropdown.trigger('loading.gl.dropdown'); $dropdown.trigger('loading.gl.dropdown');
return $.ajax({ return axios.put(issueURL, data)
type: 'PUT', .then(({ data }) => {
dataType: 'json', var user;
url: issueURL, $dropdown.trigger('loaded.gl.dropdown');
data: data $loading.fadeOut();
}).done(function(data) { if (data.assignee) {
var user; user = {
$dropdown.trigger('loaded.gl.dropdown'); name: data.assignee.name,
$loading.fadeOut(); username: data.assignee.username,
if (data.assignee) { avatar: data.assignee.avatar_url
user = { };
name: data.assignee.name, } else {
username: data.assignee.username, user = {
avatar: data.assignee.avatar_url name: 'Unassigned',
}; username: '',
} else { avatar: ''
user = { };
name: 'Unassigned', }
username: '', $value.html(assigneeTemplate(user));
avatar: '' $collapsedSidebar.attr('title', _.escape(user.name)).tooltip('fixTitle');
}; return $collapsedSidebar.html(collapsedAssigneeTemplate(user));
} });
$value.html(assigneeTemplate(user));
$collapsedSidebar.attr('title', _.escape(user.name)).tooltip('fixTitle');
return $collapsedSidebar.html(collapsedAssigneeTemplate(user));
});
}; };
collapsedAssigneeTemplate = _.template('<% if( avatar ) { %> <a class="author_link" href="/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> </a> <% } else { %> <i class="fa fa-user"></i> <% } %>'); collapsedAssigneeTemplate = _.template('<% if( avatar ) { %> <a class="author_link" href="/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> </a> <% } else { %> <i class="fa fa-user"></i> <% } %>');
assigneeTemplate = _.template('<% if (username) { %> <a class="author_link bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="avatar avatar-inline s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> No assignee - <a href="#" class="js-assign-yourself"> assign yourself </a> </span> <% } %>'); assigneeTemplate = _.template('<% if (username) { %> <a class="author_link bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="avatar avatar-inline s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> No assignee - <a href="#" class="js-assign-yourself"> assign yourself </a> </span> <% } %>');
...@@ -660,38 +657,33 @@ UsersSelect.prototype.user = function(user_id, callback) { ...@@ -660,38 +657,33 @@ UsersSelect.prototype.user = function(user_id, callback) {
var url; var url;
url = this.buildUrl(this.userPath); url = this.buildUrl(this.userPath);
url = url.replace(':id', user_id); url = url.replace(':id', user_id);
return $.ajax({ return axios.get(url)
url: url, .then(({ data }) => {
dataType: "json" callback(data);
}).done(function(user) { });
return callback(user);
});
}; };
// Return users list. Filtered by query // Return users list. Filtered by query
// Only active users retrieved // Only active users retrieved
UsersSelect.prototype.users = function(query, options, callback) { UsersSelect.prototype.users = function(query, options, callback) {
var url; const url = this.buildUrl(this.usersPath);
url = this.buildUrl(this.usersPath); const params = {
return $.ajax({ search: query,
url: url, per_page: options.perPage || 20,
data: { active: true,
search: query, project_id: options.projectId || null,
per_page: options.perPage || 20, group_id: options.groupId || null,
active: true, skip_ldap: options.skipLdap || null,
project_id: options.projectId || null, todo_filter: options.todoFilter || null,
group_id: options.groupId || null, todo_state_filter: options.todoStateFilter || null,
skip_ldap: options.skipLdap || null, current_user: options.showCurrentUser || null,
todo_filter: options.todoFilter || null, author_id: options.authorId || null,
todo_state_filter: options.todoStateFilter || null, skip_users: options.skipUsers || null
current_user: options.showCurrentUser || null, };
author_id: options.authorId || null, return axios.get(url, { params })
skip_users: options.skipUsers || null .then(({ data }) => {
}, callback(data);
dataType: "json" });
}).done(function(users) {
return callback(users);
});
}; };
UsersSelect.prototype.buildUrl = function(url) { UsersSelect.prototype.buildUrl = function(url) {
......
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
<template> <template>
<div class="branch-commit"> <div class="branch-commit">
<template v-if="hasCommitRef && showBranch"> <template v-if="hasCommitRef && showBranch">
<div class="icon-container hidden-xs"> <div class="icon-container">
<i <i
v-if="tag" v-if="tag"
class="fa fa-tag" class="fa fa-tag"
...@@ -132,7 +132,7 @@ ...@@ -132,7 +132,7 @@
</div> </div>
<a <a
class="ref-name hidden-xs" class="ref-name"
:href="commitRef.ref_url" :href="commitRef.ref_url"
v-tooltip v-tooltip
data-container="body" data-container="body"
......
...@@ -148,7 +148,7 @@ ...@@ -148,7 +148,7 @@
.ref-name { .ref-name {
font-weight: $gl-font-weight-bold; font-weight: $gl-font-weight-bold;
max-width: 120px; max-width: 100px;
overflow: hidden; overflow: hidden;
display: inline-block; display: inline-block;
white-space: nowrap; white-space: nowrap;
......
class Admin::BroadcastMessagesController < Admin::ApplicationController class Admin::BroadcastMessagesController < Admin::ApplicationController
include BroadcastMessagesHelper
before_action :finder, only: [:edit, :update, :destroy] before_action :finder, only: [:edit, :update, :destroy]
def index def index
...@@ -37,7 +39,8 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController ...@@ -37,7 +39,8 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
end end
def preview def preview
@broadcast_message = BroadcastMessage.new(broadcast_message_params) broadcast_message = BroadcastMessage.new(broadcast_message_params)
render json: { message: render_broadcast_message(broadcast_message) }
end end
protected protected
......
...@@ -8,7 +8,10 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -8,7 +8,10 @@ class Projects::IssuesController < Projects::ApplicationController
prepend_before_action :authenticate_user!, only: [:new, :export_csv] prepend_before_action :authenticate_user!, only: [:new, :export_csv]
<<<<<<< HEAD
before_action :whitelist_query_limiting_ee, only: [:update] before_action :whitelist_query_limiting_ee, only: [:update]
=======
>>>>>>> upstream/master
before_action :whitelist_query_limiting, only: [:create, :create_merge_request, :move, :bulk_update] before_action :whitelist_query_limiting, only: [:create, :create_merge_request, :move, :bulk_update]
before_action :check_issues_available! before_action :check_issues_available!
before_action :issue, except: [:index, :new, :create, :bulk_update, :export_csv] before_action :issue, except: [:index, :new, :create, :bulk_update, :export_csv]
...@@ -261,8 +264,11 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -261,8 +264,11 @@ class Projects::IssuesController < Projects::ApplicationController
# 3. https://gitlab.com/gitlab-org/gitlab-ce/issues/42426 # 3. https://gitlab.com/gitlab-org/gitlab-ce/issues/42426
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42422') Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42422')
end end
<<<<<<< HEAD
def whitelist_query_limiting_ee def whitelist_query_limiting_ee
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ee/issues/4794') Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ee/issues/4794')
end end
=======
>>>>>>> upstream/master
end end
...@@ -9,7 +9,10 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -9,7 +9,10 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
prepend ::EE::Projects::MergeRequestsController prepend ::EE::Projects::MergeRequestsController
skip_before_action :merge_request, only: [:index, :bulk_update] skip_before_action :merge_request, only: [:index, :bulk_update]
<<<<<<< HEAD
before_action :whitelist_query_limiting_ee, only: [:merge, :show] before_action :whitelist_query_limiting_ee, only: [:merge, :show]
=======
>>>>>>> upstream/master
before_action :whitelist_query_limiting, only: [:assign_related_issues, :update] before_action :whitelist_query_limiting, only: [:assign_related_issues, :update]
before_action :authorize_update_issuable!, only: [:close, :edit, :update, :remove_wip, :sort] before_action :authorize_update_issuable!, only: [:close, :edit, :update, :remove_wip, :sort]
before_action :set_issuables_index, only: [:index] before_action :set_issuables_index, only: [:index]
...@@ -355,9 +358,12 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -355,9 +358,12 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
# Also see https://gitlab.com/gitlab-org/gitlab-ce/issues/42441 # Also see https://gitlab.com/gitlab-org/gitlab-ce/issues/42441
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42438') Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42438')
end end
<<<<<<< HEAD
def whitelist_query_limiting_ee def whitelist_query_limiting_ee
# Also see https://gitlab.com/gitlab-org/gitlab-ee/issues/4793 # Also see https://gitlab.com/gitlab-org/gitlab-ee/issues/4793
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ee/issues/4792') Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ee/issues/4792')
end end
=======
>>>>>>> upstream/master
end end
...@@ -4,6 +4,8 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -4,6 +4,8 @@ class RegistrationsController < Devise::RegistrationsController
before_action :whitelist_query_limiting, only: [:destroy] before_action :whitelist_query_limiting, only: [:destroy]
before_action :whitelist_query_limiting, only: [:destroy]
def new def new
redirect_to(new_user_session_path) redirect_to(new_user_session_path)
end end
......
...@@ -17,8 +17,12 @@ module Clusters ...@@ -17,8 +17,12 @@ module Clusters
'stable/nginx-ingress' 'stable/nginx-ingress'
end end
def chart_values_file
"#{Rails.root}/vendor/#{name}/values.yaml"
end
def install_command def install_command
Gitlab::Kubernetes::Helm::InstallCommand.new(name, chart: chart) Gitlab::Kubernetes::Helm::InstallCommand.new(name, chart: chart, chart_values_file: chart_values_file)
end end
end end
end end
......
...@@ -230,10 +230,13 @@ class Namespace < ActiveRecord::Base ...@@ -230,10 +230,13 @@ class Namespace < ActiveRecord::Base
has_parent? has_parent?
end end
<<<<<<< HEAD
def multiple_issue_boards_available?(user = nil) def multiple_issue_boards_available?(user = nil)
feature_available?(:multiple_issue_boards) feature_available?(:multiple_issue_boards)
end end
=======
>>>>>>> upstream/master
def full_path_was def full_path_was
if parent_id_was.nil? if parent_id_was.nil?
path_was path_was
......
...@@ -239,8 +239,8 @@ class User < ActiveRecord::Base ...@@ -239,8 +239,8 @@ class User < ActiveRecord::Base
joins(:identities).where(identities: { provider: provider }) joins(:identities).where(identities: { provider: provider })
end end
scope :todo_authors, ->(user_id, state) { where(id: Todo.where(user_id: user_id, state: state).select(:author_id)) } scope :todo_authors, ->(user_id, state) { where(id: Todo.where(user_id: user_id, state: state).select(:author_id)) }
scope :order_recent_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('last_sign_in_at', 'DESC')) } scope :order_recent_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('current_sign_in_at', 'DESC')) }
scope :order_oldest_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('last_sign_in_at', 'ASC')) } scope :order_oldest_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('current_sign_in_at', 'ASC')) }
def self.with_two_factor def self.with_two_factor
joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id") joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id")
......
...@@ -213,7 +213,11 @@ class WikiPage ...@@ -213,7 +213,11 @@ class WikiPage
last_commit_sha = attrs.delete(:last_commit_sha) last_commit_sha = attrs.delete(:last_commit_sha)
if last_commit_sha && last_commit_sha != self.last_commit_sha if last_commit_sha && last_commit_sha != self.last_commit_sha
<<<<<<< HEAD
raise PageChangedError.new("WikiEdit|You are attempting to update a page that has changed since you started editing it.") raise PageChangedError.new("WikiEdit|You are attempting to update a page that has changed since you started editing it.")
=======
raise PageChangedError
>>>>>>> upstream/master
end end
update_attributes(attrs) update_attributes(attrs)
...@@ -223,7 +227,11 @@ class WikiPage ...@@ -223,7 +227,11 @@ class WikiPage
if wiki.find_page(page_details).present? if wiki.find_page(page_details).present?
@attributes[:title] = @page.url_path @attributes[:title] = @page.url_path
<<<<<<< HEAD
raise PageRenameError.new("WikiEdit|There is already a page with the same title in that path.") raise PageRenameError.new("WikiEdit|There is already a page with the same title in that path.")
=======
raise PageRenameError
>>>>>>> upstream/master
end end
else else
page_details = @page.url_path page_details = @page.url_path
......
...@@ -22,8 +22,7 @@ module SystemNoteService ...@@ -22,8 +22,7 @@ module SystemNoteService
commits_text = "#{total_count} commit".pluralize(total_count) commits_text = "#{total_count} commit".pluralize(total_count)
body = "added #{commits_text}\n\n" body = "added #{commits_text}\n\n"
body << existing_commit_summary(noteable, existing_commits, oldrev) body << commits_list(noteable, new_commits, existing_commits, oldrev)
body << new_commit_summary(new_commits).join("\n")
body << "\n\n[Compare with previous version](#{diff_comparison_url(noteable, project, oldrev)})" body << "\n\n[Compare with previous version](#{diff_comparison_url(noteable, project, oldrev)})"
create_note(NoteSummary.new(noteable, project, author, body, action: 'commit', commit_count: total_count)) create_note(NoteSummary.new(noteable, project, author, body, action: 'commit', commit_count: total_count))
...@@ -481,7 +480,7 @@ module SystemNoteService ...@@ -481,7 +480,7 @@ module SystemNoteService
# Returns an Array of Strings # Returns an Array of Strings
def new_commit_summary(new_commits) def new_commit_summary(new_commits)
new_commits.collect do |commit| new_commits.collect do |commit|
"* #{commit.short_id} - #{escape_html(commit.title)}" content_tag('li', "#{commit.short_id} - #{commit.title}")
end end
end end
...@@ -709,6 +708,16 @@ module SystemNoteService ...@@ -709,6 +708,16 @@ module SystemNoteService
"#{cross_reference_note_prefix}#{gfm_reference}" "#{cross_reference_note_prefix}#{gfm_reference}"
end end
# Builds a list of existing and new commits according to existing_commits and
# new_commits methods.
# Returns a String wrapped in `ul` and `li` tags.
def commits_list(noteable, new_commits, existing_commits, oldrev)
existing_commit_summary = existing_commit_summary(noteable, existing_commits, oldrev)
new_commit_summary = new_commit_summary(new_commits).join
content_tag('ul', "#{existing_commit_summary}#{new_commit_summary}".html_safe)
end
# Build a single line summarizing existing commits being added in a merge # Build a single line summarizing existing commits being added in a merge
# request # request
# #
...@@ -745,11 +754,8 @@ module SystemNoteService ...@@ -745,11 +754,8 @@ module SystemNoteService
branch = noteable.target_branch branch = noteable.target_branch
branch = "#{noteable.target_project_namespace}:#{branch}" if noteable.for_fork? branch = "#{noteable.target_project_namespace}:#{branch}" if noteable.for_fork?
"* #{commit_ids} - #{commits_text} from branch `#{branch}`\n" branch_name = content_tag('code', branch)
end content_tag('li', "#{commit_ids} - #{commits_text} from branch #{branch_name}".html_safe)
def escape_html(text)
Rack::Utils.escape_html(text)
end end
def url_helpers def url_helpers
...@@ -766,4 +772,8 @@ module SystemNoteService ...@@ -766,4 +772,8 @@ module SystemNoteService
start_sha: oldrev start_sha: oldrev
) )
end end
def content_tag(*args)
ActionController::Base.helpers.content_tag(*args)
end
end end
$('.js-broadcast-message-preview').html("#{j(render_broadcast_message(@broadcast_message))}");
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
- if @repository.gitlab_ci_yml - if @repository.gitlab_ci_yml
%li %li
= link_to _('CI configuration'), ci_configuration_path(@project) = link_to _('CI/CD configuration'), ci_configuration_path(@project)
- if current_user && can_push_branch?(@project, @project.default_branch) - if current_user && can_push_branch?(@project, @project.default_branch)
- unless @repository.changelog - unless @repository.changelog
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
- unless @repository.gitlab_ci_yml - unless @repository.gitlab_ci_yml
%li.missing %li.missing
= link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do
#{ _('Set up CI') } #{ _('Set up CI/CD') }
- if koding_enabled? && @repository.koding_yml.blank? - if koding_enabled? && @repository.koding_yml.blank?
%li.missing %li.missing
= link_to _('Set up Koding'), add_koding_stack_path(@project) = link_to _('Set up Koding'), add_koding_stack_path(@project)
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
.wiki .wiki
= markdown_field(release, :description) = markdown_field(release, :description)
.row-fixed-content.controls .row-fixed-content.controls.flex-row
= render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name] = render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name]
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
......
---
title: Fix Sort by Recent Sign-in in Admin Area
merge_request: 13852
author: Poornima M
---
title: Enable Prometheus metrics for deployed Ingresses
merge_request: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/16866
author: joshlambert
type: changed
---
title: Fixes different margins between buttons in tag list
merge_request: 16927
author: Jacopo Beschi @jacopo-beschi
type: fixed
---
title: Rename button to enable CI/CD configuration to "Set up CI/CD"
merge_request: 16870
author:
type: changed
---
title: Bypass commits title markdown on notes
merge_request:
author:
type: fixed
---
title: Include branch in mobile view for pipelines
merge_request: 16910
author: George Tsiolis
type: other
...@@ -14,7 +14,10 @@ constraints(GroupUrlConstrainer.new) do ...@@ -14,7 +14,10 @@ constraints(GroupUrlConstrainer.new) do
get :merge_requests, as: :merge_requests_group get :merge_requests, as: :merge_requests_group
get :projects, as: :projects_group get :projects, as: :projects_group
get :activity, as: :activity_group get :activity, as: :activity_group
<<<<<<< HEAD
get :subgroups, as: :subgroups_group ## EE-specific get :subgroups, as: :subgroups_group ## EE-specific
=======
>>>>>>> upstream/master
put :transfer, as: :transfer_group put :transfer, as: :transfer_group
end end
......
...@@ -18,12 +18,21 @@ class MigrateRemainingIssuesClosedAt < ActiveRecord::Migration ...@@ -18,12 +18,21 @@ class MigrateRemainingIssuesClosedAt < ActiveRecord::Migration
Gitlab::BackgroundMigration.steal('CopyColumn') Gitlab::BackgroundMigration.steal('CopyColumn')
Gitlab::BackgroundMigration.steal('CleanupConcurrentTypeChange') Gitlab::BackgroundMigration.steal('CleanupConcurrentTypeChange')
# It's possible the cleanup job was killed which means we need to manually if migrate_column_type?
# migrate any remaining rows. if closed_at_for_type_change_exists?
migrate_remaining_rows if migrate_column_type? migrate_remaining_rows
else
# Due to some EE merge problems some environments may not have the
# "closed_at_for_type_change" column. If this is the case we have no
# other option than to migrate the data _right now_.
change_column_type_concurrently(:issues, :closed_at, :datetime_with_timezone)
cleanup_concurrent_column_type_change(:issues, :closed_at)
end
end
end end
def down def down
# Previous migrations already revert the changes made here.
end end
def migrate_remaining_rows def migrate_remaining_rows
...@@ -39,4 +48,8 @@ class MigrateRemainingIssuesClosedAt < ActiveRecord::Migration ...@@ -39,4 +48,8 @@ class MigrateRemainingIssuesClosedAt < ActiveRecord::Migration
# migration, thus we don't need to migrate those environments again. # migration, thus we don't need to migrate those environments again.
column_for('issues', 'closed_at').type == :datetime # rubocop:disable Migration/Datetime column_for('issues', 'closed_at').type == :datetime # rubocop:disable Migration/Datetime
end end
def closed_at_for_type_change_exists?
columns('issues').any? { |col| col.name == 'closed_at_for_type_change' }
end
end end
...@@ -2254,7 +2254,10 @@ ActiveRecord::Schema.define(version: 20180204200836) do ...@@ -2254,7 +2254,10 @@ ActiveRecord::Schema.define(version: 20180204200836) do
t.string "model_type" t.string "model_type"
t.string "uploader", null: false t.string "uploader", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
<<<<<<< HEAD
t.integer "store" t.integer "store"
=======
>>>>>>> upstream/master
t.string "mount_point" t.string "mount_point"
t.string "secret" t.string "secret"
end end
......
...@@ -335,6 +335,7 @@ In other words, if an existing GitLab user wants to enable LDAP sign-in for ...@@ -335,6 +335,7 @@ In other words, if an existing GitLab user wants to enable LDAP sign-in for
themselves, they should check that their GitLab email address matches their themselves, they should check that their GitLab email address matches their
LDAP email address, and then sign into GitLab via their LDAP credentials. LDAP email address, and then sign into GitLab via their LDAP credentials.
<<<<<<< HEAD
## Adjusting LDAP user and group sync schedules ## Adjusting LDAP user and group sync schedules
You can manually configure LDAP user and group sync times by setting the You can manually configure LDAP user and group sync times by setting the
...@@ -403,6 +404,8 @@ your installation compares before proceeding. ...@@ -403,6 +404,8 @@ your installation compares before proceeding.
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.
=======
>>>>>>> upstream/master
## Enabling LDAP username lowercase ## Enabling LDAP username lowercase
Some LDAP servers, depending on their configurations, can return uppercase usernames. This can lead to several confusing issues like, for example, creating links or namespaces with uppercase names. Some LDAP servers, depending on their configurations, can return uppercase usernames. This can lead to several confusing issues like, for example, creating links or namespaces with uppercase names.
......
...@@ -396,7 +396,7 @@ If you want to modify the CI/CD pipeline used by Auto DevOps, you can copy the ...@@ -396,7 +396,7 @@ If you want to modify the CI/CD pipeline used by Auto DevOps, you can copy the
Assuming that your project is new or it doesn't have a `.gitlab-ci.yml` file Assuming that your project is new or it doesn't have a `.gitlab-ci.yml` file
present: present:
1. From your project home page, either click on the "Set up CI" button, or click 1. From your project home page, either click on the "Set up CI/CD" button, or click
on the plus button and (`+`), then "New file" on the plus button and (`+`), then "New file"
1. Pick `.gitlab-ci.yml` as the template type 1. Pick `.gitlab-ci.yml` as the template type
1. Select "Auto-DevOps" from the template dropdown 1. Select "Auto-DevOps" from the template dropdown
......
...@@ -179,6 +179,7 @@ Alternatively, you can [lock the sharing with group feature](#share-with-group-l ...@@ -179,6 +179,7 @@ Alternatively, you can [lock the sharing with group feature](#share-with-group-l
In GitLab Enterprise Edition it is possible to manage GitLab group memberships using LDAP groups. In GitLab Enterprise Edition it is possible to manage GitLab group memberships using LDAP groups.
See [the GitLab Enterprise Edition documentation](../../integration/ldap.md) for more information. See [the GitLab Enterprise Edition documentation](../../integration/ldap.md) for more information.
<<<<<<< HEAD
## Epics ## Epics
> Introduced in [GitLab Enterprise Edition Ultimate][ee] 10.2. > Introduced in [GitLab Enterprise Edition Ultimate][ee] 10.2.
...@@ -189,6 +190,8 @@ milestones. ...@@ -189,6 +190,8 @@ milestones.
[Learn more about Epics.](epics/index.md) [Learn more about Epics.](epics/index.md)
=======
>>>>>>> upstream/master
## Transfer groups to another group ## Transfer groups to another group
From 10.5 there are two different ways to transfer a group: From 10.5 there are two different ways to transfer a group:
......
...@@ -77,7 +77,7 @@ is useful for submitting merge requests to the upstream. ...@@ -77,7 +77,7 @@ is useful for submitting merge requests to the upstream.
> >
> 2. Why do I need to enable Shared Runners? > 2. Why do I need to enable Shared Runners?
> >
> Shared Runners will run the script set by your GitLab CI > Shared Runners will run the script set by your GitLab CI/CD
configuration file. They're enabled by default to new projects, configuration file. They're enabled by default to new projects,
but not to forks. but not to forks.
...@@ -88,9 +88,9 @@ click **New project**, and name it considering the ...@@ -88,9 +88,9 @@ click **New project**, and name it considering the
[practical examples](getting_started_part_one.md#practical-examples). [practical examples](getting_started_part_one.md#practical-examples).
1. Clone it to your local computer, add your website 1. Clone it to your local computer, add your website
files to your project, add, commit and push to GitLab. files to your project, add, commit and push to GitLab.
1. From the your **Project**'s page, click **Set up CI**: 1. From the your **Project**'s page, click **Set up CI/CD**:
![setup GitLab CI](img/setup_ci.png) ![setup GitLab CI/CD](img/setup_ci.png)
1. Choose one of the templates from the dropbox menu. 1. Choose one of the templates from the dropbox menu.
Pick up the template corresponding to the SSG you're using (or plain HTML). Pick up the template corresponding to the SSG you're using (or plain HTML).
...@@ -98,7 +98,7 @@ Pick up the template corresponding to the SSG you're using (or plain HTML). ...@@ -98,7 +98,7 @@ Pick up the template corresponding to the SSG you're using (or plain HTML).
![gitlab-ci templates](img/choose_ci_template.png) ![gitlab-ci templates](img/choose_ci_template.png)
Once you have both site files and `.gitlab-ci.yml` in your project's Once you have both site files and `.gitlab-ci.yml` in your project's
root, GitLab CI will build your site and deploy it with Pages. root, GitLab CI/CD will build your site and deploy it with Pages.
Once the first build passes, you see your site is live by Once the first build passes, you see your site is live by
navigating to your **Project**'s **Settings** > **Pages**, navigating to your **Project**'s **Settings** > **Pages**,
where you'll find its default URL. where you'll find its default URL.
......
...@@ -45,7 +45,7 @@ has already been created, which creates a link to the license itself. ...@@ -45,7 +45,7 @@ has already been created, which creates a link to the license itself.
![New file button](img/web_editor_template_dropdown_buttons.png) ![New file button](img/web_editor_template_dropdown_buttons.png)
>**Note:** >**Note:**
The **Set up CI** button will not appear on an empty repository. You have to at The **Set up CI/CD** button will not appear on an empty repository. You have to at
least add a file in order for the button to show up. least add a file in order for the button to show up.
## Upload a file ## Upload a file
......
...@@ -4,6 +4,7 @@ module Gitlab ...@@ -4,6 +4,7 @@ module Gitlab
ATTRS = %i(title format url_path path name historical raw_data).freeze ATTRS = %i(title format url_path path name historical raw_data).freeze
include AttributesBag include AttributesBag
include Gitlab::EncodingHelper
def initialize(params) def initialize(params)
super super
...@@ -11,6 +12,10 @@ module Gitlab ...@@ -11,6 +12,10 @@ module Gitlab
# All gRPC strings in a response are frozen, so we get an unfrozen # All gRPC strings in a response are frozen, so we get an unfrozen
# version here so appending to `raw_data` doesn't blow up. # version here so appending to `raw_data` doesn't blow up.
@raw_data = @raw_data.dup @raw_data = @raw_data.dup
@title = encode_utf8(@title)
@path = encode_utf8(@path)
@name = encode_utf8(@name)
end end
def historical? def historical?
......
...@@ -64,7 +64,7 @@ module Gitlab ...@@ -64,7 +64,7 @@ module Gitlab
{ {
name: 'configuration-volume', name: 'configuration-volume',
configMap: { configMap: {
name: 'values-content-configuration', name: "values-content-configuration-#{command.name}",
items: [{ key: 'values', path: 'values.yaml' }] items: [{ key: 'values', path: 'values.yaml' }]
} }
} }
...@@ -81,7 +81,11 @@ module Gitlab ...@@ -81,7 +81,11 @@ module Gitlab
def create_config_map def create_config_map
resource = ::Kubeclient::Resource.new resource = ::Kubeclient::Resource.new
resource.metadata = { name: 'values-content-configuration', namespace: namespace_name, labels: { name: 'values-content-configuration' } } resource.metadata = {
name: "values-content-configuration-#{command.name}",
namespace: namespace_name,
labels: { name: "values-content-configuration-#{command.name}" }
}
resource.data = { values: File.read(command.chart_values_file) } resource.data = { values: File.read(command.chart_values_file) }
kubeclient.create_config_map(resource) kubeclient.create_config_map(resource)
end end
......
...@@ -8,8 +8,13 @@ msgid "" ...@@ -8,8 +8,13 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gitlab 1.0.0\n" "Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
<<<<<<< HEAD
"POT-Creation-Date: 2018-02-05 16:08+0100\n" "POT-Creation-Date: 2018-02-05 16:08+0100\n"
"PO-Revision-Date: 2018-02-05 16:08+0100\n" "PO-Revision-Date: 2018-02-05 16:08+0100\n"
=======
"POT-Creation-Date: 2018-02-05 16:03+0100\n"
"PO-Revision-Date: 2018-02-05 16:03+0100\n"
>>>>>>> upstream/master
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n" "Language: \n"
...@@ -180,6 +185,12 @@ msgstr "" ...@@ -180,6 +185,12 @@ msgstr ""
msgid "An error occurred while fetching sidebar data" msgid "An error occurred while fetching sidebar data"
msgstr "" msgstr ""
<<<<<<< HEAD
=======
msgid "An error occurred while getting projects"
msgstr ""
>>>>>>> upstream/master
msgid "An error occurred while loading filenames" msgid "An error occurred while loading filenames"
msgstr "" msgstr ""
...@@ -458,7 +469,7 @@ msgstr "" ...@@ -458,7 +469,7 @@ msgstr ""
msgid "CI / CD" msgid "CI / CD"
msgstr "" msgstr ""
msgid "CI configuration" msgid "CI/CD configuration"
msgstr "" msgstr ""
msgid "CICD|Jobs" msgid "CICD|Jobs"
...@@ -596,6 +607,7 @@ msgstr "" ...@@ -596,6 +607,7 @@ msgstr ""
msgid "CiVariable|All environments" msgid "CiVariable|All environments"
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "CiVariable|Create wildcard" msgid "CiVariable|Create wildcard"
msgstr "" msgstr ""
...@@ -608,6 +620,11 @@ msgstr "" ...@@ -608,6 +620,11 @@ msgstr ""
msgid "CiVariable|Search environments" msgid "CiVariable|Search environments"
msgstr "" msgstr ""
=======
msgid "CiVariable|Protected"
msgstr ""
>>>>>>> upstream/master
msgid "CiVariable|Toggle protected" msgid "CiVariable|Toggle protected"
msgstr "" msgstr ""
...@@ -1284,6 +1301,7 @@ msgstr "" ...@@ -1284,6 +1301,7 @@ msgstr ""
msgid "Environments|You don't have any environments right now." msgid "Environments|You don't have any environments right now."
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "Epic will be removed! Are you sure?" msgid "Epic will be removed! Are you sure?"
msgstr "" msgstr ""
...@@ -1297,6 +1315,12 @@ msgid "Error creating epic" ...@@ -1297,6 +1315,12 @@ msgid "Error creating epic"
msgstr "" msgstr ""
msgid "Error fetching contributors data." msgid "Error fetching contributors data."
=======
msgid "Error fetching contributors data."
msgstr ""
msgid "Error fetching labels."
>>>>>>> upstream/master
msgstr "" msgstr ""
msgid "Error fetching network graph." msgid "Error fetching network graph."
...@@ -1311,6 +1335,12 @@ msgstr "" ...@@ -1311,6 +1335,12 @@ msgstr ""
msgid "Error occurred when toggling the notification subscription" msgid "Error occurred when toggling the notification subscription"
msgstr "" msgstr ""
<<<<<<< HEAD
=======
msgid "Error saving label update."
msgstr ""
>>>>>>> upstream/master
msgid "Error updating status for all todos." msgid "Error updating status for all todos."
msgstr "" msgstr ""
...@@ -2523,7 +2553,7 @@ msgstr "" ...@@ -2523,7 +2553,7 @@ msgstr ""
msgid "Set a password on your account to pull or push via %{protocol}." msgid "Set a password on your account to pull or push via %{protocol}."
msgstr "" msgstr ""
msgid "Set up CI" msgid "Set up CI/CD"
msgstr "" msgstr ""
msgid "Set up Koding" msgid "Set up Koding"
...@@ -2914,9 +2944,12 @@ msgstr "" ...@@ -2914,9 +2944,12 @@ msgstr ""
msgid "There was an error when unsubscribing from this label." msgid "There was an error when unsubscribing from this label."
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "This board\\'s scope is reduced" msgid "This board\\'s scope is reduced"
msgstr "" msgstr ""
=======
>>>>>>> upstream/master
msgid "This directory" msgid "This directory"
msgstr "" msgstr ""
...@@ -3140,9 +3173,12 @@ msgstr "" ...@@ -3140,9 +3173,12 @@ msgstr ""
msgid "Trigger this manual action" msgid "Trigger this manual action"
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "Turn on Service Desk" msgid "Turn on Service Desk"
msgstr "" msgstr ""
=======
>>>>>>> upstream/master
msgid "Type %{value} to confirm:" msgid "Type %{value} to confirm:"
msgstr "" msgstr ""
......
...@@ -3,7 +3,6 @@ module QA ...@@ -3,7 +3,6 @@ module QA
module Project module Project
class Show < Page::Base class Show < Page::Base
view 'app/views/shared/_clone_panel.html.haml' do view 'app/views/shared/_clone_panel.html.haml' do
element :clone_holder, '.git-clone-holder'
element :clone_dropdown element :clone_dropdown
element :clone_options_dropdown, '.clone-options-dropdown' element :clone_options_dropdown, '.clone-options-dropdown'
element :project_repository_location, 'text_field_tag :project_clone' element :project_repository_location, 'text_field_tag :project_clone'
...@@ -31,7 +30,7 @@ module QA ...@@ -31,7 +30,7 @@ module QA
end end
# Ensure git clone textbox was updated to http URI # Ensure git clone textbox was updated to http URI
page.has_css?('.git-clone-holder input#project_clone[value*="http"]') repository_location.include?('http')
end end
end end
......
...@@ -5,7 +5,10 @@ FactoryBot.define do ...@@ -5,7 +5,10 @@ FactoryBot.define do
uploader "AvatarUploader" uploader "AvatarUploader"
mount_point :avatar mount_point :avatar
secret nil secret nil
<<<<<<< HEAD
store ObjectStorage::Store::LOCAL store ObjectStorage::Store::LOCAL
=======
>>>>>>> upstream/master
# we should build a mount agnostic upload by default # we should build a mount agnostic upload by default
transient do transient do
...@@ -16,13 +19,20 @@ FactoryBot.define do ...@@ -16,13 +19,20 @@ FactoryBot.define do
path { File.join("uploads/-/system", model.class.to_s.underscore, mount_point.to_s, 'avatar.jpg') } path { File.join("uploads/-/system", model.class.to_s.underscore, mount_point.to_s, 'avatar.jpg') }
trait :personal_snippet_upload do trait :personal_snippet_upload do
<<<<<<< HEAD
model { build(:personal_snippet) } model { build(:personal_snippet) }
path { File.join(secret, filename) } path { File.join(secret, filename) }
uploader "PersonalFileUploader" uploader "PersonalFileUploader"
=======
uploader "PersonalFileUploader"
path { File.join(secret, filename) }
model { build(:personal_snippet) }
>>>>>>> upstream/master
secret SecureRandom.hex secret SecureRandom.hex
end end
trait :issuable_upload do trait :issuable_upload do
<<<<<<< HEAD
path { File.join(secret, filename) } path { File.join(secret, filename) }
uploader "FileUploader" uploader "FileUploader"
secret SecureRandom.hex secret SecureRandom.hex
...@@ -30,6 +40,11 @@ FactoryBot.define do ...@@ -30,6 +40,11 @@ FactoryBot.define do
trait :object_storage do trait :object_storage do
store ObjectStorage::Store::REMOTE store ObjectStorage::Store::REMOTE
=======
uploader "FileUploader"
path { File.join(secret, filename) }
secret SecureRandom.hex
>>>>>>> upstream/master
end end
trait :namespace_upload do trait :namespace_upload do
......
/* eslint-disable no-new */ /* eslint-disable no-new */
import _ from 'underscore'; import _ from 'underscore';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import Sidebar from '~/right_sidebar'; import Sidebar from '~/right_sidebar';
import timeoutPromise from './helpers/set_timeout_promise_helper';
describe('Issuable right sidebar collapsed todo toggle', () => { describe('Issuable right sidebar collapsed todo toggle', () => {
const fixtureName = 'issues/open-issue.html.raw'; const fixtureName = 'issues/open-issue.html.raw';
const jsonFixtureName = 'todos/todos.json'; const jsonFixtureName = 'todos/todos.json';
let mock;
preloadFixtures(fixtureName); preloadFixtures(fixtureName);
preloadFixtures(jsonFixtureName); preloadFixtures(jsonFixtureName);
...@@ -19,19 +23,26 @@ describe('Issuable right sidebar collapsed todo toggle', () => { ...@@ -19,19 +23,26 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
document.querySelector('.js-right-sidebar') document.querySelector('.js-right-sidebar')
.classList.toggle('right-sidebar-collapsed'); .classList.toggle('right-sidebar-collapsed');
spyOn(jQuery, 'ajax').and.callFake((res) => { mock = new MockAdapter(axios);
const d = $.Deferred();
mock.onPost(`${gl.TEST_HOST}/frontend-fixtures/issues-project/todos`).reply(() => {
const response = _.clone(todoData); const response = _.clone(todoData);
if (res.type === 'DELETE') { return [200, response];
delete response.delete_path; });
}
d.resolve(response); mock.onDelete(/(.*)\/dashboard\/todos\/\d+$/).reply(() => {
return d.promise(); const response = _.clone(todoData);
delete response.delete_path;
return [200, response];
}); });
}); });
afterEach(() => {
mock.restore();
});
it('shows add todo button', () => { it('shows add todo button', () => {
expect( expect(
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon'), document.querySelector('.js-issuable-todo.sidebar-collapsed-icon'),
...@@ -52,71 +63,101 @@ describe('Issuable right sidebar collapsed todo toggle', () => { ...@@ -52,71 +63,101 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
).toBe('Add todo'); ).toBe('Add todo');
}); });
it('toggle todo state', () => { it('toggle todo state', (done) => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
expect( setTimeout(() => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'), expect(
).not.toBeNull(); document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
).not.toBeNull();
expect( expect(
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .fa-check-square'), document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .fa-check-square'),
).not.toBeNull(); ).not.toBeNull();
});
it('toggle todo state of expanded todo toggle', () => { done();
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); });
expect(
document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(),
).toBe('Mark done');
}); });
it('toggles todo button tooltip', () => { it('toggle todo state of expanded todo toggle', (done) => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
expect( setTimeout(() => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('data-original-title'), expect(
).toBe('Mark done'); document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(),
}); ).toBe('Mark done');
it('marks todo as done', () => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
expect( done();
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'), });
).not.toBeNull(); });
it('toggles todo button tooltip', (done) => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
expect( setTimeout(() => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'), expect(
).toBeNull(); document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('data-original-title'),
).toBe('Mark done');
expect( done();
document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(), });
).toBe('Add todo');
}); });
it('updates aria-label to mark done', () => { it('marks todo as done', (done) => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
expect( timeoutPromise()
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'), .then(() => {
).toBe('Mark done'); expect(
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
).not.toBeNull();
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
})
.then(timeoutPromise)
.then(() => {
expect(
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
).toBeNull();
expect(
document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(),
).toBe('Add todo');
})
.then(done)
.catch(done.fail);
}); });
it('updates aria-label to add todo', () => { it('updates aria-label to mark done', (done) => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
expect( setTimeout(() => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'), expect(
).toBe('Mark done'); document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'),
).toBe('Mark done');
done();
});
});
it('updates aria-label to add todo', (done) => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
expect( timeoutPromise()
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'), .then(() => {
).toBe('Add todo'); expect(
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'),
).toBe('Mark done');
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
})
.then(timeoutPromise)
.then(() => {
expect(
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'),
).toBe('Add todo');
})
.then(done)
.catch(done.fail);
}); });
}); });
...@@ -70,23 +70,6 @@ describe('Issue', function() { ...@@ -70,23 +70,6 @@ describe('Issue', function() {
expect($btn).toHaveText(isIssueInitiallyOpen ? 'Close issue' : 'Reopen issue'); expect($btn).toHaveText(isIssueInitiallyOpen ? 'Close issue' : 'Reopen issue');
} }
describe('task lists', function() {
beforeEach(function() {
loadFixtures('issues/issue-with-task-list.html.raw');
this.issue = new Issue();
});
it('submits an ajax request on tasklist:changed', function() {
spyOn(jQuery, 'ajax').and.callFake(function(req) {
expect(req.type).toBe('PATCH');
expect(req.url).toBe(gl.TEST_HOST + '/frontend-fixtures/issues-project/issues/1.json'); // eslint-disable-line prefer-template
expect(req.data.issue.description).not.toBe(null);
});
$('.js-task-list-field').trigger('tasklist:changed');
});
});
[true, false].forEach((isIssueInitiallyOpen) => { [true, false].forEach((isIssueInitiallyOpen) => {
describe(`with ${isIssueInitiallyOpen ? 'open' : 'closed'} issue`, function() { describe(`with ${isIssueInitiallyOpen ? 'open' : 'closed'} issue`, function() {
const action = isIssueInitiallyOpen ? 'close' : 'reopen'; const action = isIssueInitiallyOpen ? 'close' : 'reopen';
......
/* eslint-disable space-before-function-paren, no-return-assign */ /* eslint-disable space-before-function-paren, no-return-assign */
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import MergeRequest from '~/merge_request'; import MergeRequest from '~/merge_request';
import CloseReopenReportToggle from '~/close_reopen_report_toggle'; import CloseReopenReportToggle from '~/close_reopen_report_toggle';
import IssuablesHelper from '~/helpers/issuables_helper'; import IssuablesHelper from '~/helpers/issuables_helper';
...@@ -7,11 +8,24 @@ import IssuablesHelper from '~/helpers/issuables_helper'; ...@@ -7,11 +8,24 @@ import IssuablesHelper from '~/helpers/issuables_helper';
(function() { (function() {
describe('MergeRequest', function() { describe('MergeRequest', function() {
describe('task lists', function() { describe('task lists', function() {
let mock;
preloadFixtures('merge_requests/merge_request_with_task_list.html.raw'); preloadFixtures('merge_requests/merge_request_with_task_list.html.raw');
beforeEach(function() { beforeEach(function() {
loadFixtures('merge_requests/merge_request_with_task_list.html.raw'); loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
spyOn(axios, 'patch').and.callThrough();
mock = new MockAdapter(axios);
mock.onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`).reply(200, {});
return this.merge = new MergeRequest(); return this.merge = new MergeRequest();
}); });
afterEach(() => {
mock.restore();
});
it('modifies the Markdown field', function() { it('modifies the Markdown field', function() {
spyOn(jQuery, 'ajax').and.stub(); spyOn(jQuery, 'ajax').and.stub();
const changeEvent = document.createEvent('HTMLEvents'); const changeEvent = document.createEvent('HTMLEvents');
...@@ -21,14 +35,14 @@ import IssuablesHelper from '~/helpers/issuables_helper'; ...@@ -21,14 +35,14 @@ import IssuablesHelper from '~/helpers/issuables_helper';
}); });
it('submits an ajax request on tasklist:changed', (done) => { it('submits an ajax request on tasklist:changed', (done) => {
spyOn(jQuery, 'ajax').and.callFake((req) => { $('.js-task-list-field').trigger('tasklist:changed');
expect(req.type).toBe('PATCH');
expect(req.url).toBe(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`); setTimeout(() => {
expect(req.data.merge_request.description).not.toBe(null); expect(axios.patch).toHaveBeenCalledWith(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`, {
merge_request: { description: '- [ ] Task List Item' },
});
done(); done();
}); });
$('.js-task-list-field').trigger('tasklist:changed');
}); });
}); });
......
...@@ -50,13 +50,24 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; ...@@ -50,13 +50,24 @@ import timeoutPromise from './helpers/set_timeout_promise_helper';
}); });
describe('task lists', function() { describe('task lists', function() {
let mock;
beforeEach(function() { beforeEach(function() {
spyOn(axios, 'patch').and.callThrough();
mock = new MockAdapter(axios);
mock.onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`).reply(200, {});
$('.js-comment-button').on('click', function(e) { $('.js-comment-button').on('click', function(e) {
e.preventDefault(); e.preventDefault();
}); });
this.notes = new Notes('', []); this.notes = new Notes('', []);
}); });
afterEach(() => {
mock.restore();
});
it('modifies the Markdown field', function() { it('modifies the Markdown field', function() {
const changeEvent = document.createEvent('HTMLEvents'); const changeEvent = document.createEvent('HTMLEvents');
changeEvent.initEvent('change', true, true); changeEvent.initEvent('change', true, true);
...@@ -65,14 +76,15 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; ...@@ -65,14 +76,15 @@ import timeoutPromise from './helpers/set_timeout_promise_helper';
expect($('.js-task-list-field.original-task-list').val()).toBe('- [x] Task List Item'); expect($('.js-task-list-field.original-task-list').val()).toBe('- [x] Task List Item');
}); });
it('submits an ajax request on tasklist:changed', function() { it('submits an ajax request on tasklist:changed', function(done) {
spyOn(jQuery, 'ajax').and.callFake(function(req) { $('.js-task-list-container').trigger('tasklist:changed');
expect(req.type).toBe('PATCH');
expect(req.url).toBe('http://test.host/frontend-fixtures/merge-requests-project/merge_requests/1.json');
return expect(req.data.note).not.toBe(null);
});
$('.js-task-list-field.js-note-text').trigger('tasklist:changed'); setTimeout(() => {
expect(axios.patch).toHaveBeenCalledWith(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`, {
note: { note: '' },
});
done();
});
}); });
}); });
......
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics'; import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics';
import PANEL_STATE from '~/prometheus_metrics/constants'; import PANEL_STATE from '~/prometheus_metrics/constants';
import { metrics, missingVarMetrics } from './mock_data'; import { metrics, missingVarMetrics } from './mock_data';
...@@ -102,25 +104,38 @@ describe('PrometheusMetrics', () => { ...@@ -102,25 +104,38 @@ describe('PrometheusMetrics', () => {
describe('loadActiveMetrics', () => { describe('loadActiveMetrics', () => {
let prometheusMetrics; let prometheusMetrics;
let mock;
function mockSuccess() {
mock.onGet(prometheusMetrics.activeMetricsEndpoint).reply(200, {
data: metrics,
success: true,
});
}
function mockError() {
mock.onGet(prometheusMetrics.activeMetricsEndpoint).networkError();
}
beforeEach(() => { beforeEach(() => {
spyOn(axios, 'get').and.callThrough();
prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring'); prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring');
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
}); });
it('should show loader animation while response is being loaded and hide it when request is complete', (done) => { it('should show loader animation while response is being loaded and hide it when request is complete', (done) => {
const deferred = $.Deferred(); mockSuccess();
spyOn($, 'ajax').and.returnValue(deferred.promise());
prometheusMetrics.loadActiveMetrics(); prometheusMetrics.loadActiveMetrics();
expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeFalsy(); expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeFalsy();
expect($.ajax).toHaveBeenCalledWith({ expect(axios.get).toHaveBeenCalledWith(prometheusMetrics.activeMetricsEndpoint);
url: prometheusMetrics.activeMetricsEndpoint,
dataType: 'json',
global: false,
});
deferred.resolve({ data: metrics, success: true });
setTimeout(() => { setTimeout(() => {
expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeTruthy(); expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeTruthy();
...@@ -129,14 +144,10 @@ describe('PrometheusMetrics', () => { ...@@ -129,14 +144,10 @@ describe('PrometheusMetrics', () => {
}); });
it('should show empty state if response failed to load', (done) => { it('should show empty state if response failed to load', (done) => {
const deferred = $.Deferred(); mockError();
spyOn($, 'ajax').and.returnValue(deferred.promise());
spyOn(prometheusMetrics, 'populateActiveMetrics');
prometheusMetrics.loadActiveMetrics(); prometheusMetrics.loadActiveMetrics();
deferred.reject();
setTimeout(() => { setTimeout(() => {
expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeTruthy(); expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeTruthy();
expect(prometheusMetrics.$monitoredMetricsEmpty.hasClass('hidden')).toBeFalsy(); expect(prometheusMetrics.$monitoredMetricsEmpty.hasClass('hidden')).toBeFalsy();
...@@ -145,14 +156,11 @@ describe('PrometheusMetrics', () => { ...@@ -145,14 +156,11 @@ describe('PrometheusMetrics', () => {
}); });
it('should populate metrics list once response is loaded', (done) => { it('should populate metrics list once response is loaded', (done) => {
const deferred = $.Deferred();
spyOn($, 'ajax').and.returnValue(deferred.promise());
spyOn(prometheusMetrics, 'populateActiveMetrics'); spyOn(prometheusMetrics, 'populateActiveMetrics');
mockSuccess();
prometheusMetrics.loadActiveMetrics(); prometheusMetrics.loadActiveMetrics();
deferred.resolve({ data: metrics, success: true });
setTimeout(() => { setTimeout(() => {
expect(prometheusMetrics.populateActiveMetrics).toHaveBeenCalledWith(metrics); expect(prometheusMetrics.populateActiveMetrics).toHaveBeenCalledWith(metrics);
done(); done();
......
/* eslint-disable space-before-function-paren, no-var, one-var, one-var-declaration-per-line, new-parens, no-return-assign, new-cap, vars-on-top, max-len */ /* eslint-disable space-before-function-paren, no-var, one-var, one-var-declaration-per-line, new-parens, no-return-assign, new-cap, vars-on-top, max-len */
import MockAdapter from 'axios-mock-adapter';
import '~/commons/bootstrap'; import '~/commons/bootstrap';
import axios from '~/lib/utils/axios_utils';
import Sidebar from '~/right_sidebar'; import Sidebar from '~/right_sidebar';
(function() { (function() {
...@@ -35,16 +37,23 @@ import Sidebar from '~/right_sidebar'; ...@@ -35,16 +37,23 @@ import Sidebar from '~/right_sidebar';
var fixtureName = 'issues/open-issue.html.raw'; var fixtureName = 'issues/open-issue.html.raw';
preloadFixtures(fixtureName); preloadFixtures(fixtureName);
loadJSONFixtures('todos/todos.json'); loadJSONFixtures('todos/todos.json');
let mock;
beforeEach(function() { beforeEach(function() {
loadFixtures(fixtureName); loadFixtures(fixtureName);
this.sidebar = new Sidebar; mock = new MockAdapter(axios);
this.sidebar = new Sidebar();
$aside = $('.right-sidebar'); $aside = $('.right-sidebar');
$page = $('.layout-page'); $page = $('.layout-page');
$icon = $aside.find('i'); $icon = $aside.find('i');
$toggle = $aside.find('.js-sidebar-toggle'); $toggle = $aside.find('.js-sidebar-toggle');
return $labelsIcon = $aside.find('.sidebar-collapsed-icon'); return $labelsIcon = $aside.find('.sidebar-collapsed-icon');
}); });
afterEach(() => {
mock.restore();
});
it('should expand/collapse the sidebar when arrow is clicked', function() { it('should expand/collapse the sidebar when arrow is clicked', function() {
assertSidebarState('expanded'); assertSidebarState('expanded');
$toggle.click(); $toggle.click();
...@@ -63,20 +72,19 @@ import Sidebar from '~/right_sidebar'; ...@@ -63,20 +72,19 @@ import Sidebar from '~/right_sidebar';
return assertSidebarState('collapsed'); return assertSidebarState('collapsed');
}); });
it('should broadcast todo:toggle event when add todo clicked', function() { it('should broadcast todo:toggle event when add todo clicked', function(done) {
var todos = getJSONFixture('todos/todos.json'); var todos = getJSONFixture('todos/todos.json');
spyOn(jQuery, 'ajax').and.callFake(function() { mock.onPost(/(.*)\/todos$/).reply(200, todos);
var d = $.Deferred();
var response = todos;
d.resolve(response);
return d.promise();
});
var todoToggleSpy = spyOnEvent(document, 'todo:toggle'); var todoToggleSpy = spyOnEvent(document, 'todo:toggle');
$('.issuable-sidebar-header .js-issuable-todo').click(); $('.issuable-sidebar-header .js-issuable-todo').click();
expect(todoToggleSpy.calls.count()).toEqual(1); setTimeout(() => {
expect(todoToggleSpy.calls.count()).toEqual(1);
done();
});
}); });
it('should not hide collapsed icons', () => { it('should not hide collapsed icons', () => {
......
...@@ -63,14 +63,14 @@ describe Gitlab::Kubernetes::Helm::Pod do ...@@ -63,14 +63,14 @@ describe Gitlab::Kubernetes::Helm::Pod do
it 'should mount configMap specification in the volume' do it 'should mount configMap specification in the volume' do
spec = subject.generate.spec spec = subject.generate.spec
expect(spec.volumes.first.configMap['name']).to eq('values-content-configuration') expect(spec.volumes.first.configMap['name']).to eq("values-content-configuration-#{app.name}")
expect(spec.volumes.first.configMap['items'].first['key']).to eq('values') expect(spec.volumes.first.configMap['items'].first['key']).to eq('values')
expect(spec.volumes.first.configMap['items'].first['path']).to eq('values.yaml') expect(spec.volumes.first.configMap['items'].first['path']).to eq('values.yaml')
end end
end end
context 'without a configuration file' do context 'without a configuration file' do
let(:app) { create(:clusters_applications_ingress, cluster: cluster) } let(:app) { create(:clusters_applications_helm, cluster: cluster) }
it_behaves_like 'helm pod' it_behaves_like 'helm pod'
......
...@@ -691,6 +691,7 @@ describe Namespace do ...@@ -691,6 +691,7 @@ describe Namespace do
end end
end end
<<<<<<< HEAD
describe '#root_ancestor' do describe '#root_ancestor' do
it 'returns the top most ancestor', :nested_groups do it 'returns the top most ancestor', :nested_groups do
root_group = create(:group) root_group = create(:group)
...@@ -711,6 +712,15 @@ describe Namespace do ...@@ -711,6 +712,15 @@ describe Namespace do
let(:legacy_export) { legacy_project.export_project_path } let(:legacy_export) { legacy_project.export_project_path }
let(:hashed_export) { hashed_project.export_project_path } let(:hashed_export) { hashed_project.export_project_path }
=======
describe '#remove_exports' do
let(:legacy_project) { create(:project, :with_export, namespace: namespace) }
let(:hashed_project) { create(:project, :with_export, :hashed, namespace: namespace) }
let(:export_path) { Dir.mktmpdir('namespace_remove_exports_spec') }
let(:legacy_export) { legacy_project.export_project_path }
let(:hashed_export) { hashed_project.export_project_path }
>>>>>>> upstream/master
it 'removes exports for legacy and hashed projects' do it 'removes exports for legacy and hashed projects' do
allow(Gitlab::ImportExport).to receive(:storage_path) { export_path } allow(Gitlab::ImportExport).to receive(:storage_path) { export_path }
...@@ -735,10 +745,17 @@ describe Namespace do ...@@ -735,10 +745,17 @@ describe Namespace do
context 'when a parent is assigned to a group with no previous parent' do context 'when a parent is assigned to a group with no previous parent' do
it 'should return the path was' do it 'should return the path was' do
group = create(:group, parent: nil) group = create(:group, parent: nil)
<<<<<<< HEAD
parent = create(:group)
group.parent = parent
=======
parent = create(:group) parent = create(:group)
group.parent = parent group.parent = parent
>>>>>>> upstream/master
expect(group.full_path_was).to eq("#{group.path_was}") expect(group.full_path_was).to eq("#{group.path_was}")
end end
end end
......
...@@ -135,7 +135,7 @@ describe ProjectWiki do ...@@ -135,7 +135,7 @@ describe ProjectWiki do
end end
after do after do
destroy_page(subject.pages.first.page) subject.pages.each { |page| destroy_page(page.page) }
end end
it "returns the latest version of the page if it exists" do it "returns the latest version of the page if it exists" do
...@@ -156,6 +156,17 @@ describe ProjectWiki do ...@@ -156,6 +156,17 @@ describe ProjectWiki do
page = subject.find_page("index page") page = subject.find_page("index page")
expect(page).to be_a WikiPage expect(page).to be_a WikiPage
end end
context 'pages with multibyte-character title' do
before do
create_page("autre pagé", "C'est un génial Gollum Wiki")
end
it "can find a page by slug" do
page = subject.find_page("autre pagé")
expect(page.title).to eq("autre pagé")
end
end
end end
context 'when Gitaly wiki_find_page is enabled' do context 'when Gitaly wiki_find_page is enabled' do
......
...@@ -1482,28 +1482,34 @@ describe User do ...@@ -1482,28 +1482,34 @@ describe User do
describe '#sort' do describe '#sort' do
before do before do
described_class.delete_all described_class.delete_all
@user = create :user, created_at: Date.today, last_sign_in_at: Date.today, name: 'Alpha' @user = create :user, created_at: Date.today, current_sign_in_at: Date.today, name: 'Alpha'
@user1 = create :user, created_at: Date.today - 1, last_sign_in_at: Date.today - 1, name: 'Omega' @user1 = create :user, created_at: Date.today - 1, current_sign_in_at: Date.today - 1, name: 'Omega'
@user2 = create :user, created_at: Date.today - 2, last_sign_in_at: nil, name: 'Beta' @user2 = create :user, created_at: Date.today - 2, name: 'Beta'
end end
context 'when sort by recent_sign_in' do context 'when sort by recent_sign_in' do
it 'sorts users by the recent sign-in time' do let(:users) { described_class.sort('recent_sign_in') }
expect(described_class.sort('recent_sign_in').first).to eq(@user)
it 'sorts users by recent sign-in time' do
expect(users.first).to eq(@user)
expect(users.second).to eq(@user1)
end end
it 'pushes users who never signed in to the end' do it 'pushes users who never signed in to the end' do
expect(described_class.sort('recent_sign_in').third).to eq(@user2) expect(users.third).to eq(@user2)
end end
end end
context 'when sort by oldest_sign_in' do context 'when sort by oldest_sign_in' do
let(:users) { described_class.sort('oldest_sign_in') }
it 'sorts users by the oldest sign-in time' do it 'sorts users by the oldest sign-in time' do
expect(described_class.sort('oldest_sign_in').first).to eq(@user1) expect(users.first).to eq(@user1)
expect(users.second).to eq(@user)
end end
it 'pushes users who never signed in to the end' do it 'pushes users who never signed in to the end' do
expect(described_class.sort('oldest_sign_in').third).to eq(@user2) expect(users.third).to eq(@user2)
end end
end end
......
...@@ -56,10 +56,11 @@ describe SystemNoteService do ...@@ -56,10 +56,11 @@ describe SystemNoteService do
expect(note_lines[0]).to eq "added #{new_commits.size} commits" expect(note_lines[0]).to eq "added #{new_commits.size} commits"
end end
it 'adds a message line for each commit' do it 'adds a message for each commit' do
new_commits.each_with_index do |commit, i| decoded_note_content = HTMLEntities.new.decode(subject.note)
# Skip the header
expect(HTMLEntities.new.decode(note_lines[i + 1])).to eq "* #{commit.short_id} - #{commit.title}" new_commits.each do |commit|
expect(decoded_note_content).to include("<li>#{commit.short_id} - #{commit.title}</li>")
end end
end end
end end
...@@ -71,7 +72,7 @@ describe SystemNoteService do ...@@ -71,7 +72,7 @@ describe SystemNoteService do
let(:old_commits) { [noteable.commits.last] } let(:old_commits) { [noteable.commits.last] }
it 'includes the existing commit' do it 'includes the existing commit' do
expect(summary_line).to eq "* #{old_commits.first.short_id} - 1 commit from branch `feature`" expect(summary_line).to start_with("<ul><li>#{old_commits.first.short_id} - 1 commit from branch <code>feature</code>")
end end
end end
...@@ -81,22 +82,16 @@ describe SystemNoteService do ...@@ -81,22 +82,16 @@ describe SystemNoteService do
context 'with oldrev' do context 'with oldrev' do
let(:oldrev) { noteable.commits[2].id } let(:oldrev) { noteable.commits[2].id }
it 'includes a commit range' do it 'includes a commit range and count' do
expect(summary_line).to start_with "* #{Commit.truncate_sha(oldrev)}...#{old_commits.last.short_id}" expect(summary_line)
end .to start_with("<ul><li>#{Commit.truncate_sha(oldrev)}...#{old_commits.last.short_id} - 26 commits from branch <code>feature</code>")
it 'includes a commit count' do
expect(summary_line).to end_with " - 26 commits from branch `feature`"
end end
end end
context 'without oldrev' do context 'without oldrev' do
it 'includes a commit range' do it 'includes a commit range and count' do
expect(summary_line).to start_with "* #{old_commits[0].short_id}..#{old_commits[-1].short_id}" expect(summary_line)
end .to start_with("<ul><li>#{old_commits[0].short_id}..#{old_commits[-1].short_id} - 26 commits from branch <code>feature</code>")
it 'includes a commit count' do
expect(summary_line).to end_with " - 26 commits from branch `feature`"
end end
end end
...@@ -106,7 +101,7 @@ describe SystemNoteService do ...@@ -106,7 +101,7 @@ describe SystemNoteService do
end end
it 'includes the project namespace' do it 'includes the project namespace' do
expect(summary_line).to end_with "`#{noteable.target_project_namespace}:feature`" expect(summary_line).to include("<code>#{noteable.target_project_namespace}:feature</code>")
end end
end end
end end
...@@ -695,7 +690,7 @@ describe SystemNoteService do ...@@ -695,7 +690,7 @@ describe SystemNoteService do
describe '.new_commit_summary' do describe '.new_commit_summary' do
it 'escapes HTML titles' do it 'escapes HTML titles' do
commit = double(title: '<pre>This is a test</pre>', short_id: '12345678') commit = double(title: '<pre>This is a test</pre>', short_id: '12345678')
escaped = '&lt;pre&gt;This is a test&lt;&#x2F;pre&gt;' escaped = '&lt;pre&gt;This is a test&lt;/pre&gt;'
expect(described_class.new_commit_summary([commit])).to all(match(/- #{escaped}/)) expect(described_class.new_commit_summary([commit])).to all(match(/- #{escaped}/))
end end
......
...@@ -66,6 +66,7 @@ describe FileUploader do ...@@ -66,6 +66,7 @@ describe FileUploader do
end end
end end
<<<<<<< HEAD
describe "#migrate!" do describe "#migrate!" do
before do before do
uploader.store!(fixture_file_upload(Rails.root.join('spec/fixtures/dk.png'))) uploader.store!(fixture_file_upload(Rails.root.join('spec/fixtures/dk.png')))
...@@ -76,6 +77,8 @@ describe FileUploader do ...@@ -76,6 +77,8 @@ describe FileUploader do
it_behaves_like "migrates", from_store: described_class::Store::REMOTE, to_store: described_class::Store::LOCAL it_behaves_like "migrates", from_store: described_class::Store::REMOTE, to_store: described_class::Store::LOCAL
end end
=======
>>>>>>> upstream/master
describe '#upload=' do describe '#upload=' do
let(:secret) { SecureRandom.hex } let(:secret) { SecureRandom.hex }
let(:upload) { create(:upload, :issuable_upload, secret: secret, filename: 'file.txt') } let(:upload) { create(:upload, :issuable_upload, secret: secret, filename: 'file.txt') }
......
controller:
image:
tag: "0.10.2"
repository: "quay.io/kubernetes-ingress-controller/nginx-ingress-controller"
stats.enabled: true
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "10254"
...@@ -2,7 +2,7 @@ alertmanager: ...@@ -2,7 +2,7 @@ alertmanager:
enabled: false enabled: false
kubeStateMetrics: kubeStateMetrics:
enabled: false enabled: true
nodeExporter: nodeExporter:
enabled: false enabled: false
...@@ -10,11 +10,15 @@ nodeExporter: ...@@ -10,11 +10,15 @@ nodeExporter:
pushgateway: pushgateway:
enabled: false enabled: false
server:
image:
tag: v2.1.0
serverFiles: serverFiles:
alerts: "" alerts: {}
rules: "" rules: {}
prometheus.yml: |- prometheus.yml:
rule_files: rule_files:
- /etc/config/rules - /etc/config/rules
- /etc/config/alerts - /etc/config/alerts
...@@ -26,92 +30,108 @@ serverFiles: ...@@ -26,92 +30,108 @@ serverFiles:
- job_name: kubernetes-cadvisor - job_name: kubernetes-cadvisor
scheme: https scheme: https
tls_config: tls_config:
ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true insecure_skip_verify: true
bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token" bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs: kubernetes_sd_configs:
- role: node - role: node
api_server: https://kubernetes.default.svc:443
tls_config:
ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token"
relabel_configs: relabel_configs:
- action: labelmap - action: labelmap
regex: __meta_kubernetes_node_label_(.+) regex: __meta_kubernetes_node_label_(.+)
- target_label: __address__ - target_label: __address__
replacement: kubernetes.default.svc:443 replacement: kubernetes.default.svc:443
- source_labels: - source_labels:
- __meta_kubernetes_node_name - __meta_kubernetes_node_name
regex: "(.+)" regex: "(.+)"
target_label: __metrics_path__ target_label: __metrics_path__
replacement: "/api/v1/nodes/${1}/proxy/metrics/cadvisor" replacement: "/api/v1/nodes/${1}/proxy/metrics/cadvisor"
metric_relabel_configs: metric_relabel_configs:
- source_labels: - source_labels:
- pod_name - pod_name
target_label: environment target_label: environment
regex: "(.+)-.+-.+" regex: "(.+)-.+-.+"
- job_name: 'kubernetes-service-endpoints'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: (.+)(?::\d+);(\d+)
replacement: $1:$2
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: kubernetes_name
- job_name: kubernetes-nodes - job_name: kubernetes-nodes
scheme: https scheme: https
tls_config: tls_config:
ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true insecure_skip_verify: true
bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token" bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs: kubernetes_sd_configs:
- role: node - role: node
api_server: https://kubernetes.default.svc:443
tls_config:
ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token"
relabel_configs: relabel_configs:
- action: labelmap - action: labelmap
regex: __meta_kubernetes_node_label_(.+) regex: __meta_kubernetes_node_label_(.+)
- target_label: __address__ - target_label: __address__
replacement: kubernetes.default.svc:443 replacement: kubernetes.default.svc:443
- source_labels: - source_labels:
- __meta_kubernetes_node_name - __meta_kubernetes_node_name
regex: "(.+)" regex: "(.+)"
target_label: __metrics_path__ target_label: __metrics_path__
replacement: "/api/v1/nodes/${1}/proxy/metrics" replacement: "/api/v1/nodes/${1}/proxy/metrics"
metric_relabel_configs: metric_relabel_configs:
- source_labels: - source_labels:
- pod_name - pod_name
target_label: environment target_label: environment
regex: "(.+)-.+-.+" regex: "(.+)-.+-.+"
- job_name: kubernetes-pods - job_name: kubernetes-pods
tls_config: tls_config:
ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true insecure_skip_verify: true
bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token" bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs: kubernetes_sd_configs:
- role: pod - role: pod
api_server: https://kubernetes.default.svc:443
tls_config:
ca_file: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
bearer_token_file: "/var/run/secrets/kubernetes.io/serviceaccount/token"
relabel_configs: relabel_configs:
- source_labels: - source_labels:
- __meta_kubernetes_pod_annotation_prometheus_io_scrape - __meta_kubernetes_pod_annotation_prometheus_io_scrape
action: keep action: keep
regex: 'true' regex: 'true'
- source_labels: - source_labels:
- __meta_kubernetes_pod_annotation_prometheus_io_path - __meta_kubernetes_pod_annotation_prometheus_io_path
action: replace action: replace
target_label: __metrics_path__ target_label: __metrics_path__
regex: "(.+)" regex: "(.+)"
- source_labels: - source_labels:
- __address__ - __address__
- __meta_kubernetes_pod_annotation_prometheus_io_port - __meta_kubernetes_pod_annotation_prometheus_io_port
action: replace action: replace
regex: "([^:]+)(?::[0-9]+)?;([0-9]+)" regex: "([^:]+)(?::[0-9]+)?;([0-9]+)"
replacement: "$1:$2" replacement: "$1:$2"
target_label: __address__ target_label: __address__
- action: labelmap - action: labelmap
regex: __meta_kubernetes_pod_label_(.+) regex: __meta_kubernetes_pod_label_(.+)
- source_labels: - source_labels:
- __meta_kubernetes_namespace - __meta_kubernetes_namespace
action: replace action: replace
target_label: kubernetes_namespace target_label: kubernetes_namespace
- source_labels: - source_labels:
- __meta_kubernetes_pod_name - __meta_kubernetes_pod_name
action: replace action: replace
target_label: kubernetes_pod_name target_label: kubernetes_pod_name
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