Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
c7531da771
commit
44fb0702f3
|
@ -0,0 +1 @@
|
|||
main
|
|
@ -102,10 +102,10 @@ export default {
|
|||
return { fullPath: this.groupPath, first: GRAPHQL_PAGE_SIZE };
|
||||
},
|
||||
pageInfo() {
|
||||
return this.group.dependencyProxyManifests.pageInfo;
|
||||
return this.group.dependencyProxyManifests?.pageInfo;
|
||||
},
|
||||
manifests() {
|
||||
return this.group.dependencyProxyManifests.nodes;
|
||||
return this.group.dependencyProxyManifests?.nodes;
|
||||
},
|
||||
modalTitleWithCount() {
|
||||
return sprintf(
|
||||
|
@ -132,7 +132,7 @@ export default {
|
|||
);
|
||||
},
|
||||
showDeleteDropdown() {
|
||||
return this.group.dependencyProxyBlobCount > 0;
|
||||
return this.group.dependencyProxyManifests?.nodes.length > 0;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script>
|
||||
import { GlSprintf } from '@gitlab/ui';
|
||||
import { GlIcon, GlSprintf } from '@gitlab/ui';
|
||||
import { MANIFEST_PENDING_DESTRUCTION_STATUS } from '~/packages_and_registries/dependency_proxy/constants';
|
||||
import ListItem from '~/vue_shared/components/registry/list_item.vue';
|
||||
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import { s__ } from '~/locale';
|
||||
|
@ -7,6 +8,7 @@ import { s__ } from '~/locale';
|
|||
export default {
|
||||
name: 'ManifestRow',
|
||||
components: {
|
||||
GlIcon,
|
||||
GlSprintf,
|
||||
ListItem,
|
||||
TimeagoTooltip,
|
||||
|
@ -24,17 +26,31 @@ export default {
|
|||
version() {
|
||||
return this.manifest?.imageName.split(':')[1];
|
||||
},
|
||||
isErrorStatus() {
|
||||
return this.manifest?.status === MANIFEST_PENDING_DESTRUCTION_STATUS;
|
||||
},
|
||||
disabledRowStyle() {
|
||||
return this.isErrorStatus ? 'gl-font-weight-normal gl-text-gray-500' : '';
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
cachedAgoMessage: s__('DependencyProxy|Cached %{time}'),
|
||||
scheduledForDeletion: s__('DependencyProxy|Scheduled for deletion'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<list-item>
|
||||
<template #left-primary> {{ name }} </template>
|
||||
<template #left-secondary> {{ version }} </template>
|
||||
<list-item :disabled="isErrorStatus">
|
||||
<template #left-primary>
|
||||
<span :class="disabledRowStyle">{{ name }}</span>
|
||||
</template>
|
||||
<template #left-secondary>
|
||||
{{ version }}
|
||||
<span v-if="isErrorStatus" class="gl-ml-4" data-testid="status"
|
||||
><gl-icon name="clock" /> {{ $options.i18n.scheduledForDeletion }}</span
|
||||
>
|
||||
</template>
|
||||
<template #right-primary> </template>
|
||||
<template #right-secondary>
|
||||
<timeago-tooltip :time="manifest.createdAt" data-testid="cached-message">
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
export const GRAPHQL_PAGE_SIZE = 20;
|
||||
export const MANIFEST_PENDING_DESTRUCTION_STATUS = 'PENDING_DESTRUCTION';
|
||||
|
|
|
@ -20,6 +20,7 @@ query getDependencyProxyDetails(
|
|||
id
|
||||
createdAt
|
||||
imageName
|
||||
status
|
||||
}
|
||||
pageInfo {
|
||||
...PageInfo
|
||||
|
|
|
@ -32,7 +32,6 @@ export default {
|
|||
return {
|
||||
'gl-border-t-transparent': !this.first && !this.selected,
|
||||
'gl-border-t-gray-100': this.first && !this.selected,
|
||||
'gl-opacity-5': this.disabled,
|
||||
'gl-border-b-gray-100': !this.selected,
|
||||
'gl-bg-blue-50 gl-border-blue-200': this.selected,
|
||||
};
|
||||
|
|
|
@ -47,7 +47,7 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController
|
|||
end
|
||||
|
||||
def verify_asymmetric_atlassian_jwt!
|
||||
asymmetric_jwt = Atlassian::JiraConnect::AsymmetricJwt.new(auth_token, jwt_verification_claims)
|
||||
asymmetric_jwt = Atlassian::JiraConnect::Jwt::Asymmetric.new(auth_token, jwt_verification_claims)
|
||||
|
||||
return head :unauthorized unless asymmetric_jwt.valid?
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
= _('Set the default branch for this project. All merge requests and commits are made against this branch unless you specify a different one.')
|
||||
|
||||
.settings-content
|
||||
= form_for @project, remote: true, html: { multipart: true, anchor: 'default-branch-settings' }, authenticity_token: true do |f|
|
||||
= gitlab_ui_form_for @project, remote: true, html: { multipart: true, anchor: 'default-branch-settings' }, authenticity_token: true do |f|
|
||||
%fieldset
|
||||
- if @project.empty_repo?
|
||||
.text-secondary
|
||||
|
@ -20,12 +20,10 @@
|
|||
= f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide', data: { qa_selector: 'default_branch_dropdown' }})
|
||||
|
||||
.form-group
|
||||
.form-check
|
||||
= f.check_box :autoclose_referenced_issues, class: 'form-check-input'
|
||||
= f.label :autoclose_referenced_issues, class: 'form-check-label' do
|
||||
%strong= _("Auto-close referenced issues on default branch")
|
||||
.form-text.text-muted
|
||||
= _("When merge requests and commits in the default branch close, any issues they reference also close.")
|
||||
= link_to sprite_icon('question-o'), help_page_path('user/project/issues/managing_issues.md', anchor: 'closing-issues-automatically'), target: '_blank', rel: 'noopener noreferrer'
|
||||
- help_text = _("When merge requests and commits in the default branch close, any issues they reference also close.")
|
||||
- help_icon = link_to sprite_icon('question-o'), help_page_path('user/project/issues/managing_issues.md', anchor: 'closing-issues-automatically'), target: '_blank', rel: 'noopener noreferrer'
|
||||
= f.gitlab_ui_checkbox_component :autoclose_referenced_issues,
|
||||
_("Auto-close referenced issues on default branch"),
|
||||
help_text: (help_text + " " + help_icon).html_safe
|
||||
|
||||
= f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
|
||||
|
|
|
@ -41,6 +41,6 @@
|
|||
gitlab-com: true
|
||||
packages: [Free, Premium, Ultimate]
|
||||
url: 'https://docs.gitlab.com/ee/ci/runners/runners_scope.html#group-runners'
|
||||
image_url: 'https://about.gitlab.com/images/14_10/group-runners-view-new-3.pn'
|
||||
image_url: 'https://about.gitlab.com/images/14_10/group-runners-view-new-3.png'
|
||||
published_at: 2022-04-22
|
||||
release: 14.10
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- incident_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32609
|
||||
milestone: '13.1'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- incident_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33217
|
||||
milestone: '13.1'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- incident_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29864
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- value_stream_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36658
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- authentication_and_authorization
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39652
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -7,5 +7,5 @@ feature_categories:
|
|||
description: >-
|
||||
The background_migration_jobs table stores information about the jobs processed during the execution of a background migration.
|
||||
See https://docs.gitlab.com/ee/development/database/background_migrations.html for more details.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35913
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- team_planning
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33892
|
||||
milestone: '13.1'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- team_planning
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40360
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- continuous_integration
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41585
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- code_testing
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32991
|
||||
milestone: '13.1'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- code_testing
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30387
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- continuous_integration
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29162
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- pipeline_authoring
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30156
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- build_artifacts
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37969
|
||||
milestone: '13.3'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- continuous_integration
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33762
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- continuous_integration
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40036
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- kubernetes_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33228
|
||||
milestone: '13.3'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- kubernetes_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33228
|
||||
milestone: '13.3'
|
||||
|
|
|
@ -3,7 +3,7 @@ table_name: clusters_applications_cilium
|
|||
classes:
|
||||
- Clusters::Applications::Cilium
|
||||
feature_categories:
|
||||
- kubernetes_management
|
||||
- container_network_security
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34601
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- team_planning
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24229
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- dynamic_application_security_testing
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37404
|
||||
milestone: '13.3'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- dynamic_application_security_testing
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36659
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- dynamic_application_security_testing
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41639
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- dynamic_application_security_testing
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41639
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- dynamic_application_security_testing
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36659
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- source_code_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28113
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- global_search
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34069
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- experimentation_conversion
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38397
|
||||
milestone: '13.3'
|
||||
|
|
|
@ -3,7 +3,7 @@ table_name: experiments
|
|||
classes:
|
||||
- Experiment
|
||||
feature_categories:
|
||||
- experimentation_expansion
|
||||
- experimentation_conversion
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38397
|
||||
milestone: '13.3'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- secrets_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30886
|
||||
milestone: '13.1'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- advanced_deployments
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32901
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- wiki
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31121
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- team_planning
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40272
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- code_review
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34248
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- code_review
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40358
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- metrics
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27583
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- metrics
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29912
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- subgroups
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34746
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- subgroups
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36321
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- feature_flags
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/32876
|
||||
milestone: '13.1'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- feature_flags
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30243
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- feature_flags
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28822
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- package_registry
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30448
|
||||
milestone: '13.1'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- package_registry
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30618
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- package_registry
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30994
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- package_registry
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27632
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- pages
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41785
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -4,5 +4,5 @@ classes: []
|
|||
feature_categories:
|
||||
- authentication_and_authorization
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33272
|
||||
milestone: '13.1'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- compliance_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28182
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- source_code_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29095
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- metrics
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38457
|
||||
milestone: '13.3'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- planning_analytics
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37617
|
||||
milestone: '13.3'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- team_planning
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28926
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- vulnerability_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40368
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- snippets
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35026
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- team_planning
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30125
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- incident_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29994
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- infrastructure_as_code
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35211
|
||||
milestone: '13.4'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- infrastructure_as_code
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26619
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- vulnerability_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36955
|
||||
milestone: '13.3'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- vulnerability_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34289
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- vulnerability_management
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27515
|
||||
milestone: '13.0'
|
||||
|
|
|
@ -5,5 +5,5 @@ classes:
|
|||
feature_categories:
|
||||
- authentication_and_authorization
|
||||
description: TODO
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/9af97ee69a36de1dc4e73f4030d6316d3f0a82c5
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35797
|
||||
milestone: '13.2'
|
||||
|
|
|
@ -2537,7 +2537,7 @@ POST /projects/:id/housekeeping
|
|||
|
||||
### Get project push rules
|
||||
|
||||
Get the [push rules](../user/project/repository/push_rules.md#enabling-push-rules) of a
|
||||
Get the [push rules](../user/project/repository/push_rules.md) of a
|
||||
project.
|
||||
|
||||
```plaintext
|
||||
|
|
|
@ -11,7 +11,7 @@ GPG ([GNU Privacy Guard](https://gnupg.org/)) key. When you add a cryptographic
|
|||
signature to your commit, you provide extra assurance that a commit
|
||||
originated from you, rather than an impersonator. If GitLab can verify a commit
|
||||
author's identity with a public GPG key, the commit is marked **Verified** in the
|
||||
GitLab UI. You can then configure [push rules](../push_rules.md#enabling-push-rules)
|
||||
GitLab UI. You can then configure [push rules](../push_rules.md)
|
||||
for your project to reject individual commits not signed with GPG, or reject all
|
||||
commits from unverified users.
|
||||
|
||||
|
|
|
@ -28,7 +28,9 @@ The following options are available:
|
|||
by the same user as the user who pushed it, or where the committer's email address
|
||||
is not [confirmed](../../../security/user_email_confirmation.md).
|
||||
- **Reject unsigned commits** - Reject commit when it is not signed through GPG.
|
||||
Read [signing commits with GPG](gpg_signed_commits/index.md).
|
||||
Read [signing commits with GPG](gpg_signed_commits/index.md). This push rule
|
||||
can block some legitimate commits [created in the Web IDE](#reject-unsigned-commits-push-rule-disables-web-ide),
|
||||
and allow [unsigned commits created in the GitLab UI](#unsigned-commits-created-in-the-gitlab-ui).
|
||||
- **Removal of tags with** `git push` - Forbid users to remove Git tags with `git push`.
|
||||
Tags can be deleted through the web UI.
|
||||
- **Check whether the commit author is a GitLab user** - Restrict commits to existing
|
||||
|
@ -45,7 +47,8 @@ These push rules require you to create a regular expression for the rule to eval
|
|||
this regular expression can be pushed. To allow any commit message, leave empty.
|
||||
Uses multiline mode, which can be disabled using `(?-m)`.
|
||||
- **Restrict by branch name** - Only branch names that match this regular expression
|
||||
can be pushed. To allow any branch name, leave empty.
|
||||
can be pushed. To allow any branch name, leave empty. For more information, read
|
||||
[Restrict branch names](#restrict-branch-names).
|
||||
- **Restrict by commit author's email** - Only the commit author's email address that matches this
|
||||
regular expression can be pushed. Checks both the commit author and committer.
|
||||
To allow any email address, leave empty.
|
||||
|
@ -64,7 +67,7 @@ in push rules, and you can test them at the [regex101 regex tester](https://rege
|
|||
It's possible to create custom push rules rather than the push rules available in
|
||||
**Admin Area > Push Rules** by using more advanced server hooks.
|
||||
|
||||
See [server hooks](../../../administration/server_hooks.md) for more information.
|
||||
Refer to [server hooks](../../../administration/server_hooks.md) for more information.
|
||||
|
||||
## Use cases
|
||||
|
||||
|
@ -86,7 +89,11 @@ is accepted.
|
|||
|
||||
### Restrict branch names
|
||||
|
||||
If your company has a strict policy for branch names, you may want the branches to start
|
||||
> Default restricted branch names were introduced in GitLab 12.10.
|
||||
|
||||
By default, GitLab restricts certain formats of branch names for security purposes.
|
||||
40-character hexadecimal names, similar to Git commit hashes, are prohibited.
|
||||
If your company has a stricter policy for branch names, you may want the branches to start
|
||||
with a certain name. This approach enables different
|
||||
GitLab CI/CD jobs (such as `feature`, `hotfix`, `docker`, `android`) that rely on the
|
||||
branch name.
|
||||
|
@ -96,11 +103,11 @@ various branches, and CI pipelines might not work as expected. By restricting th
|
|||
branch names globally in Push Rules, such mistakes are prevented.
|
||||
All branch names that don't match your push rule are rejected.
|
||||
|
||||
Note that the name of your default branch is always allowed, regardless of the branch naming
|
||||
NOTE:
|
||||
The name of your default branch is always allowed, regardless of the branch naming
|
||||
regular expression (regex) specified. GitLab is configured this way
|
||||
because merges typically have the default branch as their target.
|
||||
If you have other target branches, include them in your regex. (See [Enabling push rules](#enabling-push-rules)).
|
||||
|
||||
If you have other target branches, include them in your regex. (See [Enabling push rules](#enable-global-push-rules)).
|
||||
The default branch also defaults to being a [protected branch](../protected_branches.md),
|
||||
which already limits users from pushing directly.
|
||||
|
||||
|
@ -111,14 +118,7 @@ Some example regular expressions you can use in push rules:
|
|||
- `^[a-z0-9\\-]{4,15}$` Branches must be between `4` and `15` characters long,
|
||||
accepting only lowercase letters, numbers and dashes.
|
||||
|
||||
#### Default restricted branch names
|
||||
|
||||
> Introduced in GitLab 12.10.
|
||||
|
||||
By default, GitLab restricts certain formats of branch names for security purposes.
|
||||
40-character hexadecimal names, similar to Git commit hashes, are prohibited.
|
||||
|
||||
## Enabling push rules
|
||||
## Enable global push rules
|
||||
|
||||
You can create push rules for all new projects to inherit, but they can be overridden
|
||||
at the project level or the [group level](../../group/index.md#group-push-rules).
|
||||
|
@ -127,8 +127,14 @@ To create global push rules:
|
|||
|
||||
1. On the top bar, select **Menu > Admin**.
|
||||
1. On the left sidebar, select **Push Rules**.
|
||||
1. Expand **Push rules**.
|
||||
1. Set the rule you want.
|
||||
1. Select **Save push rules**.
|
||||
|
||||
To override global push rules in a project's settings:
|
||||
## Override global push rules per project
|
||||
|
||||
The push rule of an individual project overrides the global push rule.
|
||||
To override global push rules for a specific project:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. On the left sidebar, select **Settings > Repository**.
|
||||
|
@ -136,28 +142,6 @@ To override global push rules in a project's settings:
|
|||
1. Set the rule you want.
|
||||
1. Select **Save push rules**.
|
||||
|
||||
### Caveat to "Reject unsigned commits" push rule
|
||||
|
||||
This push rule ignores commits that are authenticated and created by GitLab
|
||||
(either through the UI or API). When the **Reject unsigned commits** push rule is
|
||||
enabled, unsigned commits may still show up in the commit history if a commit was
|
||||
created **in** GitLab itself. As expected, commits created outside GitLab and
|
||||
pushed to the repository are rejected. For more information about how GitLab
|
||||
plans to fix this issue, read [issue #19185](https://gitlab.com/gitlab-org/gitlab/-/issues/19185).
|
||||
|
||||
#### "Reject unsigned commits" push rule disables Web IDE
|
||||
|
||||
In 13.10, if a project has the "Reject unsigned commits" push rule, the user is not allowed to
|
||||
commit through GitLab Web IDE.
|
||||
|
||||
To allow committing through the Web IDE on a project with this push rule, a GitLab administrator
|
||||
must disable the feature flag `reject_unsigned_commits_by_gitlab`. This can be done through a
|
||||
[rails console](../../../administration/operations/rails_console.md) and running:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:reject_unsigned_commits_by_gitlab)
|
||||
```
|
||||
|
||||
## Prevent pushing secrets to the repository
|
||||
|
||||
> Moved to GitLab Premium in 13.9.
|
||||
|
@ -231,28 +215,6 @@ Files blocked by this rule are listed below. For a complete list of criteria, se
|
|||
- `*.history`
|
||||
- `*_history`
|
||||
|
||||
### Prevent pushing secrets to all projects
|
||||
|
||||
To set a global push rule to prevent pushing secrets to all projects:
|
||||
|
||||
1. On the top bar, select **Menu > Admin**.
|
||||
1. On the left sidebar, select **Push Rules**.
|
||||
1. Expand **Push rules**.
|
||||
1. Select **Prevent pushing secret files**.
|
||||
1. Select **Save push rules**.
|
||||
|
||||
### Prevent pushing secrets to a project
|
||||
|
||||
The push rule of a project overrides the global push rule.
|
||||
|
||||
To prevent pushing secrets to a project:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. On the left sidebar, select **Settings > Repository**.
|
||||
1. Expand **Push rules**.
|
||||
1. Select **Prevent pushing secret files**.
|
||||
1. Select **Save push rules**.
|
||||
|
||||
## Prohibited file names
|
||||
|
||||
> Moved to GitLab Premium in 13.9.
|
||||
|
@ -295,14 +257,26 @@ end of the grouped collection of match conditions where it is appended to all ma
|
|||
(\.exe|^config\.yml|^directory-name\/config\.yml|(^|\/)install\.exe)$
|
||||
```
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
## Troubleshooting
|
||||
|
||||
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
||||
one might have when setting this up, or when something is changed, or on upgrading, it's
|
||||
important to describe those, too. Think of things that may go wrong and include them here.
|
||||
This is important to minimize requests for support, and to avoid doc comments with
|
||||
questions that you know someone might ask.
|
||||
### Reject unsigned commits push rule disables Web IDE
|
||||
|
||||
Each scenario can be a third-level heading, e.g. `### Getting error message X`.
|
||||
If you have none to add when creating a doc, leave this section in place
|
||||
but commented out to help encourage others to add to it in the future. -->
|
||||
In 13.10, if a project has the **Reject unsigned commits** push rule, the user is not allowed to
|
||||
commit through GitLab Web IDE.
|
||||
|
||||
To allow committing through the Web IDE on a project with this push rule, a GitLab administrator
|
||||
must disable the feature flag `reject_unsigned_commits_by_gitlab`. This can be done through a
|
||||
[rails console](../../../administration/operations/rails_console.md) and running:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:reject_unsigned_commits_by_gitlab)
|
||||
```
|
||||
|
||||
### Unsigned commits created in the GitLab UI
|
||||
|
||||
This push rule ignores commits that are authenticated and created by GitLab
|
||||
(either through the UI or API). When the **Reject unsigned commits** push rule is
|
||||
enabled, unsigned commits may still show up in the commit history if a commit was
|
||||
created **in** GitLab itself. As expected, commits created outside GitLab and
|
||||
pushed to the repository are rejected. For more information about this issue,
|
||||
read [issue #19185](https://gitlab.com/gitlab-org/gitlab/-/issues/19185).
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Atlassian
|
||||
module JiraConnect
|
||||
# See documentation about Atlassian asymmetric JWT verification:
|
||||
# https://developer.atlassian.com/cloud/jira/platform/understanding-jwt-for-connect-apps/#verifying-a-asymmetric-jwt-token-for-install-callbacks
|
||||
|
||||
class AsymmetricJwt
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
KeyFetchError = Class.new(StandardError)
|
||||
|
||||
ALGORITHM = 'RS256'
|
||||
PUBLIC_KEY_CDN_URL = 'https://connect-install-keys.atlassian.com/'
|
||||
UUID4_REGEX = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/.freeze
|
||||
|
||||
def initialize(token, verification_claims)
|
||||
@token = token
|
||||
@verification_claims = verification_claims
|
||||
end
|
||||
|
||||
def valid?
|
||||
claims.present? && claims['qsh'] == verification_qsh
|
||||
end
|
||||
|
||||
def iss_claim
|
||||
return unless claims
|
||||
|
||||
claims['iss']
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def claims
|
||||
strong_memoize(:claims) do
|
||||
_, jwt_headers = decode_token
|
||||
public_key = retrieve_public_key(jwt_headers['kid'])
|
||||
decoded_claims, _ = decode_token(public_key, true, **relevant_claims, verify_aud: true, verify_iss: true, algorithm: ALGORITHM)
|
||||
|
||||
decoded_claims
|
||||
rescue JWT::DecodeError, OpenSSL::PKey::PKeyError, KeyFetchError
|
||||
end
|
||||
end
|
||||
|
||||
def decode_token(key = nil, verify = false, **claims)
|
||||
Atlassian::Jwt.decode(@token, key, verify, **claims)
|
||||
end
|
||||
|
||||
def retrieve_public_key(key_id)
|
||||
raise KeyFetchError unless UUID4_REGEX.match?(key_id)
|
||||
|
||||
public_key = Gitlab::HTTP.try_get(PUBLIC_KEY_CDN_URL + key_id).try(:body)
|
||||
|
||||
raise KeyFetchError if public_key.blank?
|
||||
|
||||
OpenSSL::PKey.read(public_key)
|
||||
end
|
||||
|
||||
def relevant_claims
|
||||
@verification_claims.slice(:aud, :iss)
|
||||
end
|
||||
|
||||
def verification_qsh
|
||||
@verification_claims[:qsh]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,80 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Atlassian
|
||||
module JiraConnect
|
||||
module Jwt
|
||||
# See documentation about Atlassian asymmetric JWT verification:
|
||||
# https://developer.atlassian.com/cloud/jira/platform/understanding-jwt-for-connect-apps/#verifying-a-asymmetric-jwt-token-for-install-callbacks
|
||||
|
||||
class Asymmetric
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
KeyFetchError = Class.new(StandardError)
|
||||
|
||||
ALGORITHM = 'RS256'
|
||||
PUBLIC_KEY_CDN_URL = 'https://connect-install-keys.atlassian.com/'
|
||||
UUID4_REGEX = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/.freeze
|
||||
|
||||
def initialize(token, verification_claims)
|
||||
@token = token
|
||||
@verification_claims = verification_claims
|
||||
end
|
||||
|
||||
def valid?
|
||||
claims.present? && claims['qsh'] == verification_qsh
|
||||
end
|
||||
|
||||
def iss_claim
|
||||
return unless claims
|
||||
|
||||
claims['iss']
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def claims
|
||||
strong_memoize(:claims) do
|
||||
_, jwt_headers = decode_token
|
||||
public_key = retrieve_public_key(jwt_headers['kid'])
|
||||
|
||||
decoded_claims(public_key)
|
||||
rescue JWT::DecodeError, OpenSSL::PKey::PKeyError, KeyFetchError
|
||||
end
|
||||
end
|
||||
|
||||
def decoded_claims(public_key)
|
||||
decode_token(
|
||||
public_key,
|
||||
true,
|
||||
**relevant_claims,
|
||||
verify_aud: true,
|
||||
verify_iss: true,
|
||||
algorithm: ALGORITHM
|
||||
).first
|
||||
end
|
||||
|
||||
def decode_token(key = nil, verify = false, **claims)
|
||||
Atlassian::Jwt.decode(@token, key, verify, **claims)
|
||||
end
|
||||
|
||||
def retrieve_public_key(key_id)
|
||||
raise KeyFetchError unless UUID4_REGEX.match?(key_id)
|
||||
|
||||
public_key = Gitlab::HTTP.try_get(PUBLIC_KEY_CDN_URL + key_id).try(:body)
|
||||
|
||||
raise KeyFetchError if public_key.blank?
|
||||
|
||||
OpenSSL::PKey.read(public_key)
|
||||
end
|
||||
|
||||
def relevant_claims
|
||||
@verification_claims.slice(:aud, :iss)
|
||||
end
|
||||
|
||||
def verification_qsh
|
||||
@verification_claims[:qsh]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
require_relative Rails.root.join('metrics_server', 'dependencies')
|
||||
require_relative Rails.root.join('metrics_server', 'metrics_server')
|
||||
|
||||
namespace :gitlab do
|
||||
namespace :metrics_exporter do
|
||||
REPO = 'https://gitlab.com/gitlab-org/gitlab-metrics-exporter.git'
|
||||
|
||||
desc "GitLab | Metrics Exporter | Install or upgrade gitlab-metrics-exporter"
|
||||
task :install, [:dir] => :gitlab_environment do |t, args|
|
||||
unless args.dir.present?
|
||||
abort %(Please specify the directory where you want to install the exporter
|
||||
Usage: rake "gitlab:metrics_exporter:install[/installation/dir]")
|
||||
end
|
||||
|
||||
version = ENV['GITLAB_METRICS_EXPORTER_VERSION'] || MetricsServer.version
|
||||
make = Gitlab::Utils.which('gmake') || Gitlab::Utils.which('make')
|
||||
|
||||
abort "Couldn't find a 'make' binary" unless make
|
||||
|
||||
checkout_or_clone_version(version: version, repo: REPO, target_dir: args.dir, clone_opts: %w[--depth 1])
|
||||
|
||||
Dir.chdir(args.dir) { run_command!([make]) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12270,6 +12270,9 @@ msgstr ""
|
|||
msgid "DependencyProxy|Image list"
|
||||
msgstr ""
|
||||
|
||||
msgid "DependencyProxy|Scheduled for deletion"
|
||||
msgstr ""
|
||||
|
||||
msgid "DependencyProxy|Storage settings"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -7,6 +7,10 @@ class MetricsServer # rubocop:disable Gitlab/NamespacedClass
|
|||
PumaProcessSupervisor = Class.new(Gitlab::ProcessSupervisor)
|
||||
|
||||
class << self
|
||||
def version
|
||||
Rails.root.join('GITLAB_METRICS_EXPORTER_VERSION').read.chomp
|
||||
end
|
||||
|
||||
def start_for_puma
|
||||
metrics_dir = ::Prometheus::Client.configuration.multiprocess_files_dir
|
||||
|
||||
|
@ -25,15 +29,41 @@ class MetricsServer # rubocop:disable Gitlab/NamespacedClass
|
|||
end
|
||||
end
|
||||
|
||||
def spawn(target, metrics_dir:, gitlab_config: nil, wipe_metrics_dir: false)
|
||||
def start_for_sidekiq(**options)
|
||||
if new_metrics_server?
|
||||
self.spawn('sidekiq', **options)
|
||||
else
|
||||
self.fork('sidekiq', **options)
|
||||
end
|
||||
end
|
||||
|
||||
def spawn(target, metrics_dir:, **options)
|
||||
return spawn_ruby_server(target, metrics_dir: metrics_dir, **options) unless new_metrics_server?
|
||||
|
||||
settings = settings_for(target)
|
||||
path = options[:path]&.then { |p| Pathname.new(p) } || Pathname.new('')
|
||||
cmd = path.join('gitlab-metrics-exporter').to_path
|
||||
env = {
|
||||
'GME_MMAP_METRICS_DIR' => metrics_dir.to_s,
|
||||
'GME_PROBES' => 'self,mmap',
|
||||
'GME_SERVER_HOST' => settings['address'],
|
||||
'GME_SERVER_PORT' => settings['port'].to_s
|
||||
}
|
||||
|
||||
Process.spawn(env, cmd, err: $stderr, out: $stdout, pgroup: true).tap do |pid|
|
||||
Process.detach(pid)
|
||||
end
|
||||
end
|
||||
|
||||
def spawn_ruby_server(target, metrics_dir:, wipe_metrics_dir: false, **options)
|
||||
ensure_valid_target!(target)
|
||||
|
||||
cmd = "#{Rails.root}/bin/metrics-server"
|
||||
env = {
|
||||
'METRICS_SERVER_TARGET' => target,
|
||||
'WIPE_METRICS_DIR' => wipe_metrics_dir ? '1' : '0'
|
||||
'WIPE_METRICS_DIR' => wipe_metrics_dir ? '1' : '0',
|
||||
'GITLAB_CONFIG' => ENV['GITLAB_CONFIG']
|
||||
}
|
||||
env['GITLAB_CONFIG'] = gitlab_config if gitlab_config
|
||||
|
||||
Process.spawn(env, cmd, err: $stderr, out: $stdout, pgroup: true).tap do |pid|
|
||||
Process.detach(pid)
|
||||
|
@ -66,9 +96,23 @@ class MetricsServer # rubocop:disable Gitlab/NamespacedClass
|
|||
|
||||
private
|
||||
|
||||
def new_metrics_server?
|
||||
Gitlab::Utils.to_boolean(ENV['GITLAB_GOLANG_METRICS_SERVER'])
|
||||
end
|
||||
|
||||
def ensure_valid_target!(target)
|
||||
raise "Target must be one of [puma,sidekiq]" unless %w(puma sidekiq).include?(target)
|
||||
end
|
||||
|
||||
def settings_for(target)
|
||||
settings_key =
|
||||
case target
|
||||
when 'puma' then 'web_exporter'
|
||||
when 'sidekiq' then 'sidekiq_exporter'
|
||||
else ensure_valid_target!(target)
|
||||
end
|
||||
::Settings.monitoring[settings_key]
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(target, metrics_dir, wipe_metrics_dir)
|
||||
|
|
|
@ -164,8 +164,7 @@ module Gitlab
|
|||
|
||||
def restart_metrics_server
|
||||
@logger.info("Starting metrics server on port #{sidekiq_exporter_port}")
|
||||
MetricsServer.fork(
|
||||
'sidekiq',
|
||||
MetricsServer.start_for_sidekiq(
|
||||
metrics_dir: @metrics_dir,
|
||||
reset_signals: TERMINATE_SIGNALS + FORWARD_SIGNALS
|
||||
)
|
||||
|
|
|
@ -1,44 +1,83 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require 'rake_helper'
|
||||
|
||||
require_relative '../../../metrics_server/metrics_server'
|
||||
|
||||
# End-to-end tests for the metrics server process we use to serve metrics
|
||||
# from forking applications (Sidekiq, Puma) to the Prometheus scraper.
|
||||
RSpec.describe 'bin/metrics-server', :aggregate_failures do
|
||||
RSpec.describe 'GitLab metrics server', :aggregate_failures do
|
||||
let(:config_file) { Tempfile.new('gitlab.yml') }
|
||||
let(:address) { '127.0.0.1' }
|
||||
let(:port) { 3807 }
|
||||
let(:config) do
|
||||
{
|
||||
'test' => {
|
||||
'monitoring' => {
|
||||
'web_exporter' => {
|
||||
'address' => 'localhost',
|
||||
'address' => address,
|
||||
'enabled' => true,
|
||||
'port' => 3807
|
||||
'port' => port
|
||||
},
|
||||
'sidekiq_exporter' => {
|
||||
'address' => 'localhost',
|
||||
'address' => address,
|
||||
'enabled' => true,
|
||||
'port' => 3807
|
||||
'port' => port
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
%w(puma sidekiq).each do |target|
|
||||
context "with a running server targeting #{target}" do
|
||||
before(:all) do
|
||||
Rake.application.rake_require 'tasks/gitlab/metrics_exporter'
|
||||
|
||||
@exporter_path = Rails.root.join('tmp', 'test', 'gme')
|
||||
|
||||
run_rake_task('gitlab:metrics_exporter:install', @exporter_path)
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
FileUtils.rm_rf(@exporter_path)
|
||||
end
|
||||
|
||||
shared_examples 'serves metrics endpoint' do
|
||||
it 'serves /metrics endpoint' do
|
||||
start_server!
|
||||
|
||||
expect do
|
||||
Timeout.timeout(10) do
|
||||
http_ok = false
|
||||
until http_ok
|
||||
sleep 1
|
||||
response = Gitlab::HTTP.try_get("http://#{address}:#{port}/metrics", allow_local_requests: true)
|
||||
http_ok = response&.success?
|
||||
end
|
||||
end
|
||||
end.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'spawns a server' do |target, use_golang_server|
|
||||
context "targeting #{target} when using Golang server is #{use_golang_server}" do
|
||||
let(:metrics_dir) { Dir.mktmpdir }
|
||||
|
||||
before do
|
||||
# We need to send a request to localhost
|
||||
WebMock.allow_net_connect!
|
||||
subject(:start_server!) do
|
||||
@pid = MetricsServer.spawn(target, metrics_dir: metrics_dir, path: @exporter_path.join('bin'))
|
||||
end
|
||||
|
||||
before do
|
||||
if use_golang_server
|
||||
stub_env('GITLAB_GOLANG_METRICS_SERVER', '1')
|
||||
allow(Settings).to receive(:monitoring).and_return(config.dig('test', 'monitoring'))
|
||||
else
|
||||
config_file.write(YAML.dump(config))
|
||||
config_file.close
|
||||
|
||||
@pid = MetricsServer.spawn(target, metrics_dir: metrics_dir, gitlab_config: config_file.path, wipe_metrics_dir: true)
|
||||
stub_env('GITLAB_CONFIG', config_file.path)
|
||||
end
|
||||
# We need to send a request to localhost
|
||||
WebMock.allow_net_connect!
|
||||
end
|
||||
|
||||
after do
|
||||
|
@ -54,25 +93,25 @@ RSpec.describe 'bin/metrics-server', :aggregate_failures do
|
|||
|
||||
expect(Gitlab::ProcessManagement.process_alive?(@pid)).to be(false)
|
||||
end
|
||||
rescue Errno::ESRCH => _
|
||||
# 'No such process' means the process died before
|
||||
rescue Errno::ESRCH, Errno::ECHILD => _
|
||||
# 'No such process' or 'No child processes' means the process died before
|
||||
ensure
|
||||
config_file.unlink
|
||||
FileUtils.rm_rf(metrics_dir, secure: true)
|
||||
end
|
||||
|
||||
it 'serves /metrics endpoint' do
|
||||
expect do
|
||||
Timeout.timeout(10) do
|
||||
http_ok = false
|
||||
until http_ok
|
||||
sleep 1
|
||||
response = Gitlab::HTTP.try_get("http://localhost:3807/metrics", allow_local_requests: true)
|
||||
http_ok = response&.success?
|
||||
end
|
||||
end
|
||||
end.not_to raise_error
|
||||
it_behaves_like 'serves metrics endpoint'
|
||||
|
||||
context 'when using Pathname instance as target directory' do
|
||||
let(:metrics_dir) { Pathname.new(Dir.mktmpdir) }
|
||||
|
||||
it_behaves_like 'serves metrics endpoint'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'spawns a server', 'puma', true
|
||||
it_behaves_like 'spawns a server', 'puma', false
|
||||
it_behaves_like 'spawns a server', 'sidekiq', true
|
||||
it_behaves_like 'spawns a server', 'sidekiq', false
|
||||
end
|
||||
|
|
|
@ -314,7 +314,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
|
|||
let(:sidekiq_exporter_enabled) { true }
|
||||
|
||||
it 'does not start a sidekiq metrics server' do
|
||||
expect(MetricsServer).not_to receive(:fork)
|
||||
expect(MetricsServer).not_to receive(:start_for_sidekiq)
|
||||
|
||||
cli.run(%w(foo))
|
||||
end
|
||||
|
@ -324,7 +324,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
|
|||
let(:sidekiq_exporter_enabled) { true }
|
||||
|
||||
it 'does not start a sidekiq metrics server' do
|
||||
expect(MetricsServer).not_to receive(:fork)
|
||||
expect(MetricsServer).not_to receive(:start_for_sidekiq)
|
||||
|
||||
cli.run(%w(foo))
|
||||
end
|
||||
|
@ -347,7 +347,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
|
|||
end
|
||||
|
||||
it 'does not start a sidekiq metrics server' do
|
||||
expect(MetricsServer).not_to receive(:fork)
|
||||
expect(MetricsServer).not_to receive(:start_for_sidekiq)
|
||||
|
||||
cli.run(%w(foo))
|
||||
end
|
||||
|
@ -366,7 +366,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
|
|||
end
|
||||
|
||||
it 'does not start a sidekiq metrics server' do
|
||||
expect(MetricsServer).not_to receive(:fork)
|
||||
expect(MetricsServer).not_to receive(:start_for_sidekiq)
|
||||
|
||||
cli.run(%w(foo))
|
||||
end
|
||||
|
@ -389,9 +389,9 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
|
|||
with_them do
|
||||
specify do
|
||||
if start_metrics_server
|
||||
expect(MetricsServer).to receive(:fork).with('sidekiq', metrics_dir: metrics_dir, reset_signals: trapped_signals)
|
||||
expect(MetricsServer).to receive(:start_for_sidekiq).with(metrics_dir: metrics_dir, reset_signals: trapped_signals)
|
||||
else
|
||||
expect(MetricsServer).not_to receive(:fork)
|
||||
expect(MetricsServer).not_to receive(:start_for_sidekiq)
|
||||
end
|
||||
|
||||
cli.run(%w(foo))
|
||||
|
@ -421,7 +421,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
|
|||
let(:sidekiq_exporter_enabled) { true }
|
||||
|
||||
it 'does not start the server' do
|
||||
expect(MetricsServer).not_to receive(:fork)
|
||||
expect(MetricsServer).not_to receive(:start_for_sidekiq)
|
||||
|
||||
cli.run(%w(foo --dryrun))
|
||||
end
|
||||
|
@ -442,7 +442,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
|
|||
it 'stops the entire process cluster if one of the workers has been terminated' do
|
||||
expect(supervisor).to receive(:alive).and_return(true)
|
||||
expect(supervisor).to receive(:supervise).and_yield([2])
|
||||
expect(MetricsServer).to receive(:fork).once.and_return(metrics_server_pid)
|
||||
expect(MetricsServer).to receive(:start_for_sidekiq).once.and_return(metrics_server_pid)
|
||||
expect(Gitlab::ProcessManagement).to receive(:signal_processes).with([42, 99], :TERM)
|
||||
|
||||
cli.run(%w(foo))
|
||||
|
@ -452,7 +452,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
|
|||
it 'restarts the metrics server when it is down' do
|
||||
expect(supervisor).to receive(:alive).and_return(true)
|
||||
expect(supervisor).to receive(:supervise).and_yield([metrics_server_pid])
|
||||
expect(MetricsServer).to receive(:fork).twice.and_return(metrics_server_pid)
|
||||
expect(MetricsServer).to receive(:start_for_sidekiq).twice.and_return(metrics_server_pid)
|
||||
|
||||
cli.run(%w(foo))
|
||||
end
|
||||
|
@ -462,7 +462,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
|
|||
it 'does not restart the metrics server' do
|
||||
expect(supervisor).to receive(:alive).and_return(false)
|
||||
expect(supervisor).to receive(:supervise).and_yield([metrics_server_pid])
|
||||
expect(MetricsServer).to receive(:fork).once.and_return(metrics_server_pid)
|
||||
expect(MetricsServer).to receive(:start_for_sidekiq).once.and_return(metrics_server_pid)
|
||||
|
||||
cli.run(%w(foo))
|
||||
end
|
||||
|
|
|
@ -27,7 +27,7 @@ RSpec.describe JiraConnect::EventsController do
|
|||
|
||||
shared_context 'valid JWT token' do
|
||||
before do
|
||||
allow_next_instance_of(Atlassian::JiraConnect::AsymmetricJwt) do |asymmetric_jwt|
|
||||
allow_next_instance_of(Atlassian::JiraConnect::Jwt::Asymmetric) do |asymmetric_jwt|
|
||||
allow(asymmetric_jwt).to receive(:valid?).and_return(true)
|
||||
allow(asymmetric_jwt).to receive(:iss_claim).and_return(client_key)
|
||||
end
|
||||
|
@ -36,7 +36,7 @@ RSpec.describe JiraConnect::EventsController do
|
|||
|
||||
shared_context 'invalid JWT token' do
|
||||
before do
|
||||
allow_next_instance_of(Atlassian::JiraConnect::AsymmetricJwt) do |asymmetric_jwt|
|
||||
allow_next_instance_of(Atlassian::JiraConnect::Jwt::Asymmetric) do |asymmetric_jwt|
|
||||
allow(asymmetric_jwt).to receive(:valid?).and_return(false)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
|||
import ListItem from '~/vue_shared/components/registry/list_item.vue';
|
||||
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import Component from '~/packages_and_registries/dependency_proxy/components/manifest_row.vue';
|
||||
import { MANIFEST_PENDING_DESTRUCTION_STATUS } from '~/packages_and_registries/dependency_proxy/constants';
|
||||
import { proxyManifests } from 'jest/packages_and_registries/dependency_proxy/mock_data';
|
||||
|
||||
describe('Manifest Row', () => {
|
||||
|
@ -26,15 +27,17 @@ describe('Manifest Row', () => {
|
|||
const findListItem = () => wrapper.findComponent(ListItem);
|
||||
const findCachedMessages = () => wrapper.findByTestId('cached-message');
|
||||
const findTimeAgoTooltip = () => wrapper.findComponent(TimeagoTooltip);
|
||||
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
const findStatus = () => wrapper.findByTestId('status');
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
describe('With a manifest on the DEFAULT status', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('has a list item', () => {
|
||||
expect(findListItem().exists()).toBe(true);
|
||||
});
|
||||
|
@ -56,4 +59,31 @@ describe('Manifest Row', () => {
|
|||
time: defaultProps.manifest.createdAt,
|
||||
});
|
||||
});
|
||||
|
||||
it('does not have a status element displayed', () => {
|
||||
expect(findStatus().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('With a manifest on the PENDING_DESTRUCTION_STATUS', () => {
|
||||
const pendingDestructionManifest = {
|
||||
manifest: {
|
||||
...defaultProps.manifest,
|
||||
status: MANIFEST_PENDING_DESTRUCTION_STATUS,
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
createComponent(pendingDestructionManifest);
|
||||
});
|
||||
|
||||
it('has a list item', () => {
|
||||
expect(findListItem().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('has a status element displayed', () => {
|
||||
expect(findStatus().exists()).toBe(true);
|
||||
expect(findStatus().text()).toBe('Scheduled for deletion');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,8 +8,18 @@ export const proxyData = () => ({
|
|||
export const proxySettings = (extend = {}) => ({ enabled: true, ...extend });
|
||||
|
||||
export const proxyManifests = () => [
|
||||
{ id: 'proxy-1', createdAt: '2021-09-22T09:45:28Z', imageName: 'alpine:latest' },
|
||||
{ id: 'proxy-2', createdAt: '2021-09-21T09:45:28Z', imageName: 'alpine:stable' },
|
||||
{
|
||||
id: 'proxy-1',
|
||||
createdAt: '2021-09-22T09:45:28Z',
|
||||
imageName: 'alpine:latest',
|
||||
status: 'DEFAULT',
|
||||
},
|
||||
{
|
||||
id: 'proxy-2',
|
||||
createdAt: '2021-09-21T09:45:28Z',
|
||||
imageName: 'alpine:stable',
|
||||
status: 'DEFAULT',
|
||||
},
|
||||
];
|
||||
|
||||
export const pagination = (extend) => ({
|
||||
|
|
|
@ -101,20 +101,6 @@ describe('list item', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('disabled prop', () => {
|
||||
it('when true applies gl-opacity-5 class', () => {
|
||||
mountComponent({ disabled: true });
|
||||
|
||||
expect(wrapper.classes('gl-opacity-5')).toBe(true);
|
||||
});
|
||||
|
||||
it('when false does not apply gl-opacity-5 class', () => {
|
||||
mountComponent({ disabled: false });
|
||||
|
||||
expect(wrapper.classes('gl-opacity-5')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('borders and selection', () => {
|
||||
it.each`
|
||||
first | selected | shouldHave | shouldNotHave
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Atlassian::JiraConnect::AsymmetricJwt do
|
||||
RSpec.describe Atlassian::JiraConnect::Jwt::Asymmetric do
|
||||
describe '#valid?' do
|
||||
subject(:asymmetric_jwt) { described_class.new(jwt, verification_claims) }
|
||||
|
||||
|
@ -10,15 +10,19 @@ RSpec.describe Atlassian::JiraConnect::AsymmetricJwt do
|
|||
let(:jwt_claims) { { aud: aud, iss: client_key, qsh: qsh } }
|
||||
let(:aud) { 'https://test.host/-/jira_connect' }
|
||||
let(:client_key) { '1234' }
|
||||
let(:qsh) { Atlassian::Jwt.create_query_string_hash('https://gitlab.test/events/installed', 'POST', 'https://gitlab.test') }
|
||||
let(:public_key_id) { '123e4567-e89b-12d3-a456-426614174000' }
|
||||
let(:jwt_headers) { { kid: public_key_id } }
|
||||
let(:private_key) { OpenSSL::PKey::RSA.generate 2048 }
|
||||
let(:jwt) { JWT.encode(jwt_claims, private_key, 'RS256', jwt_headers) }
|
||||
let(:public_key) { private_key.public_key }
|
||||
let(:install_keys_url) { "https://connect-install-keys.atlassian.com/#{public_key_id}" }
|
||||
let(:qsh) do
|
||||
Atlassian::Jwt.create_query_string_hash('https://gitlab.test/events/installed', 'POST', 'https://gitlab.test')
|
||||
end
|
||||
|
||||
before do
|
||||
stub_request(:get, "https://connect-install-keys.atlassian.com/#{public_key_id}").to_return(body: public_key.to_s, status: 200)
|
||||
stub_request(:get, install_keys_url)
|
||||
.to_return(body: public_key.to_s, status: 200)
|
||||
end
|
||||
|
||||
it 'returns true when verified with public key from CDN' do
|
||||
|
@ -26,7 +30,7 @@ RSpec.describe Atlassian::JiraConnect::AsymmetricJwt do
|
|||
|
||||
expect(asymmetric_jwt).to be_valid
|
||||
|
||||
expect(WebMock).to have_requested(:get, "https://connect-install-keys.atlassian.com/#{public_key_id}")
|
||||
expect(WebMock).to have_requested(:get, install_keys_url)
|
||||
end
|
||||
|
||||
context 'JWT does not contain a key ID' do
|
||||
|
@ -43,7 +47,7 @@ RSpec.describe Atlassian::JiraConnect::AsymmetricJwt do
|
|||
|
||||
context 'public key can not be retrieved' do
|
||||
before do
|
||||
stub_request(:get, "https://connect-install-keys.atlassian.com/#{public_key_id}").to_return(body: '', status: 404)
|
||||
stub_request(:get, install_keys_url).to_return(body: '', status: 404)
|
||||
end
|
||||
|
||||
it { is_expected.not_to be_valid }
|
|
@ -0,0 +1,81 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rake_helper'
|
||||
require_relative '../../../support/helpers/next_instance_of'
|
||||
|
||||
RSpec.describe 'gitlab:metrics_exporter:install' do
|
||||
before do
|
||||
Rake.application.rake_require 'tasks/gitlab/metrics_exporter'
|
||||
end
|
||||
|
||||
subject(:task) do
|
||||
Rake::Task['gitlab:metrics_exporter:install']
|
||||
end
|
||||
|
||||
context 'when no target directory is specified' do
|
||||
it 'aborts with an error message' do
|
||||
expect do
|
||||
expect { task.execute }.to output(/Please specify the directory/).to_stdout
|
||||
end.to raise_error(SystemExit)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when target directory is specified' do
|
||||
let(:args) { Rake::TaskArguments.new(%w(dir), %w(path/to/exporter)) }
|
||||
let(:context) { TOPLEVEL_BINDING.eval('self') }
|
||||
let(:expected_clone_params) do
|
||||
{
|
||||
repo: 'https://gitlab.com/gitlab-org/gitlab-metrics-exporter.git',
|
||||
version: 'main',
|
||||
target_dir: 'path/to/exporter'
|
||||
}
|
||||
end
|
||||
|
||||
context 'when dependencies are missing' do
|
||||
it 'aborts with an error message' do
|
||||
expect(Gitlab::Utils).to receive(:which).with('gmake').ordered
|
||||
expect(Gitlab::Utils).to receive(:which).with('make').ordered
|
||||
|
||||
expect do
|
||||
expect { task.execute(args) }.to output(/Couldn't find a 'make' binary/).to_stdout
|
||||
end.to raise_error(SystemExit)
|
||||
end
|
||||
end
|
||||
|
||||
it 'installs the exporter with gmake' do
|
||||
expect(Gitlab::Utils).to receive(:which).with('gmake').and_return('path/to/gmake').ordered
|
||||
expect(context).to receive(:checkout_or_clone_version).with(hash_including(expected_clone_params)).ordered
|
||||
expect(Dir).to receive(:chdir).with('path/to/exporter').and_yield.ordered
|
||||
expect(context).to receive(:run_command!).with(['path/to/gmake']).ordered
|
||||
|
||||
task.execute(args)
|
||||
end
|
||||
|
||||
it 'installs the exporter with make' do
|
||||
expect(Gitlab::Utils).to receive(:which).with('gmake').ordered
|
||||
expect(Gitlab::Utils).to receive(:which).with('make').and_return('path/to/make').ordered
|
||||
expect(context).to receive(:checkout_or_clone_version).with(hash_including(expected_clone_params)).ordered
|
||||
expect(Dir).to receive(:chdir).with('path/to/exporter').and_yield.ordered
|
||||
expect(context).to receive(:run_command!).with(['path/to/make']).ordered
|
||||
|
||||
task.execute(args)
|
||||
end
|
||||
|
||||
context 'when overriding version via environment variable' do
|
||||
before do
|
||||
stub_env('GITLAB_METRICS_EXPORTER_VERSION', '1.0')
|
||||
end
|
||||
|
||||
it 'clones from repository with that version instead' do
|
||||
expect(Gitlab::Utils).to receive(:which).with('gmake').and_return('path/to/gmake').ordered
|
||||
expect(context).to receive(:checkout_or_clone_version).with(
|
||||
hash_including(expected_clone_params.merge(version: '1.0'))
|
||||
).ordered
|
||||
expect(Dir).to receive(:chdir).with('path/to/exporter').and_yield.ordered
|
||||
expect(context).to receive(:run_command!).with(['path/to/gmake']).ordered
|
||||
|
||||
task.execute(args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -15,6 +15,8 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
|
|||
let(:ruby_sampler_double) { double(Gitlab::Metrics::Samplers::RubySampler) }
|
||||
|
||||
before do
|
||||
# Make sure we never actually spawn any new processes in a unit test.
|
||||
%i(spawn fork detach).each { |m| allow(Process).to receive(m) }
|
||||
# We do not want this to have knock-on effects on the test process.
|
||||
allow(Gitlab::ProcessManagement).to receive(:modify_signals)
|
||||
|
||||
|
@ -67,13 +69,19 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
|
|||
end
|
||||
|
||||
describe '.spawn' do
|
||||
context 'for legacy Ruby server' do
|
||||
let(:expected_env) do
|
||||
{
|
||||
'METRICS_SERVER_TARGET' => target,
|
||||
'WIPE_METRICS_DIR' => '0'
|
||||
'WIPE_METRICS_DIR' => '0',
|
||||
'GITLAB_CONFIG' => 'path/to/config/gitlab.yml'
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
stub_env('GITLAB_CONFIG', 'path/to/config/gitlab.yml')
|
||||
end
|
||||
|
||||
it 'spawns a new server process and returns its PID' do
|
||||
expect(Process).to receive(:spawn).with(
|
||||
expected_env,
|
||||
|
@ -86,16 +94,44 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
|
|||
|
||||
expect(pid).to eq(99)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when path to gitlab.yml is passed' do
|
||||
it 'sets the GITLAB_CONFIG environment variable' do
|
||||
context 'for Golang server' do
|
||||
let(:expected_port) { target == 'puma' ? '8083' : '8082' }
|
||||
let(:expected_env) do
|
||||
{
|
||||
'GME_MMAP_METRICS_DIR' => metrics_dir,
|
||||
'GME_PROBES' => 'self,mmap',
|
||||
'GME_SERVER_HOST' => 'localhost',
|
||||
'GME_SERVER_PORT' => expected_port
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
stub_env('GITLAB_GOLANG_METRICS_SERVER', '1')
|
||||
end
|
||||
|
||||
it 'spawns a new server process and returns its PID' do
|
||||
expect(Process).to receive(:spawn).with(
|
||||
expected_env.merge('GITLAB_CONFIG' => 'path/to/config/gitlab.yml'),
|
||||
end_with('bin/metrics-server'),
|
||||
expected_env,
|
||||
'gitlab-metrics-exporter',
|
||||
hash_including(pgroup: true)
|
||||
).and_return(99)
|
||||
expect(Process).to receive(:detach).with(99)
|
||||
|
||||
pid = described_class.spawn(target, metrics_dir: metrics_dir)
|
||||
|
||||
expect(pid).to eq(99)
|
||||
end
|
||||
|
||||
it 'can launch from explicit path instead of PATH' do
|
||||
expect(Process).to receive(:spawn).with(
|
||||
expected_env,
|
||||
'/path/to/gme/gitlab-metrics-exporter',
|
||||
hash_including(pgroup: true)
|
||||
).and_return(99)
|
||||
|
||||
described_class.spawn(target, metrics_dir: metrics_dir, gitlab_config: 'path/to/config/gitlab.yml')
|
||||
described_class.spawn(target, metrics_dir: metrics_dir, path: '/path/to/gme/')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -112,12 +148,23 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
|
|||
end
|
||||
|
||||
describe '.spawn' do
|
||||
context 'for legacy Ruby server' do
|
||||
it 'raises an error' do
|
||||
expect { described_class.spawn('unsupported', metrics_dir: metrics_dir) }.to(
|
||||
raise_error('Target must be one of [puma,sidekiq]')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'for Golang server' do
|
||||
it 'raises an error' do
|
||||
stub_env('GITLAB_GOLANG_METRICS_SERVER', '1')
|
||||
expect { described_class.spawn('unsupported', metrics_dir: metrics_dir) }.to(
|
||||
raise_error('Target must be one of [puma,sidekiq]')
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'a metrics exporter' do |target, expected_name|
|
||||
|
@ -245,4 +292,23 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.start_for_sidekiq' do
|
||||
context 'for legacy Ruby server' do
|
||||
it 'forks the parent process' do
|
||||
expect(Process).to receive(:fork).and_return(42)
|
||||
|
||||
described_class.start_for_sidekiq(metrics_dir: '/path/to/metrics')
|
||||
end
|
||||
end
|
||||
|
||||
context 'for Golang server' do
|
||||
it 'spawns the server process' do
|
||||
stub_env('GITLAB_GOLANG_METRICS_SERVER', '1')
|
||||
expect(Process).to receive(:spawn).and_return(42)
|
||||
|
||||
described_class.start_for_sidekiq(metrics_dir: '/path/to/metrics')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue