Skip to content
Snippets Groups Projects
Commit b9bac6db authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 8c4198cb
No related branches found
No related tags found
No related merge requests found
Showing
with 270 additions and 155 deletions
<!-- Instructions: Use this template for a proof of concept or when a deeper technical evaluation is required. Please weigh tech evaluation issues and follow the instructions below accordingly. -->
### Topic to Evaluate
<!-- Describe the related issue and challenge we need to establish a proof of concept for-->
* [Link to other Issue](link)
### Tasks to Evaluate
<!-- Outline the tasks with issues that you need evaluate as a part of the implementation issue -->
- [ ] Add task
- [ ] Add task
- [ ] Add task
### Risks and Implementation Considerations
<!-- Idenitfy any risks found in the research, whether this is performance, impacts to other functionality or other bugs -->
### Team
- [ ] Add ~"workflow::planning breakdown" ~feature and the corresponding `~devops::<stage>` and `~group::<group>` labels.
- [ ] Ping the PM and EM.
Loading
Loading
@@ -90,11 +90,7 @@ export default {
};
</script>
<template>
<div v-gl-resize-observer-directive="onResize" class="prometheus-graph">
<div class="prometheus-graph-header">
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphData.title }}</h5>
<div ref="graphWidgets" class="prometheus-graph-widgets"><slot></slot></div>
</div>
<div v-gl-resize-observer-directive="onResize">
<gl-column-chart
ref="columnChart"
v-bind="$attrs"
Loading
Loading
Loading
Loading
@@ -27,10 +27,7 @@ export default {
};
</script>
<template>
<div class="prometheus-graph d-flex flex-column justify-content-center">
<div class="prometheus-graph-header">
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphTitle }}</h5>
</div>
<div class="d-flex flex-column justify-content-center">
<div
class="prepend-top-8 svg-w-100 d-flex align-items-center"
:style="svgContainerStyle"
Loading
Loading
Loading
Loading
@@ -2,13 +2,11 @@
import { GlResizeObserverDirective } from '@gitlab/ui';
import { GlHeatmap } from '@gitlab/ui/dist/charts';
import dateformat from 'dateformat';
import PrometheusHeader from '../shared/prometheus_header.vue';
import { graphDataValidatorForValues } from '../../utils';
 
export default {
components: {
GlHeatmap,
PrometheusHeader,
},
directives: {
GlResizeObserverDirective,
Loading
Loading
@@ -65,8 +63,7 @@ export default {
};
</script>
<template>
<div v-gl-resize-observer-directive="onResize" class="prometheus-graph col-12 col-lg-6">
<prometheus-header :graph-title="graphData.title" />
<div v-gl-resize-observer-directive="onResize" class="col-12 col-lg-6">
<gl-heatmap
ref="heatmapChart"
v-bind="$attrs"
Loading
Loading
Loading
Loading
@@ -42,10 +42,7 @@ export default {
};
</script>
<template>
<div class="prometheus-graph">
<div class="prometheus-graph-header">
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphTitle }}</h5>
</div>
<div>
<gl-single-stat :value="statValue" :title="graphTitle" variant="success" />
</div>
</template>
Loading
Loading
@@ -81,11 +81,7 @@ export default {
};
</script>
<template>
<div v-gl-resize-observer-directive="onResize" class="prometheus-graph">
<div class="prometheus-graph-header">
<h5 ref="graphTitle" class="prometheus-graph-title">{{ graphData.title }}</h5>
<div ref="graphWidgets" class="prometheus-graph-widgets"><slot></slot></div>
</div>
<div v-gl-resize-observer-directive="onResize">
<gl-stacked-column-chart
ref="chart"
v-bind="$attrs"
Loading
Loading
Loading
Loading
@@ -112,7 +112,6 @@ export default {
isDeployment: false,
sha: '',
},
showTitleTooltip: false,
width: 0,
height: chartHeight,
svgs: {},
Loading
Loading
@@ -285,12 +284,6 @@ export default {
return `${this.graphData.y_label}`;
},
},
mounted() {
const graphTitleEl = this.$refs.graphTitle;
if (graphTitleEl && graphTitleEl.scrollWidth > graphTitleEl.offsetWidth) {
this.showTitleTooltip = true;
}
},
created() {
this.setSvg('rocket');
this.setSvg('scroll-handle');
Loading
Loading
@@ -387,24 +380,7 @@ export default {
</script>
 
<template>
<div v-gl-resize-observer-directive="onResize" class="prometheus-graph">
<div class="prometheus-graph-header">
<h5
ref="graphTitle"
class="prometheus-graph-title js-graph-title text-truncate append-right-8"
>
{{ graphData.title }}
</h5>
<gl-tooltip :target="() => $refs.graphTitle" :disabled="!showTitleTooltip">
{{ graphData.title }}
</gl-tooltip>
<div
class="prometheus-graph-widgets js-graph-widgets flex-fill"
data-qa-selector="prometheus_graph_widgets"
>
<slot></slot>
</div>
</div>
<div v-gl-resize-observer-directive="onResize">
<component
:is="glChartComponent"
ref="chart"
Loading
Loading
Loading
Loading
@@ -3,10 +3,12 @@ import { mapState } from 'vuex';
import { pickBy } from 'lodash';
import invalidUrl from '~/lib/utils/invalid_url';
import {
GlResizeObserverDirective,
GlDropdown,
GlDropdownItem,
GlModal,
GlModalDirective,
GlTooltip,
GlTooltipDirective,
} from '@gitlab/ui';
import { __ } from '~/locale';
Loading
Loading
@@ -29,11 +31,13 @@ export default {
MonitorStackedColumnChart,
MonitorEmptyChart,
Icon,
GlTooltip,
GlDropdown,
GlDropdownItem,
GlModal,
},
directives: {
GlResizeObserver: GlResizeObserverDirective,
GlModal: GlModalDirective,
GlTooltip: GlTooltipDirective,
TrackEvent: TrackEventDirective,
Loading
Loading
@@ -61,11 +65,15 @@ export default {
},
data() {
return {
showTitleTooltip: false,
zoomedTimeRange: null,
};
},
computed: {
...mapState('monitoringDashboard', ['deploymentData', 'projectPath', 'logsPath', 'timeRange']),
title() {
return this.graphData.title || '';
},
alertWidgetAvailable() {
return IS_EE && this.prometheusAlertsAvailable && this.alertsEndpoint && this.graphData;
},
Loading
Loading
@@ -97,12 +105,24 @@ export default {
const data = new Blob([this.csvText], { type: 'text/plain' });
return window.URL.createObjectURL(data);
},
monitorChartComponent() {
timeChartComponent() {
if (this.isPanelType('anomaly-chart')) {
return MonitorAnomalyChart;
}
return MonitorTimeSeriesChart;
},
isContextualMenuShown() {
return (
this.graphDataHasMetrics &&
!this.isPanelType('single-stat') &&
!this.isPanelType('heatmap') &&
!this.isPanelType('column') &&
!this.isPanelType('stacked-column')
);
},
},
mounted() {
this.refreshTitleTooltip();
},
methods: {
getGraphAlerts(queries) {
Loading
Loading
@@ -119,9 +139,18 @@ export default {
showToast() {
this.$toast.show(__('Link copied'));
},
refreshTitleTooltip() {
const { graphTitle } = this.$refs;
this.showTitleTooltip =
Boolean(graphTitle) && graphTitle.scrollWidth > graphTitle.offsetWidth;
},
downloadCSVOptions,
generateLinkToChartOptions,
 
onResize() {
this.refreshTitleTooltip();
},
onDatazoom({ start, end }) {
this.zoomedTimeRange = { start, end };
},
Loading
Loading
@@ -129,88 +158,109 @@ export default {
};
</script>
<template>
<monitor-single-stat-chart
v-if="isPanelType('single-stat') && graphDataHasMetrics"
:graph-data="graphData"
/>
<monitor-heatmap-chart
v-else-if="isPanelType('heatmap') && graphDataHasMetrics"
:graph-data="graphData"
/>
<monitor-column-chart
v-else-if="isPanelType('column') && graphDataHasMetrics"
:graph-data="graphData"
/>
<monitor-stacked-column-chart
v-else-if="isPanelType('stacked-column') && graphDataHasMetrics"
:graph-data="graphData"
/>
<component
:is="monitorChartComponent"
v-else-if="graphDataHasMetrics"
ref="timeChart"
:graph-data="graphData"
:deployment-data="deploymentData"
:project-path="projectPath"
:thresholds="getGraphAlertValues(graphData.metrics)"
:group-id="groupId"
@datazoom="onDatazoom"
>
<div class="d-flex align-items-center">
<alert-widget
v-if="alertWidgetAvailable && graphData"
:modal-id="`alert-modal-${index}`"
:alerts-endpoint="alertsEndpoint"
:relevant-queries="graphData.metrics"
:alerts-to-manage="getGraphAlerts(graphData.metrics)"
@setAlerts="setAlerts"
/>
<gl-dropdown
v-gl-tooltip
class="ml-auto mx-3"
toggle-class="btn btn-transparent border-0"
data-qa-selector="prometheus_widgets_dropdown"
:right="true"
:no-caret="true"
:title="__('More actions')"
<div v-gl-resize-observer="onResize" class="prometheus-graph">
<div class="prometheus-graph-header">
<h5
ref="graphTitle"
class="prometheus-graph-title gl-font-size-large font-weight-bold text-truncate append-right-8"
>
<template slot="button-content">
<icon name="ellipsis_v" class="text-secondary" />
</template>
{{ title }}
</h5>
<gl-tooltip :target="() => $refs.graphTitle" :disabled="!showTitleTooltip">
{{ title }}
</gl-tooltip>
<div
v-if="isContextualMenuShown"
class="prometheus-graph-widgets js-graph-widgets flex-fill"
data-qa-selector="prometheus_graph_widgets"
>
<div class="d-flex align-items-center">
<alert-widget
v-if="alertWidgetAvailable && graphData"
:modal-id="`alert-modal-${index}`"
:alerts-endpoint="alertsEndpoint"
:relevant-queries="graphData.metrics"
:alerts-to-manage="getGraphAlerts(graphData.metrics)"
@setAlerts="setAlerts"
/>
<gl-dropdown
v-gl-tooltip
class="ml-auto mx-3"
toggle-class="btn btn-transparent border-0"
data-qa-selector="prometheus_widgets_dropdown"
right
no-caret
:title="__('More actions')"
>
<template slot="button-content">
<icon name="ellipsis_v" class="text-secondary" />
</template>
 
<gl-dropdown-item
v-if="logsPathWithTimeRange"
ref="viewLogsLink"
:href="logsPathWithTimeRange"
>
{{ s__('Metrics|View logs') }}
</gl-dropdown-item>
<gl-dropdown-item
v-if="logsPathWithTimeRange"
ref="viewLogsLink"
:href="logsPathWithTimeRange"
>
{{ s__('Metrics|View logs') }}
</gl-dropdown-item>
 
<gl-dropdown-item
v-track-event="downloadCSVOptions(graphData.title)"
:href="downloadCsv"
download="chart_metrics.csv"
>
{{ __('Download CSV') }}
</gl-dropdown-item>
<gl-dropdown-item
v-if="clipboardText"
ref="copyChartLink"
v-track-event="generateLinkToChartOptions(clipboardText)"
:data-clipboard-text="clipboardText"
@click="showToast(clipboardText)"
>
{{ __('Generate link to chart') }}
</gl-dropdown-item>
<gl-dropdown-item
v-if="alertWidgetAvailable"
v-gl-modal="`alert-modal-${index}`"
data-qa-selector="alert_widget_menu_item"
>
{{ __('Alerts') }}
</gl-dropdown-item>
</gl-dropdown>
<gl-dropdown-item
v-if="csvText"
ref="downloadCsvLink"
v-track-event="downloadCSVOptions(title)"
:href="downloadCsv"
download="chart_metrics.csv"
>
{{ __('Download CSV') }}
</gl-dropdown-item>
<gl-dropdown-item
v-if="clipboardText"
ref="copyChartLink"
v-track-event="generateLinkToChartOptions(clipboardText)"
:data-clipboard-text="clipboardText"
@click="showToast(clipboardText)"
>
{{ __('Generate link to chart') }}
</gl-dropdown-item>
<gl-dropdown-item
v-if="alertWidgetAvailable"
v-gl-modal="`alert-modal-${index}`"
data-qa-selector="alert_widget_menu_item"
>
{{ __('Alerts') }}
</gl-dropdown-item>
</gl-dropdown>
</div>
</div>
</div>
</component>
<monitor-empty-chart v-else :graph-title="graphData.title" />
<monitor-single-stat-chart
v-if="isPanelType('single-stat') && graphDataHasMetrics"
:graph-data="graphData"
/>
<monitor-heatmap-chart
v-else-if="isPanelType('heatmap') && graphDataHasMetrics"
:graph-data="graphData"
/>
<monitor-column-chart
v-else-if="isPanelType('column') && graphDataHasMetrics"
:graph-data="graphData"
/>
<monitor-stacked-column-chart
v-else-if="isPanelType('stacked-column') && graphDataHasMetrics"
:graph-data="graphData"
/>
<component
:is="timeChartComponent"
v-else-if="graphDataHasMetrics"
ref="timeChart"
:graph-data="graphData"
:deployment-data="deploymentData"
:project-path="projectPath"
:thresholds="getGraphAlertValues(graphData.metrics)"
:group-id="groupId"
@datazoom="onDatazoom"
/>
<monitor-empty-chart v-else :graph-title="title" v-bind="$attrs" v-on="$listeners" />
</div>
</template>
<script>
export default {
props: {
graphTitle: {
type: String,
required: true,
},
},
};
</script>
<template>
<div class="prometheus-graph-header">
<h5 ref="title" class="prometheus-graph-title">{{ graphTitle }}</h5>
</div>
</template>
Loading
Loading
@@ -91,10 +91,6 @@
margin-bottom: $gl-padding-8;
}
 
.prometheus-graph-title {
font-size: $gl-font-size-large;
}
.alert-current-setting {
max-width: 240px;
}
Loading
Loading
# frozen_string_literal: true
class ServerlessDomainFinder
attr_reader :match, :serverless_domain_cluster, :environment
def initialize(uri)
@match = ::Serverless::Domain::REGEXP.match(uri)
end
def execute
return unless serverless?
@serverless_domain_cluster = ::Serverless::DomainCluster.for_uuid(serverless_domain_cluster_uuid)
return unless serverless_domain_cluster
@environment = ::Environment.for_id_and_slug(match[:environment_id].to_i(16), match[:environment_slug])
return unless environment
::Serverless::Domain.new(
function_name: match[:function_name],
serverless_domain_cluster: serverless_domain_cluster,
environment: environment
)
end
def serverless_domain_cluster_uuid
return unless serverless?
match[:cluster_left] + match[:cluster_middle] + match[:cluster_right]
end
def serverless?
!!match
end
end
Loading
Loading
@@ -15,7 +15,7 @@ module Clusters
def set_initial_status
return unless not_installable?
 
self.status = status_states[:installable] if cluster&.application_helm_available? || Feature.enabled?(:managed_apps_local_tiller)
self.status = status_states[:installable] if cluster&.application_helm_available? || ::Gitlab::Kubernetes::Helm.local_tiller_enabled?
end
 
def can_uninstall?
Loading
Loading
Loading
Loading
@@ -23,7 +23,7 @@ module Clusters
@files ||= begin
files = { 'values.yaml': values }
 
files.merge!(certificate_files) if cluster.application_helm.has_ssl?
files.merge!(certificate_files) if use_tiller_ssl?
 
files
end
Loading
Loading
@@ -31,6 +31,12 @@ module Clusters
 
private
 
def use_tiller_ssl?
return false if ::Gitlab::Kubernetes::Helm.local_tiller_enabled?
cluster.application_helm.has_ssl?
end
def certificate_files
{
'ca.pem': ca_cert,
Loading
Loading
Loading
Loading
@@ -92,7 +92,10 @@ module Clusters
# When installing any application we are also performing an update
# of tiller (see Gitlab::Kubernetes::Helm::ClientCommand) so
# therefore we need to reflect that in the database.
application.cluster.application_helm.update!(version: Gitlab::Kubernetes::Helm::HELM_VERSION)
unless ::Gitlab::Kubernetes::Helm.local_tiller_enabled?
application.cluster.application_helm.update!(version: Gitlab::Kubernetes::Helm::HELM_VERSION)
end
end
 
after_transition any => [:uninstalling], :use_transactions => false do |application, _|
Loading
Loading
Loading
Loading
@@ -95,6 +95,10 @@ class Environment < ApplicationRecord
end
end
 
def self.for_id_and_slug(id, slug)
find_by(id: id, slug: slug)
end
def self.max_deployment_id_sql
Deployment.select(Deployment.arel_table[:id].maximum)
.where(Deployment.arel_table[:environment_id].eq(arel_table[:id]))
Loading
Loading
# frozen_string_literal: true
module Serverless
class Domain
include ActiveModel::Model
REGEXP = %r{^(?<scheme>https?://)?(?<function_name>[^.]+)-(?<cluster_left>\h{2})a1(?<cluster_middle>\h{10})f2(?<cluster_right>\h{2})(?<environment_id>\h+)-(?<environment_slug>[^.]+)\.(?<pages_domain_name>.+)}.freeze
UUID_LENGTH = 14
attr_accessor :function_name, :serverless_domain_cluster, :environment
validates :function_name, presence: true, allow_blank: false
validates :serverless_domain_cluster, presence: true
validates :environment, presence: true
def self.generate_uuid
SecureRandom.hex(UUID_LENGTH / 2)
end
def uri
URI("https://#{function_name}-#{serverless_domain_cluster_uuid}#{"%x" % environment.id}-#{environment.slug}.#{serverless_domain_cluster.domain}")
end
def knative_uri
URI("http://#{function_name}.#{namespace}.#{serverless_domain_cluster.knative.hostname}")
end
private
def namespace
serverless_domain_cluster.cluster.kubernetes_namespace_for(environment)
end
def serverless_domain_cluster_uuid
[
serverless_domain_cluster.uuid[0..1],
'a1',
serverless_domain_cluster.uuid[2..-3],
'f2',
serverless_domain_cluster.uuid[-2..-1]
].join
end
end
end
Loading
Loading
@@ -16,11 +16,18 @@ module Serverless
algorithm: 'aes-256-gcm'
 
validates :pages_domain, :knative, presence: true
validates :uuid, presence: true, uniqueness: true, length: { is: Gitlab::Serverless::Domain::UUID_LENGTH },
validates :uuid, presence: true, uniqueness: true, length: { is: ::Serverless::Domain::UUID_LENGTH },
format: { with: HEX_REGEXP, message: 'only allows hex characters' }
 
default_value_for(:uuid, allows_nil: false) { Gitlab::Serverless::Domain.generate_uuid }
default_value_for(:uuid, allows_nil: false) { ::Serverless::Domain.generate_uuid }
 
delegate :domain, to: :pages_domain
delegate :cluster, to: :knative
def self.for_uuid(uuid)
joins(:pages_domain, :knative)
.includes(:pages_domain, :knative)
.find_by(uuid: uuid)
end
end
end
#badge-settings{ data: { api_endpoint_url: @badge_api_endpoint,
docs_url: help_page_path('user/project/badges')} }
.text-center.prepend-top-default
= icon('spinner spin 2x')
---
title: Remove unused loading spinner from badge_settings partial
merge_request: 25044
author: nuwe1
type: other
Loading
Loading
@@ -13,7 +13,7 @@ The Packages feature allows GitLab to act as a repository for the following:
| [Conan Repository](conan_repository/index.md) **(PREMIUM)** | The GitLab Conan Repository enables every project in GitLab to have its own space to store [Conan](https://conan.io/) packages. | 12.6+ |
| [Maven Repository](maven_repository/index.md) **(PREMIUM)** | The GitLab Maven Repository enables every project in GitLab to have its own space to store [Maven](https://maven.apache.org/) packages. | 11.3+ |
| [NPM Registry](npm_registry/index.md) **(PREMIUM)** | The GitLab NPM Registry enables every project in GitLab to have its own space to store [NPM](https://www.npmjs.com/) packages. | 11.7+ |
| [NuGet Repository](nuget_repository/index.md) **(PREMIUM)** | *PLANNED* The GitLab NuGet Repository will enable every project in GitLab to have its own space to store [NuGet](https://www.nuget.org/) packages. | 12.8+ |
| [NuGet Repository](nuget_repository/index.md) **(PREMIUM)** | The GitLab NuGet Repository will enable every project in GitLab to have its own space to store [NuGet](https://www.nuget.org/) packages. | 12.8+ |
 
## Suggested contributions
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment