Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
00ecf5debe
commit
37c8b3b44e
4
Gemfile
4
Gemfile
|
@ -112,14 +112,14 @@ gem 'fog-aws', '~> 3.5'
|
|||
# Locked until fog-google resolves https://github.com/fog/fog-google/issues/421.
|
||||
# Also see config/initializers/fog_core_patch.rb.
|
||||
gem 'fog-core', '= 2.1.0'
|
||||
gem 'fog-google', '~> 1.9'
|
||||
gem 'fog-google', '~> 1.10'
|
||||
gem 'fog-local', '~> 0.6'
|
||||
gem 'fog-openstack', '~> 1.0'
|
||||
gem 'fog-rackspace', '~> 0.1.1'
|
||||
gem 'fog-aliyun', '~> 0.3'
|
||||
|
||||
# for Google storage
|
||||
gem 'google-api-client', '~> 0.23'
|
||||
gem 'google-api-client', '~> 0.33'
|
||||
|
||||
# for aws storage
|
||||
gem 'unf', '~> 0.1.4'
|
||||
|
|
29
Gemfile.lock
29
Gemfile.lock
|
@ -286,7 +286,7 @@ GEM
|
|||
factory_bot_rails (5.1.0)
|
||||
factory_bot (~> 5.1.0)
|
||||
railties (>= 4.2.0)
|
||||
faraday (0.15.4)
|
||||
faraday (0.17.3)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
faraday-http-cache (2.0.0)
|
||||
faraday (~> 0.8)
|
||||
|
@ -330,11 +330,11 @@ GEM
|
|||
excon (~> 0.58)
|
||||
formatador (~> 0.2)
|
||||
mime-types
|
||||
fog-google (1.9.1)
|
||||
fog-google (1.10.0)
|
||||
fog-core (<= 2.1.0)
|
||||
fog-json (~> 1.2)
|
||||
fog-xml (~> 0.1.0)
|
||||
google-api-client (~> 0.23.0)
|
||||
google-api-client (>= 0.32, < 0.34)
|
||||
fog-json (1.2.0)
|
||||
fog-core
|
||||
multi_json (~> 1.10)
|
||||
|
@ -419,23 +419,24 @@ GEM
|
|||
actionpack (>= 3.0)
|
||||
multi_json
|
||||
request_store (>= 1.0)
|
||||
google-api-client (0.23.4)
|
||||
google-api-client (0.33.2)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (>= 0.5, < 0.7.0)
|
||||
googleauth (~> 0.9)
|
||||
httpclient (>= 2.8.1, < 3.0)
|
||||
mime-types (~> 3.0)
|
||||
mini_mime (~> 1.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
signet (~> 0.12)
|
||||
google-protobuf (3.8.0)
|
||||
googleapis-common-protos-types (1.0.4)
|
||||
google-protobuf (~> 3.0)
|
||||
googleauth (0.6.6)
|
||||
faraday (~> 0.12)
|
||||
googleauth (0.12.0)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.12)
|
||||
memoist (~> 0.16)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (~> 0.7)
|
||||
signet (~> 0.14)
|
||||
gpgme (2.0.20)
|
||||
mini_portile2 (~> 2.3)
|
||||
grape (1.1.0)
|
||||
|
@ -1010,9 +1011,9 @@ GEM
|
|||
sidekiq-cron (1.0.4)
|
||||
fugit (~> 1.1)
|
||||
sidekiq (>= 4.2.1)
|
||||
signet (0.11.0)
|
||||
signet (0.14.0)
|
||||
addressable (~> 2.3)
|
||||
faraday (~> 0.9)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
multi_json (~> 1.10)
|
||||
simple_po_parser (1.1.2)
|
||||
|
@ -1224,7 +1225,7 @@ DEPENDENCIES
|
|||
fog-aliyun (~> 0.3)
|
||||
fog-aws (~> 3.5)
|
||||
fog-core (= 2.1.0)
|
||||
fog-google (~> 1.9)
|
||||
fog-google (~> 1.10)
|
||||
fog-local (~> 0.6)
|
||||
fog-openstack (~> 1.0)
|
||||
fog-rackspace (~> 0.1.1)
|
||||
|
@ -1250,7 +1251,7 @@ DEPENDENCIES
|
|||
gitlab_chronic_duration (~> 0.10.6.2)
|
||||
gitlab_omniauth-ldap (~> 2.1.1)
|
||||
gon (~> 6.2)
|
||||
google-api-client (~> 0.23)
|
||||
google-api-client (~> 0.33)
|
||||
google-protobuf (~> 3.8.0)
|
||||
gpgme (~> 2.0.19)
|
||||
grape (~> 1.1.0)
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* @module uuids
|
||||
*/
|
||||
|
||||
/**
|
||||
* A string or number representing a start state for a random generator
|
||||
* @typedef {(Number|String)} Seed
|
||||
*/
|
||||
/**
|
||||
* A UUIDv4 string in the format <code>Hex{8}-Hex{4}-4Hex{3}-[89ab]Hex{3}-Hex{12}</code>
|
||||
* @typedef {String} UUIDv4
|
||||
*/
|
||||
|
||||
// https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/20
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
|
||||
import MersenneTwister from 'mersenne-twister';
|
||||
import stringHash from 'string-hash';
|
||||
import { isString } from 'lodash';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
function getSeed(seeds) {
|
||||
return seeds.reduce((seedling, seed, i) => {
|
||||
let thisSeed = 0;
|
||||
|
||||
if (Number.isInteger(seed)) {
|
||||
thisSeed = seed;
|
||||
} else if (isString(seed)) {
|
||||
thisSeed = stringHash(seed);
|
||||
}
|
||||
|
||||
return seedling + (seeds.length - i) * thisSeed;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function getPseudoRandomNumberGenerator(...seeds) {
|
||||
let seedNumber;
|
||||
|
||||
if (seeds.length) {
|
||||
seedNumber = getSeed(seeds);
|
||||
} else {
|
||||
seedNumber = Math.floor(Math.random() * 10 ** 15);
|
||||
}
|
||||
|
||||
return new MersenneTwister(seedNumber);
|
||||
}
|
||||
|
||||
function randomValuesForUuid(prng) {
|
||||
const randomValues = [];
|
||||
|
||||
for (let i = 0; i <= 3; i += 1) {
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const view = new DataView(buffer);
|
||||
|
||||
view.setUint32(0, prng.random_int());
|
||||
|
||||
randomValues.push(view.getUint8(0), view.getUint8(1), view.getUint8(2), view.getUint8(3));
|
||||
}
|
||||
|
||||
return randomValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of UUIDv4s
|
||||
* @param {Object} [options={}]
|
||||
* @param {Seed[]} [options.seeds=[]] - A list of mixed strings or numbers to seed the UUIDv4 generator
|
||||
* @param {Number} [options.count=1] - A total number of UUIDv4s to generate
|
||||
* @returns {UUIDv4[]} An array of UUIDv4s
|
||||
*/
|
||||
export function uuids({ seeds = [], count = 1 } = {}) {
|
||||
const rng = getPseudoRandomNumberGenerator(...seeds);
|
||||
return (
|
||||
// Create an array the same size as the number of UUIDs requested
|
||||
Array(count)
|
||||
.fill(0)
|
||||
// Replace each slot in the array with a UUID which needs 16 (pseudo)random values to generate
|
||||
.map(() => v4({ random: randomValuesForUuid(rng) }))
|
||||
);
|
||||
}
|
|
@ -1,10 +1,4 @@
|
|||
<script>
|
||||
/**
|
||||
* This component generates user-defined links in the
|
||||
* dashboard yml file. However, this component will be
|
||||
* used in the metrics dashboard after
|
||||
* https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32895
|
||||
*/
|
||||
import { mapState } from 'vuex';
|
||||
import { GlIcon, GlLink } from '@gitlab/ui';
|
||||
|
||||
|
@ -21,15 +15,17 @@ export default {
|
|||
<template>
|
||||
<div
|
||||
ref="linksSection"
|
||||
class="d-sm-flex flex-sm-wrap gl-mt-3 gl-p-2 bg-gray-light border border-radius-default"
|
||||
class="gl-display-sm-flex gl-flex-sm-wrap gl-mt-5 gl-p-3 gl-bg-gray-10 border gl-rounded-base links-section"
|
||||
>
|
||||
<div
|
||||
v-for="(link, key) in links"
|
||||
:key="key"
|
||||
class="gl-mb-1 gl-pr-3 d-flex d-sm-block text-break-word"
|
||||
class="gl-mb-1 gl-mr-5 gl-display-flex gl-display-sm-block gl-hover-text-blue-600-children gl-word-break-all"
|
||||
>
|
||||
<gl-link :href="link.url" class="text-plain text-decoration-none"
|
||||
><gl-icon name="link" class="align-text-bottom mr-1" />{{ link.title }}
|
||||
<gl-link :href="link.url" class="gl-text-gray-900 gl-text-decoration-none!"
|
||||
><gl-icon name="link" class="gl-text-gray-700 gl-vertical-align-text-bottom gl-mr-2" />{{
|
||||
link.title
|
||||
}}
|
||||
</gl-link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,8 +3,6 @@ import * as types from './mutation_types';
|
|||
import axios from '~/lib/utils/axios_utils';
|
||||
import createFlash from '~/flash';
|
||||
import { convertToFixedRange } from '~/lib/utils/datetime_range';
|
||||
import { parseTemplatingVariables } from './variable_mapping';
|
||||
import { mergeURLVariables } from '../utils';
|
||||
import {
|
||||
gqClient,
|
||||
parseEnvironmentsResponse,
|
||||
|
@ -161,7 +159,6 @@ export const receiveMetricsDashboardSuccess = ({ commit, dispatch }, { response
|
|||
|
||||
commit(types.SET_ALL_DASHBOARDS, all_dashboards);
|
||||
commit(types.RECEIVE_METRICS_DASHBOARD_SUCCESS, dashboard);
|
||||
commit(types.SET_VARIABLES, mergeURLVariables(parseTemplatingVariables(dashboard.templating)));
|
||||
commit(types.SET_ENDPOINTS, convertObjectPropsToCamelCase(metrics_data));
|
||||
|
||||
return dispatch('fetchDashboardData');
|
||||
|
|
|
@ -61,8 +61,14 @@ export default {
|
|||
state.emptyState = 'loading';
|
||||
state.showEmptyState = true;
|
||||
},
|
||||
[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, dashboard) {
|
||||
state.dashboard = mapToDashboardViewModel(dashboard);
|
||||
[types.RECEIVE_METRICS_DASHBOARD_SUCCESS](state, dashboardYML) {
|
||||
const { dashboard, panelGroups, variables, links } = mapToDashboardViewModel(dashboardYML);
|
||||
state.dashboard = {
|
||||
dashboard,
|
||||
panelGroups,
|
||||
};
|
||||
state.variables = variables;
|
||||
state.links = links;
|
||||
|
||||
if (!state.dashboard.panelGroups.length) {
|
||||
state.emptyState = 'noData';
|
||||
|
|
|
@ -2,6 +2,7 @@ import { slugify } from '~/lib/utils/text_utility';
|
|||
import createGqClient, { fetchPolicies } from '~/lib/graphql';
|
||||
import { SUPPORTED_FORMATS } from '~/lib/utils/unit_format';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { parseTemplatingVariables } from './variable_mapping';
|
||||
import { NOT_IN_DB_PREFIX } from '../constants';
|
||||
import { isSafeURL } from '~/lib/utils/url_utility';
|
||||
|
||||
|
@ -217,9 +218,16 @@ const mapToPanelGroupViewModel = ({ group = '', panels = [] }, i) => {
|
|||
* @param {Array} dashboard.panel_groups - Panel groups array
|
||||
* @returns {Object}
|
||||
*/
|
||||
export const mapToDashboardViewModel = ({ dashboard = '', panel_groups = [] }) => {
|
||||
export const mapToDashboardViewModel = ({
|
||||
dashboard = '',
|
||||
templating = {},
|
||||
links = [],
|
||||
panel_groups = [],
|
||||
}) => {
|
||||
return {
|
||||
dashboard,
|
||||
variables: parseTemplatingVariables(templating),
|
||||
links: links.map(mapLinksToViewModel),
|
||||
panelGroups: panel_groups.map(mapToPanelGroupViewModel),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { debounce } from 'lodash';
|
||||
import { GlLoadingIcon, GlSearchBoxByType, GlInfiniteScroll } from '@gitlab/ui';
|
||||
import { __, n__, sprintf } from '~/locale';
|
||||
import ProjectListItem from './project_list_item.vue';
|
||||
|
||||
const SEARCH_INPUT_TIMEOUT_MS = 500;
|
||||
|
@ -48,6 +49,20 @@ export default {
|
|||
searchQuery: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
legendText() {
|
||||
const count = this.projectSearchResults.length;
|
||||
const total = this.totalResults;
|
||||
|
||||
if (total > 0) {
|
||||
return sprintf(__('Showing %{count} of %{total} projects'), { count, total });
|
||||
}
|
||||
|
||||
return sprintf(n__('Showing %{count} project', 'Showing %{count} projects', count), {
|
||||
count,
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
projectClicked(project) {
|
||||
this.$emit('projectClicked', project);
|
||||
|
@ -82,17 +97,23 @@ export default {
|
|||
:total-items="totalResults"
|
||||
@bottomReached="bottomReached"
|
||||
>
|
||||
<div v-if="!showLoadingIndicator" slot="items" class="d-flex flex-column">
|
||||
<project-list-item
|
||||
v-for="project in projectSearchResults"
|
||||
:key="project.id"
|
||||
:selected="isSelected(project)"
|
||||
:project="project"
|
||||
:matcher="searchQuery"
|
||||
class="js-project-list-item"
|
||||
@click="projectClicked(project)"
|
||||
/>
|
||||
</div>
|
||||
<template v-if="!showLoadingIndicator" #items>
|
||||
<div class="d-flex flex-column">
|
||||
<project-list-item
|
||||
v-for="project in projectSearchResults"
|
||||
:key="project.id"
|
||||
:selected="isSelected(project)"
|
||||
:project="project"
|
||||
:matcher="searchQuery"
|
||||
class="js-project-list-item"
|
||||
@click="projectClicked(project)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #default>
|
||||
{{ legendText }}
|
||||
</template>
|
||||
</gl-infinite-scroll>
|
||||
<div v-if="showNoResultsMessage" class="text-muted ml-2 js-no-results-message">
|
||||
{{ __('Sorry, no projects matched your search') }}
|
||||
|
|
|
@ -21,6 +21,14 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.links-section {
|
||||
.gl-hover-text-blue-600-children:hover {
|
||||
* {
|
||||
@include gl-text-blue-600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.draggable {
|
||||
|
|
|
@ -28,6 +28,8 @@ module ServiceParams
|
|||
:drone_url,
|
||||
:enable_ssl_verification,
|
||||
:external_wiki_url,
|
||||
:google_iap_service_account_json,
|
||||
:google_iap_audience_client_id,
|
||||
# We're using `issues_events` and `merge_requests_events`
|
||||
# in the view so we still need to explicitly state them
|
||||
# here. `Service#event_names` would only give
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Mutations
|
||||
module Metrics
|
||||
module Dashboard
|
||||
module Annotations
|
||||
class Base < BaseMutation
|
||||
private
|
||||
|
||||
# This method is defined here in order to be used by `authorized_find!` in the subclasses.
|
||||
def find_object(id:)
|
||||
GitlabSchema.object_from_id(id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Mutations
|
||||
module Metrics
|
||||
module Dashboard
|
||||
module Annotations
|
||||
class Delete < Base
|
||||
graphql_name 'DeleteAnnotation'
|
||||
|
||||
authorize :delete_metrics_dashboard_annotation
|
||||
|
||||
argument :id,
|
||||
GraphQL::ID_TYPE,
|
||||
required: true,
|
||||
description: 'The global id of the annotation to delete'
|
||||
|
||||
def resolve(id:)
|
||||
annotation = authorized_find!(id: id)
|
||||
|
||||
result = ::Metrics::Dashboard::Annotations::DeleteService.new(context[:current_user], annotation).execute
|
||||
|
||||
errors = Array.wrap(result[:message])
|
||||
|
||||
{
|
||||
errors: errors
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -26,6 +26,7 @@ module Types
|
|||
mount_mutation Mutations::MergeRequests::SetWip, calls_gitaly: true
|
||||
mount_mutation Mutations::MergeRequests::SetAssignees
|
||||
mount_mutation Mutations::Metrics::Dashboard::Annotations::Create
|
||||
mount_mutation Mutations::Metrics::Dashboard::Annotations::Delete
|
||||
mount_mutation Mutations::Notes::Create::Note, calls_gitaly: true
|
||||
mount_mutation Mutations::Notes::Create::DiffNote, calls_gitaly: true
|
||||
mount_mutation Mutations::Notes::Create::ImageDiffNote, calls_gitaly: true
|
||||
|
|
|
@ -20,6 +20,8 @@ module DesignManagement
|
|||
has_many :notes, as: :noteable, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :user_mentions, class_name: 'DesignUserMention', dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
has_many :events, as: :target, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
validates :project, :filename, presence: true
|
||||
validates :issue, presence: true, unless: :importing?
|
||||
validates :filename, uniqueness: { scope: :issue_id }, length: { maximum: 255 }
|
||||
|
@ -189,6 +191,11 @@ module DesignManagement
|
|||
alias_method :after_note_created, :after_note_changed
|
||||
alias_method :after_note_destroyed, :after_note_changed
|
||||
|
||||
# Part of the interface of objects we can create events about
|
||||
def resource_parent
|
||||
project
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def head_version
|
||||
|
|
|
@ -5,6 +5,8 @@ class PrometheusService < MonitoringService
|
|||
|
||||
# Access to prometheus is directly through the API
|
||||
prop_accessor :api_url
|
||||
prop_accessor :google_iap_service_account_json
|
||||
prop_accessor :google_iap_audience_client_id
|
||||
boolean_accessor :manual_configuration
|
||||
|
||||
# We need to allow the self-monitoring project to connect to the internal
|
||||
|
@ -49,7 +51,7 @@ class PrometheusService < MonitoringService
|
|||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
result = [
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'manual_configuration',
|
||||
|
@ -64,6 +66,27 @@ class PrometheusService < MonitoringService
|
|||
required: true
|
||||
}
|
||||
]
|
||||
|
||||
if Feature.enabled?(:prometheus_service_iap_auth)
|
||||
result += [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'google_iap_audience_client_id',
|
||||
title: 'Google IAP Audience Client ID',
|
||||
placeholder: s_('PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)'),
|
||||
required: false
|
||||
},
|
||||
{
|
||||
type: 'textarea',
|
||||
name: 'google_iap_service_account_json',
|
||||
title: 'Google IAP Service Account JSON',
|
||||
placeholder: s_('PrometheusService|Contents of the credentials.json file of your service account, like: { "type": "service_account", "project_id": ... }'),
|
||||
required: false
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
# Check we can connect to the Prometheus API
|
||||
|
@ -77,7 +100,14 @@ class PrometheusService < MonitoringService
|
|||
def prometheus_client
|
||||
return unless should_return_client?
|
||||
|
||||
Gitlab::PrometheusClient.new(api_url, allow_local_requests: allow_local_api_url?)
|
||||
options = { allow_local_requests: allow_local_api_url? }
|
||||
|
||||
if Feature.enabled?(:prometheus_service_iap_auth) && behind_iap?
|
||||
# Adds the Authorization header
|
||||
options[:headers] = iap_client.apply({})
|
||||
end
|
||||
|
||||
Gitlab::PrometheusClient.new(api_url, options)
|
||||
end
|
||||
|
||||
def prometheus_available?
|
||||
|
@ -149,4 +179,12 @@ class PrometheusService < MonitoringService
|
|||
|
||||
Prometheus::CreateDefaultAlertsWorker.perform_async(project_id)
|
||||
end
|
||||
|
||||
def behind_iap?
|
||||
manual_configuration? && google_iap_audience_client_id.present? && google_iap_service_account_json.present?
|
||||
end
|
||||
|
||||
def iap_client
|
||||
@iap_client ||= Google::Auth::Credentials.new(Gitlab::Json.parse(google_iap_service_account_json), target_audience: google_iap_audience_client_id).client
|
||||
end
|
||||
end
|
||||
|
|
|
@ -45,8 +45,8 @@ module Projects
|
|||
project_issues_url(project, label_name: INCIDENT_LABEL_NAME)
|
||||
end
|
||||
|
||||
def starts_at
|
||||
super&.rfc3339
|
||||
def start_time
|
||||
starts_at&.strftime('%d %B %Y, %-l:%M%p (%Z)')
|
||||
end
|
||||
|
||||
def issue_summary_markdown
|
||||
|
@ -73,7 +73,7 @@ module Projects
|
|||
def metadata_list
|
||||
metadata = []
|
||||
|
||||
metadata << list_item('Start time', starts_at) if starts_at
|
||||
metadata << list_item('Start time', start_time) if start_time
|
||||
metadata << list_item('full_query', backtick(full_query)) if full_query
|
||||
metadata << list_item(service.label.humanize, service.value) if service
|
||||
metadata << list_item(monitoring_tool.label.humanize, monitoring_tool.value) if monitoring_tool
|
||||
|
@ -149,7 +149,7 @@ module Projects
|
|||
end
|
||||
|
||||
def embed_time
|
||||
starts_at ? Time.rfc3339(starts_at) : Time.current
|
||||
starts_at || Time.current
|
||||
end
|
||||
|
||||
def alert_embed_window_params(time)
|
||||
|
|
|
@ -15,6 +15,7 @@ module DesignManagement
|
|||
return error('Forbidden!') unless can_delete_designs?
|
||||
|
||||
version = delete_designs!
|
||||
EventCreateService.new.destroy_designs(designs, current_user)
|
||||
|
||||
success(version: version)
|
||||
end
|
||||
|
@ -48,7 +49,9 @@ module DesignManagement
|
|||
end
|
||||
|
||||
def design_action(design)
|
||||
on_success { counter.count(:delete) }
|
||||
on_success do
|
||||
counter.count(:delete)
|
||||
end
|
||||
|
||||
DesignManagement::DesignAction.new(design, :delete)
|
||||
end
|
||||
|
|
|
@ -20,6 +20,7 @@ module DesignManagement
|
|||
uploaded_designs, version = upload_designs!
|
||||
skipped_designs = designs - uploaded_designs
|
||||
|
||||
create_events
|
||||
success({ designs: uploaded_designs, version: version, skipped_designs: skipped_designs })
|
||||
rescue ::ActiveRecord::RecordInvalid => e
|
||||
error(e.message)
|
||||
|
@ -47,7 +48,7 @@ module DesignManagement
|
|||
end
|
||||
|
||||
def build_actions
|
||||
files.zip(designs).flat_map do |(file, design)|
|
||||
@actions ||= files.zip(designs).flat_map do |(file, design)|
|
||||
Array.wrap(build_design_action(file, design))
|
||||
end
|
||||
end
|
||||
|
@ -57,7 +58,9 @@ module DesignManagement
|
|||
return if design_unchanged?(design, content)
|
||||
|
||||
action = new_file?(design) ? :create : :update
|
||||
on_success { ::Gitlab::UsageDataCounters::DesignsCounter.count(action) }
|
||||
on_success do
|
||||
::Gitlab::UsageDataCounters::DesignsCounter.count(action)
|
||||
end
|
||||
|
||||
DesignManagement::DesignAction.new(design, action, content)
|
||||
end
|
||||
|
@ -67,6 +70,16 @@ module DesignManagement
|
|||
content == existing_blobs[design]&.data
|
||||
end
|
||||
|
||||
def create_events
|
||||
by_action = @actions.group_by(&:action).transform_values { |grp| grp.map(&:design) }
|
||||
|
||||
event_create_service.save_designs(current_user, **by_action)
|
||||
end
|
||||
|
||||
def event_create_service
|
||||
@event_create_service ||= EventCreateService.new
|
||||
end
|
||||
|
||||
def commit_message
|
||||
<<~MSG
|
||||
Updated #{files.size} #{'designs'.pluralize(files.size)}
|
||||
|
|
|
@ -96,6 +96,29 @@ class EventCreateService
|
|||
create_push_event(BulkPushEventPayloadService, project, current_user, push_data)
|
||||
end
|
||||
|
||||
def save_designs(current_user, create: [], update: [])
|
||||
created = create.group_by(&:project).flat_map do |project, designs|
|
||||
Feature.enabled?(:design_activity_events, project) ? designs : []
|
||||
end.to_set
|
||||
updated = update.group_by(&:project).flat_map do |project, designs|
|
||||
Feature.enabled?(:design_activity_events, project) ? designs : []
|
||||
end.to_set
|
||||
return [] if created.empty? && updated.empty?
|
||||
|
||||
records = created.zip([:created].cycle) + updated.zip([:updated].cycle)
|
||||
|
||||
create_record_events(records, current_user)
|
||||
end
|
||||
|
||||
def destroy_designs(designs, current_user)
|
||||
designs = designs.select do |design|
|
||||
Feature.enabled?(:design_activity_events, design.project)
|
||||
end
|
||||
return [] unless designs.present?
|
||||
|
||||
create_record_events(designs.zip([:destroyed].cycle), current_user)
|
||||
end
|
||||
|
||||
# Create a new wiki page event
|
||||
#
|
||||
# @param [WikiPage::Meta] wiki_page_meta The event target
|
||||
|
@ -134,7 +157,32 @@ class EventCreateService
|
|||
end
|
||||
|
||||
def create_record_event(record, current_user, status)
|
||||
create_event(record.resource_parent, current_user, status, target_id: record.id, target_type: record.class.name)
|
||||
create_event(record.resource_parent, current_user, status,
|
||||
target_id: record.id, target_type: record.class.name)
|
||||
end
|
||||
|
||||
# If creating several events, this method will insert them all in a single
|
||||
# statement
|
||||
#
|
||||
# @param [[Eventable, Symbol]] a list of pairs of records and a valid status
|
||||
# @param [User] the author of the event
|
||||
def create_record_events(pairs, current_user)
|
||||
base_attrs = {
|
||||
created_at: Time.now.utc,
|
||||
updated_at: Time.now.utc,
|
||||
author_id: current_user.id
|
||||
}
|
||||
|
||||
attribute_sets = pairs.map do |record, status|
|
||||
action = Event.actions[status]
|
||||
raise IllegalActionError, "#{status} is not a valid status" if action.nil?
|
||||
|
||||
parent_attrs(record.resource_parent)
|
||||
.merge(base_attrs)
|
||||
.merge(action: action, target_id: record.id, target_type: record.class.name)
|
||||
end
|
||||
|
||||
Event.insert_all(attribute_sets, returning: %w[id])
|
||||
end
|
||||
|
||||
def create_push_event(service_class, project, current_user, push_data)
|
||||
|
@ -160,18 +208,24 @@ class EventCreateService
|
|||
action: status,
|
||||
author_id: current_user.id
|
||||
)
|
||||
|
||||
resource_parent_attr = case resource_parent
|
||||
when Project
|
||||
:project
|
||||
when Group
|
||||
:group
|
||||
end
|
||||
attributes[resource_parent_attr] = resource_parent if resource_parent_attr
|
||||
attributes.merge!(parent_attrs(resource_parent))
|
||||
|
||||
Event.create!(attributes)
|
||||
end
|
||||
|
||||
def parent_attrs(resource_parent)
|
||||
resource_parent_attr = case resource_parent
|
||||
when Project
|
||||
:project_id
|
||||
when Group
|
||||
:group_id
|
||||
end
|
||||
|
||||
return {} unless resource_parent_attr
|
||||
|
||||
{ resource_parent_attr => resource_parent.id }
|
||||
end
|
||||
|
||||
def create_resource_event(issuable, current_user, status)
|
||||
return unless state_change_tracking_enabled?(issuable)
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Support first_name and last_name attributes in LDAP user sync
|
||||
merge_request: 29542
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Added delete action for Dashboard Annotations in GraphQL
|
||||
merge_request: 33468
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add timezone display to alert based issue start time
|
||||
merge_request: 32702
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Render user-defined links in dashboard yml file on metrics dashboard
|
||||
merge_request: 32895
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add project_id, user_id, status, ref index to ci_pipelines
|
||||
merge_request: 33290
|
||||
author:
|
||||
type: performance
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Make project selector in various dashboard more translatable
|
||||
merge_request: 33771
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Support IAP protected prometheus installations
|
||||
merge_request: 33508
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add GitBook logo to project templates
|
||||
merge_request: 33403
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add Hugo logo to project templates
|
||||
merge_request: 33402
|
||||
author:
|
||||
type: changed
|
|
@ -626,3 +626,9 @@
|
|||
:why:
|
||||
:versions: []
|
||||
:when: 2019-11-08 10:03:31.787226000 Z
|
||||
- - :whitelist
|
||||
- CC0-1.0
|
||||
- :who: Thomas Randolph
|
||||
:why: This license is public domain
|
||||
:versions: []
|
||||
:when: 2020-06-03 05:04:44.632875345 Z
|
||||
|
|
|
@ -1,23 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
#
|
||||
# google-api-client >= 0.26.0 supports enabling CloudRun and Istio during
|
||||
# cluster creation, but fog-google currently hard deps on '~> 0.23.0', which
|
||||
# prevents us from upgrading. We are injecting these options as hashes below
|
||||
# as a workaround until this is resolved.
|
||||
#
|
||||
# This can be removed once fog-google and google-api-client can be upgraded.
|
||||
# See https://gitlab.com/gitlab-org/gitlab/issues/31280 for more details.
|
||||
#
|
||||
|
||||
require 'google/apis/container_v1beta1'
|
||||
require 'google/apis/options'
|
||||
|
||||
# these require solve load order issues (undefined constant Google::Apis::ServerError and Signet::RemoteServerError, rescued in multiple places)
|
||||
require 'google/apis/errors'
|
||||
require 'signet/errors'
|
||||
|
||||
# As stated in https://github.com/googleapis/google-api-ruby-client#errors--retries,
|
||||
# enabling retries is strongly encouraged but disabled by default. Large uploads
|
||||
# that may hit timeouts will mainly benefit from this.
|
||||
Google::Apis::RequestOptions.default.retries = 3 if Gitlab::Utils.to_boolean(ENV.fetch('ENABLE_GOOGLE_API_RETRIES', true))
|
||||
|
||||
Google::Apis::ContainerV1beta1::AddonsConfig::Representation.tap do |representation|
|
||||
representation.hash :cloud_run_config, as: 'cloudRunConfig'
|
||||
representation.hash :istio_config, as: 'istioConfig'
|
||||
end
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddProjectIdUserIdStatusRefIndexToCiPipelines < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
SOURCE_PARENT_PIPELINE = 12
|
||||
|
||||
def up
|
||||
add_concurrent_index(
|
||||
:ci_pipelines,
|
||||
[:project_id, :user_id, :status, :ref],
|
||||
where: "source != #{SOURCE_PARENT_PIPELINE}"
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index(
|
||||
:ci_pipelines,
|
||||
[:project_id, :user_id, :status, :ref],
|
||||
where: "source != #{SOURCE_PARENT_PIPELINE}"
|
||||
)
|
||||
end
|
||||
end
|
|
@ -9416,6 +9416,8 @@ CREATE INDEX index_ci_pipelines_on_project_id_and_status_and_config_source ON pu
|
|||
|
||||
CREATE INDEX index_ci_pipelines_on_project_id_and_status_and_updated_at ON public.ci_pipelines USING btree (project_id, status, updated_at);
|
||||
|
||||
CREATE INDEX index_ci_pipelines_on_project_id_and_user_id_and_status_and_ref ON public.ci_pipelines USING btree (project_id, user_id, status, ref) WHERE (source <> 12);
|
||||
|
||||
CREATE INDEX index_ci_pipelines_on_project_idandrefandiddesc ON public.ci_pipelines USING btree (project_id, ref, id DESC);
|
||||
|
||||
CREATE INDEX index_ci_pipelines_on_status ON public.ci_pipelines USING btree (status);
|
||||
|
@ -13791,6 +13793,7 @@ COPY "schema_migrations" (version) FROM STDIN;
|
|||
20200527152657
|
||||
20200528054112
|
||||
20200528123703
|
||||
20200528125905
|
||||
20200603073101
|
||||
\.
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ exceptions:
|
|||
- ASCII
|
||||
- AWS
|
||||
- CNAME
|
||||
- CPU
|
||||
- CSS
|
||||
- CSV
|
||||
- DNS
|
||||
|
@ -39,6 +40,7 @@ exceptions:
|
|||
- POST
|
||||
- PUT
|
||||
- RSA
|
||||
- RSS
|
||||
- SAML
|
||||
- SCP
|
||||
- SCSS
|
||||
|
@ -50,6 +52,7 @@ exceptions:
|
|||
- TIP
|
||||
- TLS
|
||||
- TODO
|
||||
- UNIX
|
||||
- URI
|
||||
- URL
|
||||
- VPC
|
||||
|
|
|
@ -113,6 +113,7 @@ Dreamweaver
|
|||
Elasticsearch
|
||||
enablement
|
||||
enqueued
|
||||
ETag
|
||||
Excon
|
||||
expirable
|
||||
Facebook
|
||||
|
|
|
@ -194,7 +194,7 @@ use the `hard` option, because (from the man page):
|
|||
|
||||
Other vendors make similar recommendations, including
|
||||
[SAP](http://wiki.scn.sap.com/wiki/x/PARnFQ) and NetApp's
|
||||
[knowledge base](https://kb.netapp.com/app/answers/answer_view/a_id/1004893/~/hard-mount-vs-soft-mount-),
|
||||
[knowledge base](https://kb.netapp.com/Advice_and_Troubleshooting/Data_Storage_Software/ONTAP_OS/What_are_the_differences_between_hard_mount_and_soft_mount),
|
||||
they highlight that if the NFS client driver caches data, `soft` means there is no certainty if
|
||||
writes by GitLab are actually on disk.
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ It allows you to see (from left to right):
|
|||
![Redis profiling using the Performance Bar](img/performance_bar_redis_calls.png)
|
||||
- total load timings of the page; click through for details of these calls. Values in the following order:
|
||||
- Backend - Time that the actual base page took to load
|
||||
- [First Contentful Paint](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint) - Time until something was visible to the user
|
||||
- [First Contentful Paint](hhttps://web.dev/first-contentful-paint/) - Time until something was visible to the user
|
||||
- [DomContentLoaded](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/measure-crp) Event
|
||||
- Number of Requests that the page loaded
|
||||
![Frontend requests using the Performance Bar](img/performance_bar_frontend.png)
|
||||
|
|
|
@ -6,30 +6,29 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# GitLab Prometheus metrics
|
||||
|
||||
>**Note:**
|
||||
Available since [Omnibus GitLab 9.3](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/29118). For
|
||||
installations from source you'll have to configure it yourself.
|
||||
|
||||
To enable the GitLab Prometheus metrics:
|
||||
|
||||
1. Log into GitLab as an administrator.
|
||||
1. Navigate to **Admin Area > Settings > Metrics and profiling**.
|
||||
1. Log into GitLab as a user with [administrator permissions](../../../user/permissions.md).
|
||||
1. Navigate to **{admin}** **Admin Area > Settings > Metrics and profiling**.
|
||||
1. Find the **Metrics - Prometheus** section, and click **Enable Prometheus Metrics**.
|
||||
1. [Restart GitLab](../../restart_gitlab.md#omnibus-gitlab-restart) for the changes to take effect.
|
||||
|
||||
NOTE: **Note:**
|
||||
For installations from source you'll have to configure it yourself.
|
||||
|
||||
## Collecting the metrics
|
||||
|
||||
GitLab monitors its own internal service metrics, and makes them available at the
|
||||
`/-/metrics` endpoint. Unlike other [Prometheus](https://prometheus.io) exporters, in order to access
|
||||
it, the client IP needs to be [included in a whitelist](../ip_whitelist.md).
|
||||
`/-/metrics` endpoint. Unlike other [Prometheus](https://prometheus.io) exporters, to access
|
||||
it, the client IP address needs to be [explicitly allowed](../ip_whitelist.md).
|
||||
|
||||
For Omnibus and Chart installations, these metrics are automatically enabled
|
||||
and collected as of [GitLab
|
||||
9.4](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1702). For
|
||||
source installations or earlier versions, these metrics will need to be enabled
|
||||
For [Omnibus GitLab](https://docs.gitlab.com/omnibus/) and Chart installations,
|
||||
these metrics are enabled and collected as of
|
||||
[GitLab 9.4](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1702).
|
||||
For source installations or earlier versions, these metrics must be enabled
|
||||
manually and collected by a Prometheus server.
|
||||
|
||||
See also [Sidekiq metrics](#sidekiq-metrics) for how to enable and view metrics from Sidekiq nodes.
|
||||
For enabling and viewing metrics from Sidekiq nodes, see [Sidekiq metrics](#sidekiq-metrics).
|
||||
|
||||
## Metrics available
|
||||
|
||||
|
@ -50,7 +49,7 @@ The following metrics are available:
|
|||
| `gitlab_method_call_duration_seconds` | Histogram | 10.2 | Method calls real duration | `controller`, `action`, `module`, `method` |
|
||||
| `gitlab_page_out_of_bounds` | Counter | 12.8 | Counter for the PageLimiter pagination limit being hit | `controller`, `action`, `bot` |
|
||||
| `gitlab_rails_queue_duration_seconds` | Histogram | 9.4 | Measures latency between GitLab Workhorse forwarding a request to Rails | |
|
||||
| `gitlab_sql_duration_seconds` | Histogram | 10.2 | SQL execution time, excluding SCHEMA operations and BEGIN / COMMIT | |
|
||||
| `gitlab_sql_duration_seconds` | Histogram | 10.2 | SQL execution time, excluding `SCHEMA` operations and `BEGIN` / `COMMIT` | |
|
||||
| `gitlab_transaction_allocated_memory_bytes` | Histogram | 10.2 | Allocated memory for all transactions (`gitlab_transaction_*` metrics) | |
|
||||
| `gitlab_transaction_cache_<key>_count_total` | Counter | 10.2 | Counter for total Rails cache calls (per key) | |
|
||||
| `gitlab_transaction_cache_<key>_duration_total` | Counter | 10.2 | Counter for total time (seconds) spent in Rails cache calls (per key) | |
|
||||
|
@ -65,11 +64,11 @@ The following metrics are available:
|
|||
| `gitlab_transaction_event_build_not_found_total` | Counter | 9.4 | Counter for build not found for API /jobs/request | |
|
||||
| `gitlab_transaction_event_change_default_branch_total` | Counter | 9.4 | Counter when default branch is changed for any repository | |
|
||||
| `gitlab_transaction_event_create_repository_total` | Counter | 9.4 | Counter when any repository is created | |
|
||||
| `gitlab_transaction_event_etag_caching_cache_hit_total` | Counter | 9.4 | Counter for etag cache hit. | `endpoint` |
|
||||
| `gitlab_transaction_event_etag_caching_header_missing_total` | Counter | 9.4 | Counter for etag cache miss - header missing | `endpoint` |
|
||||
| `gitlab_transaction_event_etag_caching_key_not_found_total` | Counter | 9.4 | Counter for etag cache miss - key not found | `endpoint` |
|
||||
| `gitlab_transaction_event_etag_caching_middleware_used_total` | Counter | 9.4 | Counter for etag middleware accessed | `endpoint` |
|
||||
| `gitlab_transaction_event_etag_caching_resource_changed_total` | Counter | 9.4 | Counter for etag cache miss - resource changed | `endpoint` |
|
||||
| `gitlab_transaction_event_etag_caching_cache_hit_total` | Counter | 9.4 | Counter for ETag cache hit. | `endpoint` |
|
||||
| `gitlab_transaction_event_etag_caching_header_missing_total` | Counter | 9.4 | Counter for ETag cache miss - header missing | `endpoint` |
|
||||
| `gitlab_transaction_event_etag_caching_key_not_found_total` | Counter | 9.4 | Counter for ETag cache miss - key not found | `endpoint` |
|
||||
| `gitlab_transaction_event_etag_caching_middleware_used_total` | Counter | 9.4 | Counter for ETag middleware accessed | `endpoint` |
|
||||
| `gitlab_transaction_event_etag_caching_resource_changed_total` | Counter | 9.4 | Counter for ETag cache miss - resource changed | `endpoint` |
|
||||
| `gitlab_transaction_event_fork_repository_total` | Counter | 9.4 | Counter for repository forks (RepositoryForkWorker). Only incremented when source repository exists | |
|
||||
| `gitlab_transaction_event_import_repository_total` | Counter | 9.4 | Counter for repository imports (RepositoryImportWorker) | |
|
||||
| `gitlab_transaction_event_push_branch_total` | Counter | 9.4 | Counter for all branch pushes | |
|
||||
|
@ -193,8 +192,6 @@ They all have these labels:
|
|||
1. `ActiveRecord::Base` is the main database connection.
|
||||
1. `Geo::TrackingBase` is the connection to the Geo tracking database, if
|
||||
enabled.
|
||||
1. `Gitlab::Database::LoadBalancing::Host` is a connection used by [database
|
||||
load balancing](../../database_load_balancing.md), if enabled.
|
||||
1. `host` - the host name used to connect to the database.
|
||||
1. `port` - the port used to connect to the database.
|
||||
|
||||
|
@ -238,31 +235,28 @@ Unicorn specific metrics, when Unicorn is used.
|
|||
|
||||
When Puma is used instead of Unicorn, the following metrics are available:
|
||||
|
||||
| Metric | Type | Since | Description |
|
||||
|:---------------------------------------------- |:------- |:----- |:----------- |
|
||||
| `puma_workers` | Gauge | 12.0 | Total number of workers |
|
||||
| `puma_running_workers` | Gauge | 12.0 | Number of booted workers |
|
||||
| `puma_stale_workers` | Gauge | 12.0 | Number of old workers |
|
||||
| `puma_running` | Gauge | 12.0 | Number of running threads |
|
||||
| `puma_queued_connections` | Gauge | 12.0 | Number of connections in that worker's "to do" set waiting for a worker thread |
|
||||
| `puma_active_connections` | Gauge | 12.0 | Number of threads processing a request |
|
||||
| `puma_pool_capacity` | Gauge | 12.0 | Number of requests the worker is capable of taking right now |
|
||||
| `puma_max_threads` | Gauge | 12.0 | Maximum number of worker threads |
|
||||
| `puma_idle_threads` | Gauge | 12.0 | Number of spawned threads which are not processing a request |
|
||||
| `puma_killer_terminations_total` | Gauge | 12.0 | Number of workers terminated by PumaWorkerKiller |
|
||||
| Metric | Type | Since | Description |
|
||||
|:--------------------------------- |:------- |:----- |:----------- |
|
||||
| `puma_workers` | Gauge | 12.0 | Total number of workers |
|
||||
| `puma_running_workers` | Gauge | 12.0 | Number of booted workers |
|
||||
| `puma_stale_workers` | Gauge | 12.0 | Number of old workers |
|
||||
| `puma_running` | Gauge | 12.0 | Number of running threads |
|
||||
| `puma_queued_connections` | Gauge | 12.0 | Number of connections in that worker's "to do" set waiting for a worker thread |
|
||||
| `puma_active_connections` | Gauge | 12.0 | Number of threads processing a request |
|
||||
| `puma_pool_capacity` | Gauge | 12.0 | Number of requests the worker is capable of taking right now |
|
||||
| `puma_max_threads` | Gauge | 12.0 | Maximum number of worker threads |
|
||||
| `puma_idle_threads` | Gauge | 12.0 | Number of spawned threads which are not processing a request |
|
||||
| `puma_killer_terminations_total` | Gauge | 12.0 | Number of workers terminated by PumaWorkerKiller |
|
||||
|
||||
## Metrics shared directory
|
||||
|
||||
GitLab's Prometheus client requires a directory to store metrics data shared between multi-process services.
|
||||
Those files are shared among all instances running under Unicorn server.
|
||||
The directory needs to be accessible to all running Unicorn's processes otherwise
|
||||
metrics will not function correctly.
|
||||
The directory must be accessible to all running Unicorn's processes, or
|
||||
metrics won't function correctly.
|
||||
|
||||
For best performance its advisable that this directory will be located in `tmpfs`.
|
||||
This directory's location is configured using environment variable `prometheus_multiproc_dir`.
|
||||
For best performance, create this directory in `tmpfs`.
|
||||
|
||||
Its location is configured using environment variable `prometheus_multiproc_dir`.
|
||||
|
||||
If GitLab is installed using Omnibus and `tmpfs` is available then metrics
|
||||
directory will be automatically configured.
|
||||
|
||||
[← Back to the main Prometheus page](index.md)
|
||||
If GitLab is installed using [Omnibus GitLab](https://docs.gitlab.com/omnibus/)
|
||||
and `tmpfs` is available, then the metrics directory will be configured for you.
|
||||
|
|
|
@ -6,27 +6,24 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Node exporter
|
||||
|
||||
>**Note:**
|
||||
Available since Omnibus GitLab 8.16. For installations from source you'll
|
||||
have to install and configure it yourself.
|
||||
|
||||
The [node exporter](https://github.com/prometheus/node_exporter) allows you to measure
|
||||
The [node exporter](https://github.com/prometheus/node_exporter) enables you to measure
|
||||
various machine resources such as memory, disk and CPU utilization.
|
||||
|
||||
NOTE: **Note:**
|
||||
For installations from source you'll have to install and configure it yourself.
|
||||
|
||||
To enable the node exporter:
|
||||
|
||||
1. [Enable Prometheus](index.md#configuring-prometheus)
|
||||
1. Edit `/etc/gitlab/gitlab.rb`
|
||||
1. Add or find and uncomment the following line, making sure it's set to `true`:
|
||||
1. [Enable Prometheus](index.md#configuring-prometheus).
|
||||
1. Edit `/etc/gitlab/gitlab.rb`.
|
||||
1. Add (or find and uncomment) the following line, making sure it's set to `true`:
|
||||
|
||||
```ruby
|
||||
node_exporter['enable'] = true
|
||||
```
|
||||
|
||||
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
|
||||
for the changes to take effect
|
||||
1. Save the file, and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
|
||||
for the changes to take effect.
|
||||
|
||||
Prometheus will now automatically begin collecting performance data from
|
||||
the node exporter exposed under `localhost:9100`.
|
||||
|
||||
[← Back to the main Prometheus page](index.md)
|
||||
Prometheus will now begin collecting performance data from the node exporter
|
||||
exposed at `localhost:9100`.
|
||||
|
|
|
@ -6,29 +6,30 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# PgBouncer exporter
|
||||
|
||||
>**Note:**
|
||||
Available since [Omnibus GitLab 11.0](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/2493).
|
||||
For installations from source you'll have to install and configure it yourself.
|
||||
> Introduced in [Omnibus GitLab 11.0](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/2493).
|
||||
|
||||
The [PgBouncer exporter](https://github.com/prometheus-community/pgbouncer_exporter) allows you to measure various PgBouncer metrics.
|
||||
The [PgBouncer exporter](https://github.com/prometheus-community/pgbouncer_exporter) enables
|
||||
you to measure various [PgBouncer](https://www.pgbouncer.org/) metrics.
|
||||
|
||||
NOTE: **Note:**
|
||||
For installations from source you'll have to install and configure it yourself.
|
||||
|
||||
To enable the PgBouncer exporter:
|
||||
|
||||
1. [Enable Prometheus](index.md#configuring-prometheus)
|
||||
1. Edit `/etc/gitlab/gitlab.rb`
|
||||
1. Add or find and uncomment the following line, making sure it's set to `true`:
|
||||
1. [Enable Prometheus](index.md#configuring-prometheus).
|
||||
1. Edit `/etc/gitlab/gitlab.rb`.
|
||||
1. Add (or find and uncomment) the following line, making sure it's set to `true`:
|
||||
|
||||
```ruby
|
||||
pgbouncer_exporter['enable'] = true
|
||||
```
|
||||
|
||||
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to
|
||||
take effect.
|
||||
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
|
||||
for the changes to take effect.
|
||||
|
||||
Prometheus will now automatically begin collecting performance data from
|
||||
the PgBouncer exporter exposed under `localhost:9188`.
|
||||
Prometheus will now begin collecting performance data from the PgBouncer exporter
|
||||
exposed at `localhost:9188`.
|
||||
|
||||
The PgBouncer exporter will also be enabled by default if the [`pgbouncer_role`](https://docs.gitlab.com/omnibus/roles/#postgres-roles)
|
||||
The PgBouncer exporter will also be enabled by default if the
|
||||
[`pgbouncer_role`](https://docs.gitlab.com/omnibus/roles/#postgresql-roles)
|
||||
role is enabled.
|
||||
|
||||
[← Back to the main Prometheus page](index.md)
|
||||
|
|
|
@ -6,12 +6,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# PostgreSQL Server Exporter
|
||||
|
||||
>**Note:**
|
||||
Available since [Omnibus GitLab 8.17](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1131).
|
||||
For installations from source you will have to install and configure it yourself.
|
||||
|
||||
The [PostgreSQL Server Exporter](https://github.com/wrouesnel/postgres_exporter) allows you to export various PostgreSQL metrics.
|
||||
|
||||
NOTE: **Note:**
|
||||
For installations from source you will have to install and configure it yourself.
|
||||
|
||||
To enable the PostgreSQL Server Exporter:
|
||||
|
||||
1. [Enable Prometheus](index.md#configuring-prometheus).
|
||||
|
@ -21,10 +20,10 @@ To enable the PostgreSQL Server Exporter:
|
|||
postgres_exporter['enable'] = true
|
||||
```
|
||||
|
||||
NOTE: **Note:**
|
||||
If PostgreSQL Server Exporter is configured on a separate node, make sure that the local
|
||||
address is [listed in `trust_auth_cidr_addresses`](../../high_availability/database.md#network-information) or the
|
||||
exporter will not be able to connect to the database.
|
||||
NOTE: **Note:**
|
||||
If PostgreSQL Server Exporter is configured on a separate node, make sure the local
|
||||
address is [listed in `trust_auth_cidr_addresses`](../../high_availability/database.md#network-information), or the
|
||||
exporter can't connect to the database.
|
||||
|
||||
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to
|
||||
take effect.
|
||||
|
@ -34,31 +33,44 @@ the PostgreSQL Server Exporter exposed under `localhost:9187`.
|
|||
|
||||
## Advanced configuration
|
||||
|
||||
In most cases, PostgreSQL Server Exporter will work with the defaults and you should not
|
||||
need to change anything.
|
||||
|
||||
To further customize the PostgreSQL Server Exporter, use the following configuration options:
|
||||
In most cases, PostgreSQL Server Exporter works with the defaults and you should not
|
||||
need to change anything. To further customize the PostgreSQL Server Exporter,
|
||||
use the following configuration options:
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb`:
|
||||
|
||||
```ruby
|
||||
postgres_exporter['dbname'] = 'pgbouncer' # The name of the database to connect to.
|
||||
postgres_exporter['user'] = 'gitlab-psql' # The user to sign in as.
|
||||
postgres_exporter['password'] = '' # The user's password.
|
||||
postgres_exporter['host'] = 'localhost' # The host to connect to. Values that start with '/' are for unix domain sockets (default is 'localhost').
|
||||
postgres_exporter['port'] = 5432 # The port to bind to (default is '5432').
|
||||
postgres_exporter['sslmode'] = 'require' # Whether or not to use SSL. Valid options are:
|
||||
# 'disable' (no SSL),
|
||||
# 'require' (always use SSL and skip verification, this is the default value),
|
||||
# 'verify-ca' (always use SSL and verify that the certificate presented by the server was signed by a trusted CA),
|
||||
# 'verify-full' (always use SSL and verify that the certification presented by the server was signed by a trusted CA and the server host name matches the one in the certificate).
|
||||
postgres_exporter['fallback_application_name'] = '' # An application_name to fall back to if one isn't provided.
|
||||
postgres_exporter['connect_timeout'] = '' # Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely.
|
||||
postgres_exporter['sslcert'] = 'ssl.crt' # Cert file location. The file must contain PEM encoded data.
|
||||
postgres_exporter['sslkey'] = 'ssl.key' # Key file location. The file must contain PEM encoded data.
|
||||
postgres_exporter['sslrootcert'] = 'ssl-root.crt' # The location of the root certificate file. The file must contain PEM encoded data.
|
||||
# The name of the database to connect to.
|
||||
postgres_exporter['dbname'] = 'pgbouncer'
|
||||
# The user to sign in as.
|
||||
postgres_exporter['user'] = 'gitlab-psql'
|
||||
# The user's password.
|
||||
postgres_exporter['password'] = ''
|
||||
# The host to connect to. Values that start with '/' are for unix domain sockets
|
||||
# (default is 'localhost').
|
||||
postgres_exporter['host'] = 'localhost'
|
||||
# The port to bind to (default is '5432').
|
||||
postgres_exporter['port'] = 5432
|
||||
# Whether or not to use SSL. Valid options are:
|
||||
# 'disable' (no SSL),
|
||||
# 'require' (always use SSL and skip verification, this is the default value),
|
||||
# 'verify-ca' (always use SSL and verify that the certificate presented by
|
||||
# the server was signed by a trusted CA),
|
||||
# 'verify-full' (always use SSL and verify that the certification presented
|
||||
# by the server was signed by a trusted CA and the server host name matches
|
||||
# the one in the certificate).
|
||||
postgres_exporter['sslmode'] = 'require'
|
||||
# An application_name to fall back to if one isn't provided.
|
||||
postgres_exporter['fallback_application_name'] = ''
|
||||
# Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely.
|
||||
postgres_exporter['connect_timeout'] = ''
|
||||
# Cert file location. The file must contain PEM encoded data.
|
||||
postgres_exporter['sslcert'] = 'ssl.crt'
|
||||
# Key file location. The file must contain PEM encoded data.
|
||||
postgres_exporter['sslkey'] = 'ssl.key'
|
||||
# The location of the root certificate file. The file must contain PEM encoded data.
|
||||
postgres_exporter['sslrootcert'] = 'ssl-root.crt'
|
||||
```
|
||||
|
||||
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
|
||||
|
||||
[← Back to the main Prometheus page](index.md)
|
||||
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
|
||||
for the changes to take effect.
|
||||
|
|
|
@ -6,19 +6,18 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Redis exporter
|
||||
|
||||
>**Note:**
|
||||
Available since [Omnibus GitLab 8.17](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1118).
|
||||
For installations from source you'll have to install and configure it yourself.
|
||||
|
||||
The [Redis exporter](https://github.com/oliver006/redis_exporter) allows you to measure
|
||||
various [Redis](https://redis.io) metrics. For more information on what's exported,
|
||||
The [Redis exporter](https://github.com/oliver006/redis_exporter) enables you to measure
|
||||
various [Redis](https://redis.io) metrics. For more information on what is exported,
|
||||
[read the upstream documentation](https://github.com/oliver006/redis_exporter/blob/master/README.md#whats-exported).
|
||||
|
||||
NOTE: **Note:**
|
||||
For installations from source you'll have to install and configure it yourself.
|
||||
|
||||
To enable the Redis exporter:
|
||||
|
||||
1. [Enable Prometheus](index.md#configuring-prometheus)
|
||||
1. Edit `/etc/gitlab/gitlab.rb`
|
||||
1. Add or find and uncomment the following line, making sure it's set to `true`:
|
||||
1. [Enable Prometheus](index.md#configuring-prometheus).
|
||||
1. Edit `/etc/gitlab/gitlab.rb`.
|
||||
1. Add (or find and uncomment) the following line, making sure it's set to `true`:
|
||||
|
||||
```ruby
|
||||
redis_exporter['enable'] = true
|
||||
|
@ -27,7 +26,5 @@ To enable the Redis exporter:
|
|||
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
|
||||
for the changes to take effect.
|
||||
|
||||
Prometheus will now automatically begin collecting performance data from
|
||||
the Redis exporter exposed under `localhost:9121`.
|
||||
|
||||
[← Back to the main Prometheus page](index.md)
|
||||
Prometheus will now begin collecting performance data from
|
||||
the Redis exporter exposed at `localhost:9121`.
|
||||
|
|
|
@ -1725,6 +1725,36 @@ type CreateSnippetPayload {
|
|||
snippet: Snippet
|
||||
}
|
||||
|
||||
"""
|
||||
Autogenerated input type of DeleteAnnotation
|
||||
"""
|
||||
input DeleteAnnotationInput {
|
||||
"""
|
||||
A unique identifier for the client performing the mutation.
|
||||
"""
|
||||
clientMutationId: String
|
||||
|
||||
"""
|
||||
The global id of the annotation to delete
|
||||
"""
|
||||
id: ID!
|
||||
}
|
||||
|
||||
"""
|
||||
Autogenerated return type of DeleteAnnotation
|
||||
"""
|
||||
type DeleteAnnotationPayload {
|
||||
"""
|
||||
A unique identifier for the client performing the mutation.
|
||||
"""
|
||||
clientMutationId: String
|
||||
|
||||
"""
|
||||
Errors encountered during execution of the mutation.
|
||||
"""
|
||||
errors: [String!]!
|
||||
}
|
||||
|
||||
"""
|
||||
The response from the AdminSidekiqQueuesDeleteJobs mutation.
|
||||
"""
|
||||
|
@ -7210,6 +7240,7 @@ type Mutation {
|
|||
createNote(input: CreateNoteInput!): CreateNotePayload
|
||||
createRequirement(input: CreateRequirementInput!): CreateRequirementPayload
|
||||
createSnippet(input: CreateSnippetInput!): CreateSnippetPayload
|
||||
deleteAnnotation(input: DeleteAnnotationInput!): DeleteAnnotationPayload
|
||||
designManagementDelete(input: DesignManagementDeleteInput!): DesignManagementDeletePayload
|
||||
designManagementUpload(input: DesignManagementUploadInput!): DesignManagementUploadPayload
|
||||
destroyNote(input: DestroyNoteInput!): DestroyNotePayload
|
||||
|
|
|
@ -4570,6 +4570,94 @@
|
|||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "INPUT_OBJECT",
|
||||
"name": "DeleteAnnotationInput",
|
||||
"description": "Autogenerated input type of DeleteAnnotation",
|
||||
"fields": null,
|
||||
"inputFields": [
|
||||
{
|
||||
"name": "id",
|
||||
"description": "The global id of the annotation to delete",
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null
|
||||
},
|
||||
{
|
||||
"name": "clientMutationId",
|
||||
"description": "A unique identifier for the client performing the mutation.",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null
|
||||
}
|
||||
],
|
||||
"interfaces": null,
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "DeleteAnnotationPayload",
|
||||
"description": "Autogenerated return type of DeleteAnnotation",
|
||||
"fields": [
|
||||
{
|
||||
"name": "clientMutationId",
|
||||
"description": "A unique identifier for the client performing the mutation.",
|
||||
"args": [
|
||||
|
||||
],
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "errors",
|
||||
"description": "Errors encountered during execution of the mutation.",
|
||||
"args": [
|
||||
|
||||
],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [
|
||||
|
||||
],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "DeleteJobsResponse",
|
||||
|
@ -20521,6 +20609,33 @@
|
|||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "deleteAnnotation",
|
||||
"description": null,
|
||||
"args": [
|
||||
{
|
||||
"name": "input",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "INPUT_OBJECT",
|
||||
"name": "DeleteAnnotationInput",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "OBJECT",
|
||||
"name": "DeleteAnnotationPayload",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "designManagementDelete",
|
||||
"description": null,
|
||||
|
|
|
@ -305,6 +305,15 @@ Autogenerated return type of CreateSnippet
|
|||
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
|
||||
| `snippet` | Snippet | The snippet after mutation |
|
||||
|
||||
## DeleteAnnotationPayload
|
||||
|
||||
Autogenerated return type of DeleteAnnotation
|
||||
|
||||
| Name | Type | Description |
|
||||
| --- | ---- | ---------- |
|
||||
| `clientMutationId` | String | A unique identifier for the client performing the mutation. |
|
||||
| `errors` | String! => Array | Errors encountered during execution of the mutation. |
|
||||
|
||||
## DeleteJobsResponse
|
||||
|
||||
The response from the AdminSidekiqQueuesDeleteJobs mutation.
|
||||
|
|
|
@ -1007,6 +1007,8 @@ Parameters:
|
|||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `api_url` | string | true | Prometheus API Base URL. For example, `http://prometheus.example.com/`. |
|
||||
| `google_iap_audience_client_id` | string | false | Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com) |
|
||||
| `google_iap_service_account_json` | string | false | credentials.json file for your service account, like { "type": "service_account", "project_id": ... } |
|
||||
|
||||
### Delete Prometheus service
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ Phoenix can run in any OS where Erlang is supported:
|
|||
- Fedora
|
||||
- Raspbian
|
||||
|
||||
Check the [Phoenix learning guide](https://hexdocs.pm/phoenix/learning.html) for more information.
|
||||
Check the [Phoenix learning guide](https://hexdocs.pm/phoenix/overview.html) for more information.
|
||||
|
||||
### What is Elixir?
|
||||
|
||||
|
|
|
@ -210,7 +210,7 @@ which can be used by projects in that instance.
|
|||
Declarative Jenkinsfiles contain "Sections" and "Directives" which are used to control the behavior of your
|
||||
pipelines. There are equivalents for all of these in GitLab, which we've documented below.
|
||||
|
||||
This section is based on the [Jenkinsfile syntax documentation](https://jenkins.io/doc/book/pipeline/syntax/)
|
||||
This section is based on the [Jenkinsfile syntax documentation](http://www.jenkins.io/doc/book/pipeline/syntax/)
|
||||
and is meant to be a mapping of concepts there to concepts in GitLab.
|
||||
|
||||
### Sections
|
||||
|
|
|
@ -2561,7 +2561,7 @@ job:
|
|||
|
||||
#### `artifacts:exclude`
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/15122) in GitLab 13.1
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15122) in GitLab 13.1
|
||||
> - Requires GitLab Runner 13.1
|
||||
|
||||
`exclude` makes it possible to prevent files from being added to an artifacts
|
||||
|
|
|
@ -11,7 +11,7 @@ coordinate with others to [document](../administration/instance_limits.md)
|
|||
and communicate those limits.
|
||||
|
||||
There is a guide about [introducing application
|
||||
limits](https://about.gitlab.com/handbook/product/product-management/process/index.html#introducing-application-limits).
|
||||
limits](https://about.gitlab.com/handbook/product/product-management/process/#introducing-application-limits).
|
||||
|
||||
## Development
|
||||
|
||||
|
|
|
@ -444,7 +444,7 @@ Lightweight connection pooler for PostgreSQL.
|
|||
|
||||
#### PgBouncer Exporter
|
||||
|
||||
- [Project page](https://github.com/stanhu/pgbouncer_exporter/blob/master/README.md)
|
||||
- [Project page](https://github.com/prometheus-community/pgbouncer_exporter/blob/master/README.md)
|
||||
- Configuration:
|
||||
- [Omnibus](../administration/monitoring/prometheus/pgbouncer_exporter.md)
|
||||
- [Charts](https://docs.gitlab.com/charts/installation/deployment.html#postgresql)
|
||||
|
|
|
@ -502,7 +502,7 @@ Properties of customer critical merge requests:
|
|||
- The DRI will assign the `customer-critical-merge-request` label to the merge request.
|
||||
- It is required that the reviewer(s) and maintainer(s) involved with a customer critical merge request are engaged as soon as this decision is made.
|
||||
- It is required to prioritize work for those involved on a customer critical merge request so that they have the time available necessary to focus on it.
|
||||
- It is required to adhere to GitLab [values](https://about.gitlab.com/handbook/values.md) and processes when working on customer critical merge requests, taking particular note of family and friends first/work second, definition of done, iteration, and release when it's ready.
|
||||
- It is required to adhere to GitLab [values](https://about.gitlab.com/handbook/values/) and processes when working on customer critical merge requests, taking particular note of family and friends first/work second, definition of done, iteration, and release when it's ready.
|
||||
- Customer critical merge requests are required to not reduce security, introduce data-loss risk, reduce availability, nor break existing functionality per the process for [prioritizing technical decisions](https://about.gitlab.com/handbook/engineering/#prioritizing-technical-decisions.md).
|
||||
- On customer critical requests, it is _recommended_ that those involved _consider_ coordinating synchronously (Zoom, Slack) in addition to asynchronously (merge requests comments) if they believe this will reduce elapsed time to merge even though this _may_ sacrifice [efficiency](https://about.gitlab.com/company/culture/all-remote/asynchronous/#evaluating-efficiency.md).
|
||||
- After a customer critical merge request is merged, a retrospective must be completed with the intention of reducing the frequency of future customer critical merge requests.
|
||||
|
|
|
@ -96,7 +96,7 @@ Having a knowledge base in any form that is separate from the documentation woul
|
|||
|
||||
All GitLab documentation is written using [Markdown](https://en.wikipedia.org/wiki/Markdown).
|
||||
|
||||
The [documentation website](https://docs.gitlab.com) uses GitLab Kramdown as its Markdown rendering engine. For a complete Kramdown reference, see the [GitLab Markdown Kramdown Guide](https://about.gitlab.com/handbook/engineering/ux/technical-writing/markdown-guide/).
|
||||
The [documentation website](https://docs.gitlab.com) uses GitLab Kramdown as its Markdown rendering engine. For a complete Kramdown reference, see the [GitLab Markdown Kramdown Guide](https://about.gitlab.com/handbook/markdown-guide/).
|
||||
|
||||
The [`gitlab-kramdown`](https://gitlab.com/gitlab-org/gitlab_kramdown)
|
||||
Ruby gem will support all [GFM markup](../../user/markdown.md) in the future. That is,
|
||||
|
|
|
@ -54,7 +54,7 @@ To update GitLab documentation:
|
|||
1. Follow the described standards and processes listed on the page, including:
|
||||
- The [Structure and template](structure.md) page.
|
||||
- The [Style Guide](styleguide.md).
|
||||
- The [Markdown Guide](https://about.gitlab.com/handbook/engineering/ux/technical-writing/markdown-guide/).
|
||||
- The [Markdown Guide](https://about.gitlab.com/handbook/markdown-guide/).
|
||||
1. Follow GitLab's [Merge Request Guidelines](../contributing/merge_request_workflow.md#merge-request-guidelines).
|
||||
|
||||
TIP: **Tip:**
|
||||
|
|
|
@ -32,7 +32,7 @@ because they can create conflicts in the dependency tree. Blocked dependencies a
|
|||
|
||||
### BootstrapVue
|
||||
|
||||
[BootstrapVue](https://bootstrap-vue.js.org/) is a component library built with Vue.js and Bootstrap.
|
||||
[BootstrapVue](https://bootstrap-vue.org/) is a component library built with Vue.js and Bootstrap.
|
||||
We wrap BootstrapVue components in [GitLab UI](https://gitlab.com/gitlab-org/gitlab-ui/) with the
|
||||
purpose of applying visual styles and usage guidelines specified in the
|
||||
[Pajamas Design System](https://design.gitlab.com/). For this reason, we recommend not installing
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
### Libraries
|
||||
|
||||
We use [Apollo](https://www.apollographql.com/) (specifically [Apollo Client](https://www.apollographql.com/docs/react/)) and [Vue Apollo](https://github.com/Akryum/vue-apollo/)
|
||||
We use [Apollo](https://www.apollographql.com/) (specifically [Apollo Client](https://www.apollographql.com/docs/react/)) and [Vue Apollo](https://github.com/vuejs/vue-apollo)
|
||||
when using GraphQL for frontend development.
|
||||
|
||||
If you are using GraphQL within a Vue application, the [Usage in Vue](#usage-in-vue) section
|
||||
|
@ -153,7 +153,7 @@ new Vue({
|
|||
});
|
||||
```
|
||||
|
||||
Read more about [Vue Apollo](https://github.com/vuejs/vue-apollo) in the [Vue Apollo documentation](https://vue-apollo.netlify.com/guide/).
|
||||
Read more about [Vue Apollo](https://github.com/vuejs/vue-apollo) in the [Vue Apollo documentation](https://vue-apollo.netlify.app/guide/).
|
||||
|
||||
### Local state with Apollo
|
||||
|
||||
|
@ -265,7 +265,7 @@ const defaultClient = createDefaultClient(
|
|||
|
||||
Now every single time on attempt to fetch a version, our client will fetch `id` and `sha` from the remote API endpoint and will assign our hardcoded values to `author` and `createdAt` version properties. With this data, frontend developers are able to work on UI part without being blocked by backend. When actual response is added to the API, a custom local resolver can be removed fast and the only change to query/fragment is `@client` directive removal.
|
||||
|
||||
Read more about local state management with Apollo in the [Vue Apollo documentation](https://vue-apollo.netlify.com/guide/local-state.html#local-state).
|
||||
Read more about local state management with Apollo in the [Vue Apollo documentation](https://vue-apollo.netlify.app/guide/local-state.html#local-state).
|
||||
|
||||
### Using with Vuex
|
||||
|
||||
|
|
|
@ -306,7 +306,7 @@ const dateFormat = createDateTimeFormat({ year: 'numeric', month: 'long', day: '
|
|||
console.log(dateFormat.format(new Date('2063-04-05'))) // April 5, 2063
|
||||
```
|
||||
|
||||
This makes use of [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat).
|
||||
This makes use of [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat).
|
||||
|
||||
- In Ruby/HAML, we have two ways of adding format to dates and times:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# How to run Jenkins in development environment (on macOS) **(STARTER)**
|
||||
|
||||
This is a step by step guide on how to set up [Jenkins](https://jenkins.io/) on your local machine and connect to it from your GitLab instance. GitLab triggers webhooks on Jenkins, and Jenkins connects to GitLab using the API. By running both applications on the same machine, we can make sure they are able to access each other.
|
||||
This is a step by step guide on how to set up [Jenkins](http://www.jenkins.io/) on your local machine and connect to it from your GitLab instance. GitLab triggers webhooks on Jenkins, and Jenkins connects to GitLab using the API. By running both applications on the same machine, we can make sure they are able to access each other.
|
||||
|
||||
## Install Jenkins
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ and set this column to `false`. The old servers were still updating the old colu
|
|||
that updated the new column from the old one. For the new servers though, they were only updating the new column and that same trigger
|
||||
was now working against us and setting it back to the wrong value.
|
||||
|
||||
For more information, see [the relevant issue](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/9176).
|
||||
For more information, see this [confidential issue](../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/9176`.
|
||||
|
||||
### Sidebar wasn't loading for some users
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ Any frontend engineer can contribute to this dashboard. They can contribute by a
|
|||
|
||||
There are 3 recommended high impact metrics to review on each page:
|
||||
|
||||
- [First visual change](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)
|
||||
- [First visual change](https://web.dev/first-meaningful-paint/)
|
||||
- [Speed Index](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index)
|
||||
- [Visual Complete 95%](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index)
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ Be careful to **also test [visibility levels](https://gitlab.com/gitlab-org/gitl
|
|||
|
||||
Some example of well implemented access controls and tests:
|
||||
|
||||
1. [example1](https://dev.gitlab.org/gitlab/gitlab-ee/merge_requests/710/diffs?diff_id=13750#af40ef0eaae3c1e018809e1d88086e32bccaca40_43_43)
|
||||
1. [example1](https://dev.gitlab.org/gitlab/gitlab-ee/-/merge_requests/710/diffs?diff_id=13750#af40ef0eaae3c1e018809e1d88086e32bccaca40_43_43)
|
||||
1. [example2](https://dev.gitlab.org/gitlab/gitlabhq/-/merge_requests/2511/diffs#ed3aaab1510f43b032ce345909a887e5b167e196_142_155)
|
||||
1. [example3](https://dev.gitlab.org/gitlab/gitlabhq/-/merge_requests/3170/diffs?diff_id=17494)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ Following are two great articles that everyone should read to understand what
|
|||
automated testing means, and what are its principles:
|
||||
|
||||
- [Five Factor Testing](https://madeintandem.com/blog/five-factor-testing/): Why do we need tests?
|
||||
- [Principles of Automated Testing](http://www.lihaoyi.com/post/PrinciplesofAutomatedTesting.html): Levels of testing. Prioritize tests. Cost of tests.
|
||||
- [Principles of Automated Testing](https://www.lihaoyi.com/post/PrinciplesofAutomatedTesting.html): Levels of testing. Prioritize tests. Cost of tests.
|
||||
|
||||
## [Testing levels](testing_levels.md)
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ If [Review App Stability](https://app.periscopedata.com/app/gitlab/496118/Engine
|
|||
dips this may be a signal that the `review-apps-ce/ee` cluster is unhealthy.
|
||||
Leading indicators may be health check failures leading to restarts or majority failure for Review App deployments.
|
||||
|
||||
The [Review Apps Overview dashboard](https://app.google.stackdriver.com/dashboards/6798952013815386466?project=gitlab-review-apps&timeDomain=1d)
|
||||
The [Review Apps Overview dashboard](https://console.cloud.google.com/monitoring/classic/dashboards/6798952013815386466?project=gitlab-review-apps&timeDomain=1d)
|
||||
aids in identifying load spikes on the cluster, and if nodes are problematic or the entire cluster is trending towards unhealthy.
|
||||
|
||||
### Release failed with `ImagePullBackOff`
|
||||
|
|
|
@ -50,7 +50,7 @@ prompt, terminal, and command line) of your preference. Here are some suggestion
|
|||
- [iTerm2](https://www.iterm2.com/), which you can integrate with [zsh](https://git-scm.com/book/id/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-Zsh) and [oh my zsh](https://ohmyz.sh/) for color highlighting, among other handy features for Git users.
|
||||
- For Windows users:
|
||||
- Built-in: **cmd**. Click the search icon on the bottom navbar on Windows and type "cmd" to find it.
|
||||
- [PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-7): a Windows "powered up" shell, from which you can execute a greater number of commands.
|
||||
- [PowerShell](https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/install/installing-windows-powershell): a Windows "powered up" shell, from which you can execute a greater number of commands.
|
||||
- Git Bash: it comes built into [Git for Windows](https://gitforwindows.org/).
|
||||
- For Linux users:
|
||||
- Built-in: [Linux Terminal](https://www.howtogeek.com/140679/beginner-geek-how-to-start-using-the-linux-terminal/).
|
||||
|
|
|
@ -177,7 +177,7 @@ Click **"Save"** for the changes to take effect.
|
|||
domain registrar which points to the public IP address of your Azure VM. If you do this, you'll need
|
||||
to make sure your VM is configured to use a _static_ public IP address (i.e. not a _dynamic_ one)
|
||||
or you will have to reconfigure the DNS `A` record each time Azure reassigns your VM a new public IP
|
||||
address. Read [IP address types and allocation methods in Azure](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-ip-addresses-overview-arm) to learn more.
|
||||
address. Read [Public IP addresses](https://docs.microsoft.com/en-us/azure/virtual-network/public-ip-addresses) to learn more.
|
||||
|
||||
## Let's open some ports
|
||||
|
||||
|
|
|
@ -275,11 +275,11 @@ You can provide feedback [on this issue](https://gitlab.com/gitlab-org/gitlab/-/
|
|||
|
||||
GitLab supports the following web browsers:
|
||||
|
||||
- [Mozilla Firefox](https://www.mozilla.org/firefox/new/)
|
||||
- [Mozilla Firefox](https://www.mozilla.org/en-US/firefox/new/)
|
||||
- [Google Chrome](https://www.google.com/chrome/)
|
||||
- [Chromium](https://www.chromium.org/getting-involved/dev-channel)
|
||||
- [Apple Safari](https://www.apple.com/safari/)
|
||||
- [Microsoft Edge](https://www.microsoft.com/edge)
|
||||
- [Microsoft Edge](https://www.microsoft.com/en-us/edge)
|
||||
|
||||
For the listed web browsers, GitLab supports:
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ The following assumes you already have Vault installed and running.
|
|||
First you'll need to create a GitLab application to obtain an application ID and secret for authenticating into Vault. To do this, sign in to GitLab and follow these steps:
|
||||
|
||||
1. On GitLab, click your avatar on the top-right corner, and select your user **Settings > Applications**.
|
||||
1. Fill out the application **Name** and [**Redirect URI**](https://www.vaultproject.io/docs/auth/jwt/#redirect-uris),
|
||||
1. Fill out the application **Name** and [**Redirect URI**](https://www.vaultproject.io/docs/auth/jwt#redirect-uris),
|
||||
making sure to select the **OpenID** scope.
|
||||
1. Save application.
|
||||
1. Copy client ID and secret, or keep the page open for reference.
|
||||
|
|
|
@ -141,7 +141,7 @@ You can assign the directory and file name of your choice.
|
|||
You can also dedicate that SSH key pair to a [specific host](#working-with-non-default-ssh-key-pair-paths).
|
||||
|
||||
After assigning a file to save your SSH key, you'll get a chance to set up
|
||||
a [passphrase](https://www.ssh.com/ssh/passphrase) for your SSH key:
|
||||
a [passphrase](https://www.ssh.com/ssh/passphrase/) for your SSH key:
|
||||
|
||||
```plaintext
|
||||
Enter passphrase (empty for no passphrase):
|
||||
|
@ -412,7 +412,7 @@ are *explicitly not supported* and may stop working at any time.
|
|||
|
||||
### Options for Microsoft Windows
|
||||
|
||||
If you're running Windows 10, the [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install-win10), and its latest [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/wsl2-install) version,
|
||||
If you're running Windows 10, the [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install-win10), and its latest [WSL 2](https://docs.microsoft.com/install-win10) version,
|
||||
support the installation of different Linux distributions, which include the Git and SSH clients.
|
||||
|
||||
For current versions of Windows, you can also install the Git and SSH clients with
|
||||
|
|
|
@ -44,5 +44,5 @@ This page gathers all the resources for the topic **Authentication** within GitL
|
|||
|
||||
- [Kanboard Plugin GitLab Authentication](https://github.com/kanboard/plugin-gitlab-auth)
|
||||
- [Jenkins GitLab OAuth Plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+OAuth+Plugin)
|
||||
- [How to customize GitLab to support OpenID authentication](http://eric.van-der-vlist.com/blog/2013/11/23/how-to-customize-gitlab-to-support-openid-authentication/)
|
||||
- [How to customize GitLab to support OpenID authentication](https://eric.van-der-vlist.com/blog/2013/11/23/how-to-customize-gitlab-to-support-openid-authentication//)
|
||||
- [OKD - Configuring Authentication and User Agent](https://docs.okd.io/3.11/install_config/configuring_authentication.html#GitLab)
|
||||
|
|
|
@ -497,7 +497,7 @@ traffic within a local namespace, and from the `gitlab-managed-apps`
|
|||
namespace. All other inbound connections are blocked. Outbound
|
||||
traffic (for example, to the Internet) is not affected by the default policy.
|
||||
|
||||
You can also provide a custom [policy specification](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.16/#networkpolicyspec-v1-networking-k8s-io)
|
||||
You can also provide a custom [policy specification](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
|
||||
in the `.gitlab/auto-deploy-values.yaml` file, for example:
|
||||
|
||||
```yaml
|
||||
|
|
|
@ -70,7 +70,7 @@ more advanced rules around threat detection.
|
|||
|
||||
## Features
|
||||
|
||||
ModSecurity is enabled with the [OWASP Core Rule Set (CRS)](https://modsecurity.org/crs/) by
|
||||
ModSecurity is enabled with the [OWASP Core Rule Set (CRS)](https://github.com/coreruleset/coreruleset/) by
|
||||
default. The OWASP CRS logs attempts to the following attacks:
|
||||
|
||||
- [SQL Injection](https://wiki.owasp.org/index.php/OWASP_Periodic_Table_of_Vulnerabilities_-_SQL_Injection)
|
||||
|
@ -87,7 +87,7 @@ It is good to have a basic knowledge of the following:
|
|||
- [Kubernetes](https://kubernetes.io/docs/home/)
|
||||
- [Ingress](https://kubernetes.github.io/ingress-nginx/)
|
||||
- [ModSecurity](https://www.modsecurity.org/)
|
||||
- [OWASP Core Rule Set](https://modsecurity.org/crs/)
|
||||
- [OWASP Core Rule Set](https://github.com/coreruleset/coreruleset/)
|
||||
|
||||
## Roadmap
|
||||
|
||||
|
|
|
@ -254,5 +254,5 @@ You can explore them in more detail:
|
|||
|
||||
- [GitLab Defend Vision](https://about.gitlab.com/direction/defend/#waf)
|
||||
- [ModSecurity](https://www.modsecurity.org/)
|
||||
- [OWASP Core Rule Set](https://modsecurity.org/crs/)
|
||||
- [OWASP Core Rule Set](https://github.com/coreruleset/coreruleset/)
|
||||
- [AutoDevOps](../autodevops/index.md)
|
||||
|
|
|
@ -76,7 +76,6 @@ The GitLab University curriculum is composed of GitLab videos, screencasts, pres
|
|||
- Getting Technical Support
|
||||
- Being part of our Great Community and Contributing to GitLab
|
||||
1. [Getting Started with the GitLab Development Kit (GDK)](https://about.gitlab.com/blog/2016/06/08/getting-started-with-gitlab-development-kit/)
|
||||
1. [Contributing Technical Articles to the GitLab Blog](https://about.gitlab.com/blog/2016/01/26/call-for-writers/)
|
||||
1. [GitLab Training Workshops](training/end-user/README.md)
|
||||
1. [GitLab Professional Services](https://about.gitlab.com/services/)
|
||||
|
||||
|
@ -176,7 +175,7 @@ The GitLab University curriculum is composed of GitLab videos, screencasts, pres
|
|||
|
||||
1. [Scalability and High Availability - Video](https://www.youtube.com/watch?v=cXRMJJb6sp4&list=PLFGfElNsQthbQu_IWlNOxul0TbS_2JH-e&index=2)
|
||||
1. [High Availability - Video](https://www.youtube.com/watch?v=36KS808u6bE&index=15&list=PLFGfElNsQthbQu_IWlNOxul0TbS_2JH-e)
|
||||
1. [High Availability Documentation](https://about.gitlab.com/solutions/high-availability/)
|
||||
1. [High Availability Documentation](https://about.gitlab.com/solutions/reference-architectures/)
|
||||
|
||||
### 3.8 Cycle Analytics
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ Zendesk is our Support Center and our main communication line with our Customers
|
|||
|
||||
Some tickets need specific knowledge or a deep understanding of a particular component and will need to be escalated to a Senior Service Engineer or Developer
|
||||
|
||||
- Read about [Escalation](https://about.gitlab.com/handbook/support/workflows/issue_escalations.html)
|
||||
- Read about [Escalation](https://about.gitlab.com/handbook/support/workflows/working-with-issues.html#functional-escalation-points)
|
||||
- Find the macros in Zendesk for ticket escalations
|
||||
- Take a look at the [GitLab.com Team page](https://about.gitlab.com/company/team/) to find the resident experts in their fields
|
||||
|
||||
|
|
|
@ -990,17 +990,17 @@ when upgrading the Vault application.
|
|||
|
||||
To optimally use Vault in a production environment, it's ideal to have a good understanding
|
||||
of the internals of Vault and how to configure it. This can be done by reading the
|
||||
[the Vault documentation](https://www.vaultproject.io/docs/internals/) as well as
|
||||
[the Vault documentation](https://www.vaultproject.io/docs/internals) as well as
|
||||
the Vault Helm chart [`values.yaml` file](https://github.com/hashicorp/vault-helm/blob/v0.3.3/values.yaml).
|
||||
|
||||
At a minimum you will likely set up:
|
||||
|
||||
- A [seal](https://www.vaultproject.io/docs/configuration/seal/) for extra encryption
|
||||
- A [seal](https://www.vaultproject.io/docs/configuration/seal) for extra encryption
|
||||
of the master key.
|
||||
- A [storage backend](https://www.vaultproject.io/docs/configuration/storage/) that is
|
||||
- A [storage backend](https://www.vaultproject.io/docs/configuration/storage) that is
|
||||
suitable for environment and storage security requirements.
|
||||
- [HA Mode](https://www.vaultproject.io/docs/concepts/ha/).
|
||||
- [The Vault UI](https://www.vaultproject.io/docs/configuration/ui/).
|
||||
- [HA Mode](https://www.vaultproject.io/docs/concepts/ha).
|
||||
- [The Vault UI](https://www.vaultproject.io/docs/configuration/ui).
|
||||
|
||||
The following is an example values file (`.gitlab/managed-apps/vault/values.yaml`)
|
||||
that configures Google Key Management Service for auto-unseal, using a Google Cloud Storage backend, enabling
|
||||
|
|
|
@ -64,7 +64,7 @@ The following languages and package managers are supported.
|
|||
| Go | [Godep](https://github.com/tools/godep), [go mod](https://github.com/golang/go/wiki/Modules) |[License Finder](https://github.com/pivotal/LicenseFinder)|
|
||||
| Java | [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/) |[License Finder](https://github.com/pivotal/LicenseFinder)|
|
||||
| .NET | [Nuget](https://www.nuget.org/) (.NET Framework is supported via the [mono project](https://www.mono-project.com/). Windows specific dependencies are not supported at this time.) |[License Finder](https://github.com/pivotal/LicenseFinder)|
|
||||
| Python | [pip](https://pip.pypa.io/en/stable/) (Python is supported through [requirements.txt](https://pip.readthedocs.io/en/1.1/requirements.html) and [Pipfile.lock](https://github.com/pypa/pipfile#pipfilelock).) |[License Finder](https://github.com/pivotal/LicenseFinder)|
|
||||
| Python | [pip](https://pip.pypa.io/en/stable/) (Python is supported through [requirements.txt](https://pip.pypa.io/en/1.1/requirements/) and [Pipfile.lock](https://github.com/pypa/pipfile#pipfilelock).) |[License Finder](https://github.com/pivotal/LicenseFinder)|
|
||||
| Ruby | [gem](https://rubygems.org/) |[License Finder](https://github.com/pivotal/LicenseFinder)|
|
||||
| Objective-C, Swift | [Carthage](https://github.com/Carthage/Carthage) |[License Finder](https://github.com/pivotal/LicenseFinder)|
|
||||
|
||||
|
@ -339,7 +339,7 @@ strict-ssl = false
|
|||
|
||||
### Configuring Yarn projects
|
||||
|
||||
You can configure Yarn projects by using a [`.yarnrc.yml`](https://yarnpkg.com/configuration/yarnrc)
|
||||
You can configure Yarn projects by using a [`.yarnrc.yml`](https://yarnpkg.com/configuration/yarnrc/)
|
||||
file.
|
||||
|
||||
#### Using private Yarn registries
|
||||
|
|
|
@ -231,7 +231,7 @@ NOTE: **Note:** GitLab is unable to provide support for IdPs that are not listed
|
|||
|----------|---------------|
|
||||
| ADFS (Active Directory Federation Services) | [Create a Relying Party Trust](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-relying-party-trust) |
|
||||
| Azure | [Configuring single sign-on to applications](https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/configure-single-sign-on-non-gallery-applications) |
|
||||
| Okta | [Setting up a SAML application in Okta](https://developer.okta.com/docs/guides/saml-application-setup/overview/) |
|
||||
| Okta | [Setting up a SAML application in Okta](https://developer.okta.com/docs/guides/build-sso-integration/saml2/overview/) |
|
||||
| OneLogin | [Use the OneLogin SAML Test Connector](https://onelogin.service-now.com/support?id=kb_article&sys_id=93f95543db109700d5505eea4b96198f) |
|
||||
|
||||
When [configuring your identify provider](#configuring-your-identity-provider), please consider the notes below for specific providers to help avoid common issues and as a guide for terminology used.
|
||||
|
|
|
@ -117,7 +117,7 @@ Once synchronized, changing the field mapped to `id` and `externalId` will likel
|
|||
|
||||
### Okta configuration steps
|
||||
|
||||
The SAML application that was created during [Single sign-on](index.md#okta-setup-notes) setup for [Okta](https://developer.okta.com/docs/guides/saml-application-setup/overview/) now needs to be set up for SCIM.
|
||||
The SAML application that was created during [Single sign-on](index.md#okta-setup-notes) setup for [Okta](https://developer.okta.com/docs/guides/build-sso-integration/saml2/overview/) now needs to be set up for SCIM.
|
||||
Before proceeding, be sure to complete the [GitLab configuration](#gitlab-configuration) process.
|
||||
|
||||
1. Sign in to Okta.
|
||||
|
|
|
@ -11,7 +11,7 @@ It is **not** valid for the [GitLab documentation website](https://docs.gitlab.c
|
|||
or [GitLab's main website](https://about.gitlab.com), as they both use
|
||||
[Kramdown](https://kramdown.gettalong.org) as their Markdown engine. The documentation
|
||||
website uses an extended Kramdown gem, [GitLab Kramdown](https://gitlab.com/gitlab-org/gitlab_kramdown).
|
||||
Consult the [GitLab Kramdown Guide](https://about.gitlab.com/handbook/engineering/ux/technical-writing/markdown-guide/)
|
||||
Consult the [GitLab Kramdown Guide](https://about.gitlab.com/handbook/markdown-guide/)
|
||||
for a complete Kramdown reference.
|
||||
|
||||
NOTE: **Note:** We encourage you to view this document as [rendered by GitLab itself](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/markdown.md).
|
||||
|
|
|
@ -101,7 +101,7 @@ The handler definition will provision the Lambda function using the source code
|
|||
|
||||
The `events` declaration will create a AWS API Gateway `GET` endpoint to receive external requests and hand them over to the Lambda function via a service integration.
|
||||
|
||||
You can read more about the available properties and additional configuration possibilities of the Serverless Framework here: <https://serverless.com/framework/docs/providers/aws/guide/serverless.yml/>
|
||||
You can read more about the [available properties and additional configuration possibilities](https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml/) of the Serverless Framework.
|
||||
|
||||
#### Crafting the `.gitlab-ci.yml` file
|
||||
|
||||
|
@ -275,7 +275,7 @@ module.exports.hello = async event => {
|
|||
};
|
||||
```
|
||||
|
||||
For more information, see the [Your CORS and API Gateway survival guide](https://serverless.com/blog/cors-api-gateway-survival-guide/)
|
||||
For more information, see the [Your CORS and API Gateway survival guide](https://www.serverless.com/blog/cors-api-gateway-survival-guide/)
|
||||
blog post written by the Serverless Framework team.
|
||||
|
||||
#### Writing automated tests
|
||||
|
|
|
@ -6,7 +6,7 @@ type: concepts
|
|||
|
||||
Team Foundation Server (TFS), renamed [Azure DevOps Server](https://azure.microsoft.com/en-us/services/devops/server/)
|
||||
in 2019, is a set of tools developed by Microsoft which also includes
|
||||
[Team Foundation Version Control](https://docs.microsoft.com/en-us/azure/devops/repos/tfvc/overview?view=azure-devops)
|
||||
[Team Foundation Version Control](https://docs.microsoft.com/en-us/azure/devops/repos/tfvc/what-is-tfvc?view=azure-devops)
|
||||
(TFVC), a centralized version control system similar to Git.
|
||||
|
||||
In this document, we focus on the TFVC to Git migration.
|
||||
|
|
|
@ -32,7 +32,7 @@ integration settings.
|
|||
|
||||
Keep in mind that you need to have the appropriate permissions for your Slack
|
||||
team in order to be able to install a new application, read more in Slack's
|
||||
docs on [Adding an app to your team](https://slack.com/help/articles/202035138).
|
||||
docs on [Adding an app to your workspace](https://slack.com/help/articles/202035138-Add-an-app-to-your-workspace).
|
||||
|
||||
To enable GitLab's service for your Slack team:
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
An API token is needed when integrating with Jira Cloud, follow the steps
|
||||
below to create one:
|
||||
|
||||
1. Log in to <https://id.atlassian.com/manage/api-tokens> with your email address.
|
||||
1. Log in to [`id.atlassian.com`](https://id.atlassian.com/manage-profile/security/api-tokens) with your email address.
|
||||
|
||||
NOTE: **Note**
|
||||
It is important that the user associated with this email address has *write* access
|
||||
|
|
|
@ -865,7 +865,7 @@ You can create annotations by making requests to the
|
|||
|
||||
#### Retention policy
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/211433) in GitLab 13.01.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211433) in GitLab 13.01.
|
||||
|
||||
To avoid excessive storage space consumption by stale annotations, records attached
|
||||
to time periods older than two weeks are removed daily. This recurring background
|
||||
|
|
|
@ -208,12 +208,12 @@ At present, full URL references are supported. For example, if we refer to a des
|
|||
somewhere with:
|
||||
|
||||
```markdown
|
||||
See http://gitlab.com/your-group/your-project/-/issues/123/designs/homescreen.png
|
||||
See https://gitlab.com/your-group/your-project/-/issues/123/designs/homescreen.png
|
||||
```
|
||||
|
||||
This will be rendered as:
|
||||
|
||||
> See [#123[homescreen.png]](http://gitlab.com/your-group/your-project/-/issues/123/designs/homescreen.png)
|
||||
> See [#123[homescreen.png]](https://gitlab.com/your-group/your-project/-/issues/123/designs/homescreen.png)
|
||||
|
||||
### Enable or disable design references **(CORE ONLY)**
|
||||
|
||||
|
|
|
@ -583,6 +583,18 @@ module API
|
|||
name: :api_url,
|
||||
type: String,
|
||||
desc: 'Prometheus API Base URL, like http://prometheus.example.com/'
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
name: :google_iap_audience_client_id,
|
||||
type: String,
|
||||
desc: 'Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)'
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
name: :google_iap_service_account_json,
|
||||
type: String,
|
||||
desc: 'Contents of the credentials.json file of your service account, like: { "type": "service_account", "project_id": ... }'
|
||||
}
|
||||
],
|
||||
'pushover' => [
|
||||
|
|
|
@ -173,7 +173,10 @@ module Gitlab
|
|||
value = payload&.dig(field)
|
||||
return unless value
|
||||
|
||||
Time.rfc3339(value)
|
||||
# value is a rfc3339 timestamp
|
||||
# Timestamps from Prometheus and Alertmanager are UTC RFC3339 timestamps like: '2018-03-12T09:06:00Z' (Z represents 0 offset or UTC)
|
||||
# .utc sets the datetime zone to `UTC`
|
||||
Time.rfc3339(value).utc
|
||||
rescue ArgumentError
|
||||
end
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ module Gitlab
|
|||
*config.attributes['name'],
|
||||
*config.attributes['email'],
|
||||
*config.attributes['username']
|
||||
].compact.uniq
|
||||
].compact.uniq.reject(&:blank?)
|
||||
end
|
||||
|
||||
def self.normalize_dn(dn)
|
||||
|
|
|
@ -46,10 +46,10 @@ module Gitlab
|
|||
ProjectTemplate.new('android', 'Android', _('A ready-to-go template for use with Android apps.'), 'https://gitlab.com/gitlab-org/project-templates/android', 'illustrations/logos/android.svg'),
|
||||
ProjectTemplate.new('gomicro', 'Go Micro', _('Go Micro is a framework for micro service development.'), 'https://gitlab.com/gitlab-org/project-templates/go-micro', 'illustrations/logos/gomicro.svg'),
|
||||
ProjectTemplate.new('gatsby', 'Pages/Gatsby', _('Everything you need to create a GitLab Pages site using Gatsby.'), 'https://gitlab.com/pages/gatsby'),
|
||||
ProjectTemplate.new('hugo', 'Pages/Hugo', _('Everything you need to create a GitLab Pages site using Hugo.'), 'https://gitlab.com/pages/hugo'),
|
||||
ProjectTemplate.new('hugo', 'Pages/Hugo', _('Everything you need to create a GitLab Pages site using Hugo.'), 'https://gitlab.com/pages/hugo', 'illustrations/logos/hugo.svg'),
|
||||
ProjectTemplate.new('jekyll', 'Pages/Jekyll', _('Everything you need to create a GitLab Pages site using Jekyll.'), 'https://gitlab.com/pages/jekyll', 'illustrations/logos/jekyll.svg'),
|
||||
ProjectTemplate.new('plainhtml', 'Pages/Plain HTML', _('Everything you need to create a GitLab Pages site using plain HTML.'), 'https://gitlab.com/pages/plain-html'),
|
||||
ProjectTemplate.new('gitbook', 'Pages/GitBook', _('Everything you need to create a GitLab Pages site using GitBook.'), 'https://gitlab.com/pages/gitbook'),
|
||||
ProjectTemplate.new('gitbook', 'Pages/GitBook', _('Everything you need to create a GitLab Pages site using GitBook.'), 'https://gitlab.com/pages/gitbook', 'illustrations/logos/gitbook.svg'),
|
||||
ProjectTemplate.new('hexo', 'Pages/Hexo', _('Everything you need to create a GitLab Pages site using Hexo.'), 'https://gitlab.com/pages/hexo', 'illustrations/logos/hexo.svg'),
|
||||
ProjectTemplate.new('sse_middleman', 'Static Site Editor/Middleman', _('Middleman project with Static Site Editor support'), 'https://gitlab.com/gitlab-org/project-templates/static-site-editor-middleman'),
|
||||
ProjectTemplate.new('nfhugo', 'Netlify/Hugo', _('A Hugo site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features.'), 'https://gitlab.com/pages/nfhugo', 'illustrations/logos/netlify.svg'),
|
||||
|
|
|
@ -17475,12 +17475,18 @@ msgstr ""
|
|||
msgid "PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments"
|
||||
msgstr ""
|
||||
|
||||
msgid "PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)"
|
||||
msgstr ""
|
||||
|
||||
msgid "PrometheusService|Common metrics"
|
||||
msgstr ""
|
||||
|
||||
msgid "PrometheusService|Common metrics are automatically monitored based on a library of metrics from popular exporters."
|
||||
msgstr ""
|
||||
|
||||
msgid "PrometheusService|Contents of the credentials.json file of your service account, like: { \"type\": \"service_account\", \"project_id\": ... }"
|
||||
msgstr ""
|
||||
|
||||
msgid "PrometheusService|Custom metrics"
|
||||
msgstr ""
|
||||
|
||||
|
@ -20161,6 +20167,14 @@ msgid_plural "Showing %d events"
|
|||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "Showing %{count} of %{total} projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "Showing %{count} project"
|
||||
msgid_plural "Showing %{count} projects"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "Showing %{limit} of %{total_count} issues. "
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@
|
|||
"lodash": "^4.17.15",
|
||||
"marked": "^0.3.12",
|
||||
"mermaid": "^8.5.1",
|
||||
"mersenne-twister": "1.1.0",
|
||||
"mitt": "^1.2.0",
|
||||
"monaco-editor": "^0.18.1",
|
||||
"monaco-editor-webpack-plugin": "^1.7.0",
|
||||
|
@ -120,6 +121,7 @@
|
|||
"sortablejs": "^1.10.2",
|
||||
"sql.js": "^0.4.0",
|
||||
"stickyfilljs": "^2.1.0",
|
||||
"string-hash": "1.1.3",
|
||||
"style-loader": "^1.1.3",
|
||||
"svg4everybody": "2.1.9",
|
||||
"swagger-ui-dist": "^3.24.3",
|
||||
|
@ -133,6 +135,7 @@
|
|||
"tributejs": "4.1.3",
|
||||
"unfetch": "^4.1.0",
|
||||
"url-loader": "^3.0.0",
|
||||
"uuid": "8.1.0",
|
||||
"visibilityjs": "^1.2.4",
|
||||
"vue": "^2.6.10",
|
||||
"vue-apollo": "^3.0.3",
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
import { uuids } from '~/diffs/utils/uuids';
|
||||
|
||||
const HEX = /[a-f0-9]/i;
|
||||
const HEX_RE = HEX.source;
|
||||
const UUIDV4 = new RegExp(
|
||||
`${HEX_RE}{8}-${HEX_RE}{4}-4${HEX_RE}{3}-[89ab]${HEX_RE}{3}-${HEX_RE}{12}`,
|
||||
'i',
|
||||
);
|
||||
|
||||
describe('UUIDs Util', () => {
|
||||
describe('uuids', () => {
|
||||
const SEQUENCE_FOR_GITLAB_SEED = [
|
||||
'a1826a44-316c-480e-a93d-8cdfeb36617c',
|
||||
'e049db1f-a4cf-4cba-aa60-6d95e3b547dc',
|
||||
'6e3c737c-13a7-4380-b17d-601f187d7e69',
|
||||
'bee5cc7f-c486-45c0-8ad3-d1ac5402632d',
|
||||
'af248c9f-a3a6-4d4f-a311-fe151ffab25a',
|
||||
];
|
||||
const SEQUENCE_FOR_12345_SEED = [
|
||||
'edfb51e2-e3e1-4de5-90fd-fd1d21760881',
|
||||
'2f154da4-0a2d-4da9-b45e-0ffed391517e',
|
||||
'91566d65-8836-4222-9875-9e1df4d0bb01',
|
||||
'f6ea6c76-7640-4d71-a736-9d3bec7a1a8e',
|
||||
'bfb85869-5fb9-4c5b-a750-5af727ac5576',
|
||||
];
|
||||
|
||||
it('returns version 4 UUIDs', () => {
|
||||
expect(uuids()[0]).toMatch(UUIDV4);
|
||||
});
|
||||
|
||||
it('outputs an array of UUIDs', () => {
|
||||
const ids = uuids({ count: 11 });
|
||||
|
||||
expect(ids.length).toEqual(11);
|
||||
expect(ids.every(id => UUIDV4.test(id))).toEqual(true);
|
||||
});
|
||||
|
||||
it.each`
|
||||
seeds | uuid
|
||||
${['some', 'special', 'seed']} | ${'6fa53e51-0f70-4072-9c84-1c1eee1b9934'}
|
||||
${['magic']} | ${'fafae8cd-7083-44f3-b82d-43b30bd27486'}
|
||||
${['seeded']} | ${'e06ed291-46c5-4e42-836b-e7c772d48b49'}
|
||||
${['GitLab']} | ${'a1826a44-316c-480e-a93d-8cdfeb36617c'}
|
||||
${['JavaScript']} | ${'12dfb297-1560-4c38-9775-7178ef8472fb'}
|
||||
${[99, 169834, 2619]} | ${'3ecc8ad6-5b7c-4c9b-94a8-c7271c2fa083'}
|
||||
${[12]} | ${'2777374b-723b-469b-bd73-e586df964cfd'}
|
||||
${[9876, 'mixed!', 7654]} | ${'865212e0-4a16-4934-96f9-103cf36a6931'}
|
||||
${[123, 1234, 12345, 6]} | ${'40aa2ee6-0a11-4e67-8f09-72f5eba04244'}
|
||||
${[0]} | ${'8c7f0aac-97c4-4a2f-b716-a675d821ccc0'}
|
||||
`(
|
||||
'should always output the UUID $uuid when the options.seeds argument is $seeds',
|
||||
({ uuid, seeds }) => {
|
||||
expect(uuids({ seeds })[0]).toEqual(uuid);
|
||||
},
|
||||
);
|
||||
|
||||
describe('unseeded UUID randomness', () => {
|
||||
const nonRandom = Array(6)
|
||||
.fill(0)
|
||||
.map((_, i) => uuids({ seeds: [i] })[0]);
|
||||
const random = uuids({ count: 6 });
|
||||
const moreRandom = uuids({ count: 6 });
|
||||
|
||||
it('is different from a seeded result', () => {
|
||||
random.forEach((id, i) => {
|
||||
expect(id).not.toEqual(nonRandom[i]);
|
||||
});
|
||||
});
|
||||
|
||||
it('is different from other random results', () => {
|
||||
random.forEach((id, i) => {
|
||||
expect(id).not.toEqual(moreRandom[i]);
|
||||
});
|
||||
});
|
||||
|
||||
it('never produces any duplicates', () => {
|
||||
expect(new Set(random).size).toEqual(random.length);
|
||||
});
|
||||
});
|
||||
|
||||
it.each`
|
||||
seed | sequence
|
||||
${'GitLab'} | ${SEQUENCE_FOR_GITLAB_SEED}
|
||||
${12345} | ${SEQUENCE_FOR_12345_SEED}
|
||||
`(
|
||||
'should output the same sequence of UUIDs for the given seed "$seed"',
|
||||
({ seed, sequence }) => {
|
||||
expect(uuids({ seeds: [seed], count: 5 })).toEqual(sequence);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
|
@ -16,6 +16,7 @@ import DashboardsDropdown from '~/monitoring/components/dashboards_dropdown.vue'
|
|||
import EmptyState from '~/monitoring/components/empty_state.vue';
|
||||
import GroupEmptyState from '~/monitoring/components/group_empty_state.vue';
|
||||
import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
|
||||
import LinksSection from '~/monitoring/components/links_section.vue';
|
||||
import { createStore } from '~/monitoring/stores';
|
||||
import * as types from '~/monitoring/stores/mutation_types';
|
||||
import {
|
||||
|
@ -24,6 +25,7 @@ import {
|
|||
setMetricResult,
|
||||
setupStoreWithData,
|
||||
setupStoreWithVariable,
|
||||
setupStoreWithLinks,
|
||||
} from '../store_utils';
|
||||
import { environmentData, dashboardGitResponse, propsData } from '../mock_data';
|
||||
import { metricsDashboardViewModel, metricsDashboardPanelCount } from '../fixture_data';
|
||||
|
@ -483,6 +485,21 @@ describe('Dashboard', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('links section', () => {
|
||||
beforeEach(() => {
|
||||
createShallowWrapper({ hasMetrics: true });
|
||||
setupStoreWithData(store);
|
||||
setupStoreWithLinks(store);
|
||||
|
||||
return wrapper.vm.$nextTick();
|
||||
});
|
||||
|
||||
it('shows the links section', () => {
|
||||
expect(wrapper.vm.shouldShowLinksSection).toBe(true);
|
||||
expect(wrapper.find(LinksSection)).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
describe('single panel expands to "full screen" mode', () => {
|
||||
const findExpandedPanel = () => wrapper.find({ ref: 'expandedPanel' });
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ describe('mapToDashboardViewModel', () => {
|
|||
expect(mapToDashboardViewModel({})).toEqual({
|
||||
dashboard: '',
|
||||
panelGroups: [],
|
||||
links: [],
|
||||
variables: {},
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -44,6 +46,8 @@ describe('mapToDashboardViewModel', () => {
|
|||
|
||||
expect(mapToDashboardViewModel(response)).toEqual({
|
||||
dashboard: 'Dashboard Name',
|
||||
links: [],
|
||||
variables: {},
|
||||
panelGroups: [
|
||||
{
|
||||
group: 'Group 1',
|
||||
|
@ -76,6 +80,8 @@ describe('mapToDashboardViewModel', () => {
|
|||
it('key', () => {
|
||||
const response = {
|
||||
dashboard: 'Dashboard Name',
|
||||
links: [],
|
||||
variables: {},
|
||||
panel_groups: [
|
||||
{
|
||||
group: 'Group A',
|
||||
|
|
|
@ -38,6 +38,18 @@ export const setupStoreWithVariable = store => {
|
|||
});
|
||||
};
|
||||
|
||||
export const setupStoreWithLinks = store => {
|
||||
store.commit(`monitoringDashboard/${types.RECEIVE_METRICS_DASHBOARD_SUCCESS}`, {
|
||||
...metricsDashboardPayload,
|
||||
links: [
|
||||
{
|
||||
title: 'GitLab Website',
|
||||
url: `https://gitlab.com/website`,
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
export const setupStoreWithData = store => {
|
||||
setupAllDashboards(store);
|
||||
setupStoreWithDashboard(store);
|
||||
|
|
|
@ -110,4 +110,26 @@ describe('ProjectSelector component', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the search results legend', () => {
|
||||
it.each`
|
||||
count | total | expected
|
||||
${0} | ${0} | ${'Showing 0 projects'}
|
||||
${1} | ${0} | ${'Showing 1 project'}
|
||||
${2} | ${0} | ${'Showing 2 projects'}
|
||||
${2} | ${3} | ${'Showing 2 of 3 projects'}
|
||||
`(
|
||||
'is "$expected" given $count results are showing out of $total',
|
||||
({ count, total, expected }) => {
|
||||
wrapper.setProps({
|
||||
projectSearchResults: searchResults.slice(0, count),
|
||||
totalResults: total,
|
||||
});
|
||||
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
expect(wrapper.text()).toContain(expected);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe './config/initializers/google_api_client.rb' do
|
||||
subject { Google::Apis::ContainerV1beta1 }
|
||||
|
||||
it 'is needed' do |example|
|
||||
is_expected.not_to be_const_defined(:CloudRunConfig),
|
||||
<<-MSG.strip_heredoc
|
||||
The google-api-client gem has been upgraded!
|
||||
Remove:
|
||||
#{example.example_group.description}
|
||||
#{example.file_path}
|
||||
MSG
|
||||
end
|
||||
end
|
|
@ -57,14 +57,17 @@ describe Gitlab::Auth::Ldap::Person do
|
|||
'attributes' => {
|
||||
'name' => 'cn',
|
||||
'email' => 'mail',
|
||||
'username' => %w(uid mail memberof)
|
||||
'username' => %w(uid mail),
|
||||
'first_name' => ''
|
||||
}
|
||||
}
|
||||
)
|
||||
config = Gitlab::Auth::Ldap::Config.new('ldapmain')
|
||||
ldap_attributes = described_class.ldap_attributes(config)
|
||||
|
||||
expect(ldap_attributes).to match_array(%w(dn uid cn mail memberof))
|
||||
expect(ldap_attributes).to include('dn', 'uid', 'cn', 'mail')
|
||||
expect(ldap_attributes).to be_present
|
||||
expect(ldap_attributes.uniq!).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -599,6 +599,7 @@ design: &design
|
|||
- versions
|
||||
- notes
|
||||
- user_mentions
|
||||
- events
|
||||
designs: *design
|
||||
actions:
|
||||
- design
|
||||
|
|
|
@ -252,6 +252,26 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'behind IAP' do
|
||||
let(:manual_configuration) { true }
|
||||
|
||||
before do
|
||||
# dummy private key generated only for this test to pass openssl validation
|
||||
service.google_iap_service_account_json = '{"type":"service_account","private_key":"-----BEGIN RSA PRIVATE KEY-----\nMIIBOAIBAAJAU85LgUY5o6j6j/07GMLCNUcWJOBA1buZnNgKELayA6mSsHrIv31J\nY8kS+9WzGPQninea7DcM4hHA7smMgQD1BwIDAQABAkAqKxMy6PL3tn7dFL43p0ex\nJyOtSmlVIiAZG1t1LXhE/uoLpYi5DnbYqGgu0oih+7nzLY/dXpNpXUmiRMOUEKmB\nAiEAoTi2rBXbrLSi2C+H7M/nTOjMQQDuZ8Wr4uWpKcjYJTMCIQCFEskL565oFl/7\nRRQVH+cARrAsAAoJSbrOBAvYZ0PI3QIgIEFwis10vgEF86rOzxppdIG/G+JL0IdD\n9IluZuXAGPECIGUo7qSaLr75o2VEEgwtAFH5aptIPFjrL5LFCKwtdB4RAiAYZgFV\nHCMmaooAw/eELuMoMWNYmujZ7VaAnOewGDW0uw==\n-----END RSA PRIVATE KEY-----\n"}'
|
||||
service.google_iap_audience_client_id = "IAP_CLIENT_ID.apps.googleusercontent.com"
|
||||
|
||||
stub_request(:post, "https://oauth2.googleapis.com/token").to_return(status: 200, body: '{"id_token": "FOO"}', headers: { 'Content-Type': 'application/json; charset=UTF-8' })
|
||||
|
||||
stub_feature_flags(prometheus_service_iap_auth: true)
|
||||
end
|
||||
|
||||
it 'includes the authorization header' do
|
||||
expect(service.prometheus_client).not_to be_nil
|
||||
expect(service.prometheus_client.send(:options)).to have_key(:headers)
|
||||
expect(service.prometheus_client.send(:options)[:headers]).to eq(authorization: "Bearer FOO")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#prometheus_available?' do
|
||||
|
@ -457,9 +477,33 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
|
|||
}
|
||||
]
|
||||
end
|
||||
let(:feature_flagged_fields) do
|
||||
[
|
||||
{
|
||||
type: 'text',
|
||||
name: 'google_iap_audience_client_id',
|
||||
title: 'Google IAP Audience Client ID',
|
||||
placeholder: s_('PrometheusService|Client ID of the IAP secured resource (looks like IAP_CLIENT_ID.apps.googleusercontent.com)'),
|
||||
required: false
|
||||
},
|
||||
{
|
||||
type: 'textarea',
|
||||
name: 'google_iap_service_account_json',
|
||||
title: 'Google IAP Service Account JSON',
|
||||
placeholder: s_('PrometheusService|Contents of the credentials.json file of your service account, like: { "type": "service_account", "project_id": ... }'),
|
||||
required: false
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
it 'returns fields' do
|
||||
stub_feature_flags(prometheus_service_iap_auth: false)
|
||||
expect(service.fields).to eq(expected_fields)
|
||||
end
|
||||
|
||||
it 'returns fields with feature flag on' do
|
||||
stub_feature_flags(prometheus_service_iap_auth: true)
|
||||
expect(service.fields).to eq(expected_fields + feature_flagged_fields)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,18 +24,25 @@ describe Projects::Prometheus::AlertPresenter do
|
|||
it { is_expected.to eq(project.full_path) }
|
||||
end
|
||||
|
||||
describe '#starts_at' do
|
||||
subject { presenter.starts_at }
|
||||
describe '#start_time' do
|
||||
subject { presenter.start_time }
|
||||
|
||||
let(:starts_at) { '2020-10-31T14:02:04Z' }
|
||||
|
||||
before do
|
||||
payload['startsAt'] = starts_at
|
||||
end
|
||||
|
||||
context 'with valid datetime' do
|
||||
let(:datetime) { Time.now }
|
||||
let(:starts_at) { datetime.rfc3339 }
|
||||
context 'with valid utc datetime' do
|
||||
it { is_expected.to eq('31 October 2020, 2:02PM (UTC)') }
|
||||
|
||||
it { is_expected.to eq(datetime.rfc3339) }
|
||||
context 'with admin time zone not UTC' do
|
||||
before do
|
||||
allow(Time).to receive(:zone).and_return(ActiveSupport::TimeZone.new('Perth'))
|
||||
end
|
||||
|
||||
it { is_expected.to eq('31 October 2020, 2:02PM (UTC)') }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid datetime' do
|
||||
|
@ -56,7 +63,7 @@ describe Projects::Prometheus::AlertPresenter do
|
|||
<<~MARKDOWN.chomp
|
||||
#### Summary
|
||||
|
||||
**Start time:** #{presenter.starts_at}
|
||||
**Start time:** #{presenter.start_time}
|
||||
|
||||
MARKDOWN
|
||||
)
|
||||
|
@ -73,7 +80,7 @@ describe Projects::Prometheus::AlertPresenter do
|
|||
<<~MARKDOWN.chomp
|
||||
#### Summary
|
||||
|
||||
**Start time:** #{presenter.starts_at}
|
||||
**Start time:** #{presenter.start_time}
|
||||
|
||||
#### Alert Details
|
||||
|
||||
|
@ -94,7 +101,7 @@ describe Projects::Prometheus::AlertPresenter do
|
|||
<<~MARKDOWN.chomp
|
||||
#### Summary
|
||||
|
||||
**Start time:** #{presenter.starts_at}#{markdown_line_break}
|
||||
**Start time:** #{presenter.start_time}#{markdown_line_break}
|
||||
**full_query:** `query`
|
||||
|
||||
MARKDOWN
|
||||
|
@ -122,7 +129,7 @@ describe Projects::Prometheus::AlertPresenter do
|
|||
<<~MARKDOWN.chomp
|
||||
#### Summary
|
||||
|
||||
**Start time:** #{presenter.starts_at}#{markdown_line_break}
|
||||
**Start time:** #{presenter.start_time}#{markdown_line_break}
|
||||
**Service:** service_name#{markdown_line_break}
|
||||
**Monitoring tool:** monitoring_tool_name#{markdown_line_break}
|
||||
**Hosts:** http://localhost:3000 http://localhost:3001
|
||||
|
@ -144,7 +151,7 @@ describe Projects::Prometheus::AlertPresenter do
|
|||
<<~MARKDOWN.chomp
|
||||
#### Summary
|
||||
|
||||
**Start time:** #{presenter.starts_at}#{markdown_line_break}
|
||||
**Start time:** #{presenter.start_time}#{markdown_line_break}
|
||||
**Hosts:** http://localhost:3000
|
||||
|
||||
MARKDOWN
|
||||
|
@ -161,7 +168,7 @@ describe Projects::Prometheus::AlertPresenter do
|
|||
<<~MARKDOWN.chomp
|
||||
#### Summary
|
||||
|
||||
**Start time:** #{presenter.starts_at}#{markdown_line_break}
|
||||
**Start time:** #{presenter.start_time}#{markdown_line_break}
|
||||
**full_query:** `avg(metric) > 1.0`
|
||||
|
||||
[](#{url})
|
||||
|
@ -253,7 +260,7 @@ describe Projects::Prometheus::AlertPresenter do
|
|||
<<~MARKDOWN.chomp
|
||||
#### Summary
|
||||
|
||||
**Start time:** #{presenter.starts_at}#{markdown_line_break}
|
||||
**Start time:** #{presenter.start_time}#{markdown_line_break}
|
||||
**full_query:** `avg(metric) > 1.0`
|
||||
|
||||
MARKDOWN
|
||||
|
@ -280,7 +287,7 @@ describe Projects::Prometheus::AlertPresenter do
|
|||
<<~MARKDOWN.chomp
|
||||
#### Summary
|
||||
|
||||
**Start time:** #{presenter.starts_at}
|
||||
**Start time:** #{presenter.start_time}
|
||||
|
||||
MARKDOWN
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue