mirror of https://github.com/rancher/dashboard.git
Monitoring UI Polish - Overview & Create Route
rancher/dashboard#1986 update receiver tabs and labeled tooltips fix styling on receiver responder rows
This commit is contained in:
parent
a4aaf62034
commit
534e0a982b
|
|
@ -25,6 +25,7 @@
|
||||||
@import "./global/tooltip";
|
@import "./global/tooltip";
|
||||||
@import "./global/table";
|
@import "./global/table";
|
||||||
@import "./global/select";
|
@import "./global/select";
|
||||||
|
@import "./global/resource";
|
||||||
|
|
||||||
@import "./vendor/vue-select";
|
@import "./vendor/vue-select";
|
||||||
@import "./vendor/vue-js-modal";
|
@import "./vendor/vue-js-modal";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
.create-resource-container {
|
||||||
|
.subtypes-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.subtype-content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtype-banner {
|
||||||
|
border-left: 5px solid var(--primary);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
display: flex;
|
||||||
|
flex-basis: 40%;
|
||||||
|
margin: 10px;
|
||||||
|
min-height: 100px;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 0 0 20px var(--shadow);
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: not-allowed !important;
|
||||||
|
background-color: var(--disabled-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background-color: var(--accent-btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.top {
|
||||||
|
background-image: linear-gradient(
|
||||||
|
-90deg,
|
||||||
|
var(--body-bg),
|
||||||
|
var(--accent-btn)
|
||||||
|
);
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-right {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
color: var(--input-label);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.top) {
|
||||||
|
align-items: top;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: start;
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0px 0px 1px var(--outline-width) var(--outline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.round-image {
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 50px;
|
||||||
|
margin-right: 10px;
|
||||||
|
width: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner-abbrv {
|
||||||
|
align-items: center;
|
||||||
|
background-color: var(--primary);
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
font-size: 2.5em;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1119,6 +1119,32 @@ monitoring:
|
||||||
block: Block
|
block: Block
|
||||||
file: Filesystem
|
file: Filesystem
|
||||||
|
|
||||||
|
monitoringReceiver:
|
||||||
|
addButton: Add {type}
|
||||||
|
custom:
|
||||||
|
label: Custom
|
||||||
|
title: Custom Config
|
||||||
|
info: The YAML provided here will be directly appended to your receiver within the Alertmanager Config Secret.
|
||||||
|
email:
|
||||||
|
label: Email
|
||||||
|
title: Email Config
|
||||||
|
opsgenie:
|
||||||
|
label: Opsgenie
|
||||||
|
title: Opsgenie Config
|
||||||
|
pagerduty:
|
||||||
|
label: PagerDuty
|
||||||
|
title: PagerDuty Config
|
||||||
|
info: "You can find additional info on creating an Integration Key for PagerDuty <a href='https://www.pagerduty.com/docs/guides/prometheus-integration-guide/' target='_blank' rel='noopener nofollow' class='flex-right'>here</a>."
|
||||||
|
slack:
|
||||||
|
label: Slack
|
||||||
|
title: Slack Config
|
||||||
|
info: "You can find additional info on creating Incoming Webhooks for Slack <a href='https://rancher.slack.com/apps/A0F7XDUAZ-incoming-webhooks' target='_blank' rel='noopener noreferrer nofollow'>here</a> ."
|
||||||
|
webhook:
|
||||||
|
label: Webhook
|
||||||
|
title: Webhook Config
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
monitoringRoute:
|
monitoringRoute:
|
||||||
groups:
|
groups:
|
||||||
label: Group By
|
label: Group By
|
||||||
|
|
|
||||||
|
|
@ -359,7 +359,7 @@ export default {
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang='scss'>
|
<style lang='scss' scoped>
|
||||||
.cru-resource-yaml-container {
|
.cru-resource-yaml-container {
|
||||||
.resource-yaml {
|
.resource-yaml {
|
||||||
.yaml-editor {
|
.yaml-editor {
|
||||||
|
|
@ -367,96 +367,12 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.subtypes-container {
|
.create-resource-container {
|
||||||
display: flex;
|
.subtype-banner {
|
||||||
flex-wrap: wrap;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtype-content {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtype-banner {
|
|
||||||
border-left: 5px solid var(--primary);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
display: flex;
|
|
||||||
flex-basis: 40%;
|
|
||||||
margin: 10px;
|
|
||||||
min-height: 100px;
|
|
||||||
padding: 10px;
|
|
||||||
box-shadow: 0 0 20px var(--shadow);
|
|
||||||
|
|
||||||
&.selected {
|
|
||||||
background-color: var(--accent-btn);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.top {
|
|
||||||
background-image: linear-gradient(
|
|
||||||
-90deg,
|
|
||||||
var(--body-bg),
|
|
||||||
var(--accent-btn)
|
|
||||||
);
|
|
||||||
|
|
||||||
H2 {
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
// flex-basis: 10%;
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-right {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
color: var(--input-label);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
color: var(--input-label);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(.top) {
|
|
||||||
align-items: top;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: start;
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
box-shadow: 0px 0px 1px var(--outline-width) var(--outline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-image {
|
.round-image {
|
||||||
background-color: var(--primary);
|
background-color: var(--primary);
|
||||||
border-radius: 50%;
|
|
||||||
height: 50px;
|
|
||||||
margin-right: 10px;
|
|
||||||
width: 50px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner-abbrv {
|
|
||||||
align-items: center;
|
|
||||||
background-color: var(--primary);
|
|
||||||
color: white;
|
|
||||||
display: flex;
|
|
||||||
font-size: 2.5em;
|
|
||||||
height: 100%;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
tooltip: {
|
tooltip: {
|
||||||
type: String,
|
|
||||||
default: null,
|
default: null,
|
||||||
|
type: [String, Object]
|
||||||
},
|
},
|
||||||
|
|
||||||
hoverTooltip: {
|
hoverTooltip: {
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ export default {
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
default: null,
|
default: null,
|
||||||
type: String
|
type: [String, Object]
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
default: null,
|
default: null,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: String,
|
type: [String, Object],
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<div ref="container" class="labeled-tooltip" :class="{[status]: true, hoverable: hover}">
|
<div ref="container" class="labeled-tooltip" :class="{[status]: true, hoverable: hover}">
|
||||||
<template v-if="hover">
|
<template v-if="hover">
|
||||||
<i v-tooltip="{content: value, classes: [`tooltip-${status}`]}" :class="{'hover':!value}" class="icon icon-info status-icon" />
|
<i v-tooltip="value.content ? { ...{content: value.content, classes: [`tooltip-${status}`]}, ...value } : value" :class="{'hover':!value}" class="icon icon-info status-icon" />
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<i :class="{'hover':!value}" class="icon icon-info status-icon" />
|
<i :class="{'hover':!value}" class="icon icon-info status-icon" />
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ export default {
|
||||||
<img :src="receiverType.logo" />
|
<img :src="receiverType.logo" />
|
||||||
</div>
|
</div>
|
||||||
<h4 class="name ml-10">
|
<h4 class="name ml-10">
|
||||||
{{ receiverType.label }}
|
<t :k="receiverType.label" />
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="receiverType.name !== 'custom'" class="right">
|
<div v-if="receiverType.name !== 'custom'" class="right">
|
||||||
|
|
@ -175,14 +175,13 @@ export default {
|
||||||
</GradientBox>
|
</GradientBox>
|
||||||
</div>
|
</div>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab v-for="(receiverType, i) in receiverTypes" :key="i" :label="receiverType.label" :name="receiverType.name" :weight="receiverTypes.length - i">
|
<Tab
|
||||||
<Banner v-if="receiverType.name === 'slack'" color="info">
|
v-for="(receiverType, i) in receiverTypes"
|
||||||
Here's how you create <a href="https://rancher.slack.com/apps/A0F7XDUAZ-incoming-webhooks" target="_blank" rel="noopener noreferrer nofollow">Incoming Webhooks</a> for Slack.
|
:key="i"
|
||||||
</Banner>
|
:label="t(receiverType.label)"
|
||||||
<Banner v-if="!isView && receiverType.name === 'custom'" color="info" label="The YAML provided here will be directly appended to your receiver within the Alertmanager Config Secret" />
|
:name="receiverType.name"
|
||||||
<Banner v-if="!isView && receiverType.name === 'pagerduty'" color="info">
|
:weight="receiverTypes.length - i"
|
||||||
Here's how you create an <a href="https://www.pagerduty.com/docs/guides/prometheus-integration-guide/" target="_blank" rel="noopener nofollow" class="flex-right">Integration Key</a> for PagerDuty
|
>
|
||||||
</Banner>
|
|
||||||
<YamlEditor
|
<YamlEditor
|
||||||
v-if="receiverType.name === 'custom'"
|
v-if="receiverType.name === 'custom'"
|
||||||
ref="customEditor"
|
ref="customEditor"
|
||||||
|
|
@ -196,8 +195,7 @@ export default {
|
||||||
class="namespace-list"
|
class="namespace-list"
|
||||||
:mode="mode"
|
:mode="mode"
|
||||||
:default-add-value="{}"
|
:default-add-value="{}"
|
||||||
:disabled="disabled"
|
:add-label="t('monitoringReceiver.addButton', { type: t(receiverType.label) })"
|
||||||
:add-label="'Add ' + receiverType.label"
|
|
||||||
>
|
>
|
||||||
<template #default="props">
|
<template #default="props">
|
||||||
<div :class="{'pt-30': !isView}">
|
<div :class="{'pt-30': !isView}">
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import ArrayList from '@/components/form/ArrayList';
|
import ArrayList from '@/components/form/ArrayList';
|
||||||
import LabeledInput from '@/components/form/LabeledInput';
|
import LabeledInput from '@/components/form/LabeledInput';
|
||||||
import LabeledSelect from '@/components/form/LabeledSelect';
|
import Select from '@/components/form/Select';
|
||||||
import Checkbox from '@/components/form/Checkbox';
|
import Checkbox from '@/components/form/Checkbox';
|
||||||
import InputWithSelect from '@/components/form/InputWithSelect';
|
import InputWithSelect from '@/components/form/InputWithSelect';
|
||||||
import { _VIEW } from '@/config/query-params';
|
import { _VIEW } from '@/config/query-params';
|
||||||
|
|
@ -42,7 +42,7 @@ export const TYPES = [
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ArrayList, Checkbox, InputWithSelect, LabeledInput, LabeledSelect
|
ArrayList, Checkbox, InputWithSelect, LabeledInput, Select
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
mode: {
|
mode: {
|
||||||
|
|
@ -138,11 +138,11 @@ export default {
|
||||||
<h3>Responders</h3>
|
<h3>Responders</h3>
|
||||||
<ArrayList v-model="responders" :mode="mode" :default-add-value="defaultResponder" :show-header="true">
|
<ArrayList v-model="responders" :mode="mode" :default-add-value="defaultResponder" :show-header="true">
|
||||||
<template v-slot:column-headers>
|
<template v-slot:column-headers>
|
||||||
<div class="row" :class="{'mb-15': isView}">
|
<div class="row mb-10">
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<span class="text-label">Type</span>
|
<span class="text-label">Type</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col span-6">
|
<div class="col span-6 send-to">
|
||||||
<span class="text-label">Send To</span>
|
<span class="text-label">Send To</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -151,7 +151,7 @@ export default {
|
||||||
<div class="row responder">
|
<div class="row responder">
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<span v-if="isView">{{ typeLabel(scope.row.value.type) }}</span>
|
<span v-if="isView">{{ typeLabel(scope.row.value.type) }}</span>
|
||||||
<LabeledSelect v-else v-model="scope.row.value.type" :mode="mode" label="Type" :options="TYPES" />
|
<Select v-else v-model="scope.row.value.type" :mode="mode" label="Type" :options="TYPES" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-6 target">
|
<div class="col-span-6 target">
|
||||||
<span v-if="isView">{{ targetLabel(scope.row.value.target) }}: {{ scope.row.value.value }}</span>
|
<span v-if="isView">{{ targetLabel(scope.row.value.target) }}: {{ scope.row.value.value }}</span>
|
||||||
|
|
@ -177,6 +177,13 @@ export default {
|
||||||
&, .target {
|
&, .target {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
.send-to {
|
||||||
|
margin-left: -35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unlabeled-select ::v-deep {
|
||||||
|
height: $input-height;
|
||||||
|
}
|
||||||
|
|
||||||
.target ::v-deep {
|
.target ::v-deep {
|
||||||
& .input-container {
|
& .input-container {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@ import Checkbox from '@/components/form/Checkbox';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Checkbox, LabeledInput, LabeledSelect
|
Checkbox,
|
||||||
|
LabeledInput,
|
||||||
|
LabeledSelect,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
mode: {
|
mode: {
|
||||||
|
|
@ -14,8 +16,8 @@ export default {
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
this.$set(this.value, 'http_config', this.value.http_config || {});
|
this.$set(this.value, 'http_config', this.value.http_config || {});
|
||||||
|
|
@ -23,7 +25,7 @@ export default {
|
||||||
|
|
||||||
const integrationMapping = {
|
const integrationMapping = {
|
||||||
'Events API v2': 'routing_key',
|
'Events API v2': 'routing_key',
|
||||||
Prometheus: 'service_key'
|
Prometheus: 'service_key',
|
||||||
};
|
};
|
||||||
|
|
||||||
const integrationTypeOptions = Object.keys(integrationMapping);
|
const integrationTypeOptions = Object.keys(integrationMapping);
|
||||||
|
|
@ -39,8 +41,8 @@ export default {
|
||||||
this.integrationTypeOptions.forEach((option) => {
|
this.integrationTypeOptions.forEach((option) => {
|
||||||
this.value[this.integrationMapping[option]] = null;
|
this.value[this.integrationMapping[option]] = null;
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -48,19 +50,39 @@ export default {
|
||||||
<div>
|
<div>
|
||||||
<div class="row mb-20">
|
<div class="row mb-20">
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<LabeledSelect v-model="integrationType" :options="integrationTypeOptions" :mode="mode" label="Integration Type" />
|
<LabeledSelect
|
||||||
|
v-model="integrationType"
|
||||||
|
:options="integrationTypeOptions"
|
||||||
|
:mode="mode"
|
||||||
|
:tooltip="{ content: t('monitoringReceiver.pagerduty.info', {}, raw=true), autoHide: false}"
|
||||||
|
:hover-tooltip="true"
|
||||||
|
label="Integration Type"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<LabeledInput v-model="value[integrationMapping[integrationType]]" :mode="mode" label="Default Integration Key" />
|
<LabeledInput
|
||||||
|
v-model="value[integrationMapping[integrationType]]"
|
||||||
|
:mode="mode"
|
||||||
|
label="Default Integration Key"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-20">
|
<div class="row mb-20">
|
||||||
<div class="col span-12">
|
<div class="col span-12">
|
||||||
<LabeledInput v-model="value.http_config.proxy_url" :mode="mode" label="Proxy URL" placeholder="e.g. http://my-proxy/" />
|
<LabeledInput
|
||||||
|
v-model="value.http_config.proxy_url"
|
||||||
|
:mode="mode"
|
||||||
|
label="Proxy URL"
|
||||||
|
placeholder="e.g. http://my-proxy/"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<Checkbox v-model="value.send_resolved" :mode="mode" label="Enable send resolved alerts" />
|
<Checkbox
|
||||||
|
v-model="value.send_resolved"
|
||||||
|
:mode="mode"
|
||||||
|
label="Enable send resolved alerts"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,19 @@ export default {
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
this.$set(this.value, 'http_config', this.value.http_config || {});
|
this.$set(this.value, 'http_config', this.value.http_config || {});
|
||||||
this.$set(this.value, 'send_resolved', this.value.send_resolved || false);
|
this.$set(this.value, 'send_resolved', this.value.send_resolved || false);
|
||||||
|
|
||||||
if (this.mode === _CREATE) {
|
if (this.mode === _CREATE) {
|
||||||
this.$set(this.value, 'text', this.value.text || '{{ template "slack.rancher.text" . }}');
|
this.$set(
|
||||||
|
this.value,
|
||||||
|
'text',
|
||||||
|
this.value.text || '{{ template "slack.rancher.text" . }}'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -32,19 +36,39 @@ export default {
|
||||||
<div>
|
<div>
|
||||||
<div class="row mb-20">
|
<div class="row mb-20">
|
||||||
<div class="col span-12">
|
<div class="col span-12">
|
||||||
<LabeledInput v-model="value.api_url" :mode="mode" label="URL" placeholder="e.g. https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX" />
|
<LabeledInput
|
||||||
|
v-model="value.api_url"
|
||||||
|
:mode="mode"
|
||||||
|
label="Webhook URL"
|
||||||
|
:tooltip="{ content: t('monitoringReceiver.slack.info', {}, raw=true), autoHide: false}"
|
||||||
|
placeholder="e.g. https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-20">
|
<div class="row mb-20">
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<LabeledInput v-model="value.channel" :mode="mode" label="Default Channel" placeholder="e.g. #example" />
|
<LabeledInput
|
||||||
|
v-model="value.channel"
|
||||||
|
:mode="mode"
|
||||||
|
label="Default Channel"
|
||||||
|
placeholder="e.g. #example"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col span-6">
|
<div class="col span-6">
|
||||||
<LabeledInput v-model="value.http_config.proxy_url" :mode="mode" label="Proxy URL" placeholder="e.g. http://my-proxy/" />
|
<LabeledInput
|
||||||
|
v-model="value.http_config.proxy_url"
|
||||||
|
:mode="mode"
|
||||||
|
label="Proxy URL"
|
||||||
|
placeholder="e.g. http://my-proxy/"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<Checkbox v-model="value.send_resolved" :mode="mode" label="Enable send resolved alerts" />
|
<Checkbox
|
||||||
|
v-model="value.send_resolved"
|
||||||
|
:mode="mode"
|
||||||
|
label="Enable send resolved alerts"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -6,43 +6,46 @@ import jsyaml from 'js-yaml';
|
||||||
export const RECEIVERS_TYPES = [
|
export const RECEIVERS_TYPES = [
|
||||||
{
|
{
|
||||||
name: 'slack',
|
name: 'slack',
|
||||||
label: 'Slack',
|
label: 'monitoringReceiver.slack.label',
|
||||||
title: 'Slack Config',
|
title: 'monitoringReceiver.slack.title',
|
||||||
|
info: 'monitoringReceiver.slack.info',
|
||||||
key: 'slack_configs',
|
key: 'slack_configs',
|
||||||
logo: require(`~/assets/images/vendor/slack.svg`)
|
logo: require(`~/assets/images/vendor/slack.svg`)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'email',
|
name: 'email',
|
||||||
label: 'Email',
|
label: 'monitoringReceiver.email.label',
|
||||||
title: 'Email Config',
|
title: 'monitoringReceiver.email.title',
|
||||||
key: 'email_configs',
|
key: 'email_configs',
|
||||||
logo: require(`~/assets/images/vendor/email.svg`)
|
logo: require(`~/assets/images/vendor/email.svg`)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'pagerduty',
|
name: 'pagerduty',
|
||||||
label: 'PagerDuty',
|
label: 'monitoringReceiver.pagerduty.label',
|
||||||
title: 'PagerDuty Config',
|
title: 'monitoringReceiver.pagerduty.title',
|
||||||
|
info: 'monitoringReceiver.pagerduty.info',
|
||||||
key: 'pagerduty_configs',
|
key: 'pagerduty_configs',
|
||||||
logo: require(`~/assets/images/vendor/pagerduty.svg`)
|
logo: require(`~/assets/images/vendor/pagerduty.svg`)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'opsgenie',
|
name: 'opsgenie',
|
||||||
label: 'Opsgenie',
|
label: 'monitoringReceiver.opsgenie.label',
|
||||||
title: 'Opsgenie Config',
|
title: 'monitoringReceiver.opsgenie.title',
|
||||||
key: 'opsgenie_configs',
|
key: 'opsgenie_configs',
|
||||||
logo: require(`~/assets/images/vendor/email.svg`)
|
logo: require(`~/assets/images/vendor/email.svg`)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'webhook',
|
name: 'webhook',
|
||||||
label: 'Webhook',
|
label: 'monitoringReceiver.webhook.label',
|
||||||
title: 'Webhook Config',
|
title: 'monitoringReceiver.webhook.title',
|
||||||
key: 'webhook_configs',
|
key: 'webhook_configs',
|
||||||
logo: require(`~/assets/images/vendor/webhook.svg`)
|
logo: require(`~/assets/images/vendor/webhook.svg`)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'custom',
|
name: 'custom',
|
||||||
label: 'Custom',
|
label: 'monitoringReceiver.custom.label',
|
||||||
title: 'Custom Config',
|
title: 'monitoringReceiver.custom.title',
|
||||||
|
info: 'monitoringReceiver.custom.info',
|
||||||
key: 'webhook_configs',
|
key: 'webhook_configs',
|
||||||
logo: require(`~/assets/images/vendor/custom.svg`)
|
logo: require(`~/assets/images/vendor/custom.svg`)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,8 @@ export default {
|
||||||
group: 'prometheus',
|
group: 'prometheus',
|
||||||
iconSrc: this.prometheusSrc,
|
iconSrc: this.prometheusSrc,
|
||||||
label: 'monitoring.overview.linkedList.prometheusPromQl.label',
|
label: 'monitoring.overview.linkedList.prometheusPromQl.label',
|
||||||
description: 'monitoring.overview.linkedList.prometheusPromQl.description',
|
description:
|
||||||
|
'monitoring.overview.linkedList.prometheusPromQl.description',
|
||||||
link: `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-prometheus:9090/proxy/graph`,
|
link: `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-prometheus:9090/proxy/graph`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -67,7 +68,8 @@ export default {
|
||||||
group: 'prometheus',
|
group: 'prometheus',
|
||||||
iconSrc: this.prometheusSrc,
|
iconSrc: this.prometheusSrc,
|
||||||
label: 'monitoring.overview.linkedList.prometheusRules.label',
|
label: 'monitoring.overview.linkedList.prometheusRules.label',
|
||||||
description: 'monitoring.overview.linkedList.prometheusRules.description',
|
description:
|
||||||
|
'monitoring.overview.linkedList.prometheusRules.description',
|
||||||
link: `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-prometheus:9090/proxy/rules`,
|
link: `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-prometheus:9090/proxy/rules`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -75,7 +77,8 @@ export default {
|
||||||
group: 'prometheus',
|
group: 'prometheus',
|
||||||
iconSrc: this.prometheusSrc,
|
iconSrc: this.prometheusSrc,
|
||||||
label: 'monitoring.overview.linkedList.prometheusTargets.label',
|
label: 'monitoring.overview.linkedList.prometheusTargets.label',
|
||||||
description: 'monitoring.overview.linkedList.prometheusTargets.description',
|
description:
|
||||||
|
'monitoring.overview.linkedList.prometheusTargets.description',
|
||||||
link: `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-prometheus:9090/proxy/targets`,
|
link: `/k8s/clusters/${ this.currentCluster.id }/api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-prometheus:9090/proxy/targets`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -87,13 +90,17 @@ export default {
|
||||||
async fetchDeps() {
|
async fetchDeps() {
|
||||||
const { $store, externalLinks } = this;
|
const { $store, externalLinks } = this;
|
||||||
|
|
||||||
const workloads = await Promise.all(Object.values(WORKLOAD_TYPES).map(type => this.$store.dispatch('cluster/findAll', { type })));
|
const workloads = await Promise.all(
|
||||||
|
Object.values(WORKLOAD_TYPES).map(type => this.$store.dispatch('cluster/findAll', { type })
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
workloads.flat().forEach((workload) => {
|
workloads.flat().forEach((workload) => {
|
||||||
if (
|
if (
|
||||||
!isEmpty(workload?.spec?.template?.spec?.containers) &&
|
!isEmpty(workload?.spec?.template?.spec?.containers) &&
|
||||||
(workload.spec.template.spec.containers.find(c => c.image.includes('quay.io/coreos/prometheus-operator') ||
|
workload.spec.template.spec.containers.find(
|
||||||
c.image.includes('rancher/coreos-prometheus-operator'))
|
c => c.image.includes('quay.io/coreos/prometheus-operator') ||
|
||||||
|
c.image.includes('rancher/coreos-prometheus-operator')
|
||||||
) &&
|
) &&
|
||||||
workload?.metadata?.namespace !== CATTLE_MONITORING_NAMESPACE
|
workload?.metadata?.namespace !== CATTLE_MONITORING_NAMESPACE
|
||||||
) {
|
) {
|
||||||
|
|
@ -108,10 +115,24 @@ export default {
|
||||||
if (!isEmpty(hash.endpoints)) {
|
if (!isEmpty(hash.endpoints)) {
|
||||||
const amMatch = findBy(externalLinks, 'group', 'alertmanager');
|
const amMatch = findBy(externalLinks, 'group', 'alertmanager');
|
||||||
const grafanaMatch = findBy(externalLinks, 'group', 'grafana');
|
const grafanaMatch = findBy(externalLinks, 'group', 'grafana');
|
||||||
const promeMatch = externalLinks.filter(el => el.group === 'prometheus');
|
const promeMatch = externalLinks.filter(
|
||||||
const alertmanager = findBy(hash.endpoints, 'id', `${ CATTLE_MONITORING_NAMESPACE }/rancher-monitoring-alertmanager`);
|
el => el.group === 'prometheus'
|
||||||
const grafana = findBy(hash.endpoints, 'id', `${ CATTLE_MONITORING_NAMESPACE }/rancher-monitoring-grafana`);
|
);
|
||||||
const prometheus = findBy(hash.endpoints, 'id', `${ CATTLE_MONITORING_NAMESPACE }/rancher-monitoring-prometheus`);
|
const alertmanager = findBy(
|
||||||
|
hash.endpoints,
|
||||||
|
'id',
|
||||||
|
`${ CATTLE_MONITORING_NAMESPACE }/rancher-monitoring-alertmanager`
|
||||||
|
);
|
||||||
|
const grafana = findBy(
|
||||||
|
hash.endpoints,
|
||||||
|
'id',
|
||||||
|
`${ CATTLE_MONITORING_NAMESPACE }/rancher-monitoring-grafana`
|
||||||
|
);
|
||||||
|
const prometheus = findBy(
|
||||||
|
hash.endpoints,
|
||||||
|
'id',
|
||||||
|
`${ CATTLE_MONITORING_NAMESPACE }/rancher-monitoring-prometheus`
|
||||||
|
);
|
||||||
|
|
||||||
if (!isEmpty(alertmanager) && !isEmpty(alertmanager.subsets)) {
|
if (!isEmpty(alertmanager) && !isEmpty(alertmanager.subsets)) {
|
||||||
amMatch.enabled = true;
|
amMatch.enabled = true;
|
||||||
|
|
@ -126,7 +147,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -142,112 +163,48 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="links">
|
<div>
|
||||||
<Banner v-if="v1Installed" color="warning">
|
<Banner v-if="v1Installed" color="warning">
|
||||||
<template #default>
|
<template #default>
|
||||||
<t k="monitoring.v1Warning" :raw="true" />
|
<t k="monitoring.v1Warning" :raw="true" />
|
||||||
</template>
|
</template>
|
||||||
</Banner>
|
</Banner>
|
||||||
<div v-for="fel in externalLinks" :key="fel.label" class="link-container">
|
<div class="create-resource-container">
|
||||||
<a v-if="fel.enabled" :href="fel.link" target="_blank" rel="noopener noreferrer">
|
<div class="subtypes-container">
|
||||||
<div class="link-logo">
|
<a
|
||||||
|
v-for="fel in externalLinks"
|
||||||
|
:key="fel.label"
|
||||||
|
v-tooltip="!fel.enabled ? t('monitoring.overview.linkedList.na') : undefined"
|
||||||
|
:href="fel.enabled ? fel.link : (void 0)"
|
||||||
|
:disabled="!fel.enabled"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
:class="{ 'subtype-banner': true, disabled: !fel.enabled}"
|
||||||
|
>
|
||||||
|
<div class="subtype-content">
|
||||||
|
<div class="title">
|
||||||
|
<div class="subtype-logo round-image">
|
||||||
<LazyImage :src="fel.iconSrc" />
|
<LazyImage :src="fel.iconSrc" />
|
||||||
</div>
|
</div>
|
||||||
<div class="link-content">
|
<h5>
|
||||||
|
<span>
|
||||||
<t :k="fel.label" />
|
<t :k="fel.label" />
|
||||||
<i class="icon icon-external-link pull-right" />
|
</span>
|
||||||
|
</h5>
|
||||||
|
<div class="flex-right">
|
||||||
|
<i class="icon icon-external-link" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<div class="description"><t :k="fel.description" /></div>
|
<div class="description">
|
||||||
|
<span>
|
||||||
|
<t :k="fel.description" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a v-else v-tooltip="t('monitoring.overview.linkedList.na')" href="javascript:void(0)" :disabled="!fel.enabled">
|
|
||||||
<div class="link-logo">
|
|
||||||
<LazyImage :src="fel.iconSrc" />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="link-content">
|
|
||||||
<t :k="fel.label" />
|
|
||||||
<i class="icon icon-external-link pull-right" />
|
|
||||||
<hr />
|
|
||||||
<div class="description"><t :k="fel.description" /></div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.links {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.link-container {
|
|
||||||
background-color: var(--input-bg);
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
border: solid 1px var(--input-border);
|
|
||||||
display: flex;
|
|
||||||
flex-basis: 40%;
|
|
||||||
margin: 0 10px 10px 0;
|
|
||||||
max-width: 325px;
|
|
||||||
min-height: 100px;
|
|
||||||
border-left: solid 10px var(--primary);
|
|
||||||
|
|
||||||
a[disabled] {
|
|
||||||
cursor: not-allowed;
|
|
||||||
background-color: var(---disabled-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0px 0px 1px var(--outline-width) var(--outline);
|
|
||||||
}
|
|
||||||
|
|
||||||
> a {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
flex: 1 0;
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
.link-logo,
|
|
||||||
.link-content {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-logo {
|
|
||||||
text-align: center;
|
|
||||||
// position: absolute;
|
|
||||||
// left: 25px;
|
|
||||||
// top: 25px;
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
border-radius: calc(2 * var(--border-radius));
|
|
||||||
background-color: white;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 56px;
|
|
||||||
height: 56px;
|
|
||||||
-o-object-fit: contain;
|
|
||||||
object-fit: contain;
|
|
||||||
position: relative;
|
|
||||||
top: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.link-content {
|
|
||||||
width: 100%;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
margin-top: 10px;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 3;
|
|
||||||
line-clamp: 3;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
color: var(--secondary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue