mirror of https://github.com/rancher/dashboard.git
281 lines
8.8 KiB
Vue
281 lines
8.8 KiB
Vue
<script>
|
|
import CruResource from '@shell/components/CruResource';
|
|
|
|
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
import Tabbed from '@shell/components/Tabbed';
|
|
import Tab from '@shell/components/Tabbed/Tab';
|
|
import { MONITORING } from '@shell/config/types';
|
|
import Loading from '@shell/components/Loading';
|
|
import NameNsDescription from '@shell/components/form/NameNsDescription';
|
|
import { EDITOR_MODES } from '@shell/components/YamlEditor';
|
|
import { RECEIVERS_TYPES } from '@shell/models/monitoring.coreos.com.receiver';
|
|
import RouteConfig from './routeConfig';
|
|
import ResourceTable from '@shell/components/ResourceTable';
|
|
import ActionMenu from '@shell/components/ActionMenu';
|
|
import { _CREATE, _EDIT, _VIEW, _CONFIG } from '@shell/config/query-params';
|
|
|
|
export default {
|
|
components: {
|
|
ActionMenu,
|
|
CruResource,
|
|
Loading,
|
|
NameNsDescription,
|
|
ResourceTable,
|
|
RouteConfig,
|
|
Tab,
|
|
Tabbed,
|
|
},
|
|
|
|
mixins: [CreateEditView],
|
|
|
|
async fetch() {
|
|
const inStore = this.$store.getters['currentProduct'].inStore;
|
|
const alertmanagerConfigId = this.value.id;
|
|
|
|
const alertmanagerConfigResource = await this.$store.dispatch(`${ inStore }/find`, { type: MONITORING.ALERTMANAGERCONFIG, id: alertmanagerConfigId });
|
|
|
|
this.alertmanagerConfigId = alertmanagerConfigId;
|
|
this.alertmanagerConfigResource = alertmanagerConfigResource;
|
|
this.alertmanagerConfigDetailRoute = alertmanagerConfigResource._detailLocation;
|
|
|
|
const alertmanagerConfigActions = alertmanagerConfigResource.availableActions;
|
|
const receiverActions = alertmanagerConfigResource.getReceiverActions(alertmanagerConfigActions);
|
|
|
|
this.receiverActions = receiverActions;
|
|
},
|
|
|
|
data() {
|
|
this.value.applyDefaults();
|
|
|
|
const defaultReceiverValues = {};
|
|
const receiverSchema = this.$store.getters['cluster/schemaFor'](MONITORING.SPOOFED.ALERTMANAGERCONFIG_RECEIVER_SPEC);
|
|
const routeSchema = this.$store.getters['cluster/schemaFor'](MONITORING.SPOOFED.ALERTMANAGERCONFIG_ROUTE_SPEC);
|
|
const receiverOptions = (this.value?.spec?.receivers || []).map((receiver) => receiver.name);
|
|
|
|
return {
|
|
actionMenuTargetElement: null,
|
|
actionMenuTargetEvent: null,
|
|
config: _CONFIG,
|
|
create: _CREATE,
|
|
createReceiverLink: this.value.getCreateReceiverRoute(),
|
|
defaultReceiverValues,
|
|
receiverActionMenuIsOpen: false,
|
|
receiverTableHeaders: [
|
|
{
|
|
name: 'name',
|
|
labelKey: 'tableHeaders.name',
|
|
value: 'name',
|
|
sort: ['nameSort'],
|
|
formatter: 'LinkDetail',
|
|
canBeVariable: true,
|
|
},
|
|
{
|
|
name: 'type',
|
|
labelKey: 'tableHeaders.type',
|
|
value: 'name',
|
|
formatter: 'ReceiverIcons',
|
|
canBeVariable: true,
|
|
}
|
|
// Add more columns
|
|
],
|
|
newReceiverType: null,
|
|
receiverActions: [],
|
|
receiverOptions,
|
|
receiverTypes: RECEIVERS_TYPES,
|
|
routeSchema,
|
|
receiverSchema,
|
|
selectedReceiverName: '',
|
|
selectedRowValue: null,
|
|
view: _VIEW,
|
|
};
|
|
},
|
|
|
|
computed: {
|
|
|
|
editorMode() {
|
|
if ( this.mode === _VIEW ) {
|
|
return EDITOR_MODES.VIEW_CODE;
|
|
}
|
|
|
|
return EDITOR_MODES.EDIT_CODE;
|
|
},
|
|
},
|
|
methods: {
|
|
|
|
translateReceiverTypes() {
|
|
return this.receiverTypes.map((receiverType) => {
|
|
return {
|
|
...receiverType,
|
|
label: this.t(receiverType.label)
|
|
};
|
|
});
|
|
},
|
|
getReceiverDetailLink(receiverData) {
|
|
if (receiverData && receiverData.name) {
|
|
return this.value.getReceiverDetailLink(receiverData.name);
|
|
}
|
|
},
|
|
|
|
toggleReceiverActionMenu() {
|
|
this.receiverActionMenuIsOpen = true;
|
|
},
|
|
setActionMenuState(eventData) {
|
|
// This method is called when the user clicks a context menu
|
|
// for a receiver in the receiver in the receiver list view.
|
|
// It sets the target element so the menu can open where the
|
|
// user clicked.
|
|
const { event, targetElement } = eventData;
|
|
|
|
// TargetElement could be an array of more than
|
|
// one if there is more than one ref of the same name.
|
|
if (event && targetElement) {
|
|
this.actionMenuTargetElement = targetElement;
|
|
this.actionMenuTargetEvent = event;
|
|
|
|
// We take the selected receiver name out of the target
|
|
// element's ID to help us build the URL to link to
|
|
// the detail page of that receiver.
|
|
// We use a plus sign as the delimiter to separate the
|
|
// name because the plus is not an allowed character in
|
|
// Kubernetes names.
|
|
this.selectedReceiverName = targetElement.id.split('+').slice(2).join('');
|
|
|
|
this.toggleReceiverActionMenu();
|
|
} else {
|
|
throw new Error('Could not find action menu target element.');
|
|
}
|
|
},
|
|
goToEdit() {
|
|
// 'goToEdit' is the exact name of an action for AlertmanagerConfig
|
|
// and this method executes the action.
|
|
this.$router.push(this.alertmanagerConfigResource.getEditReceiverConfigRoute(this.selectedReceiverName, _EDIT));
|
|
},
|
|
|
|
goToEditYaml() {
|
|
// 'goToEditYaml' is the exact name of an action for AlertmanagerConfig
|
|
// and this method executes the action.
|
|
this.$router.push(this.alertmanagerConfigResource.getEditReceiverYamlRoute(this.selectedReceiverName, _EDIT));
|
|
},
|
|
promptRemove() {
|
|
// 'promptRemove' is the exact name of an action for AlertmanagerConfig
|
|
// and this method executes the action.
|
|
// Get the name of the receiver to delete from the action info.
|
|
const nameOfReceiverToDelete = this.selectedReceiverName;
|
|
// Remove it from the configuration of the parent AlertmanagerConfig
|
|
// resource.
|
|
const existingReceivers = this.alertmanagerConfigResource.spec.receivers || [];
|
|
const receiversMinusDeletedItem = existingReceivers.filter((receiver) => {
|
|
return receiver.name !== nameOfReceiverToDelete;
|
|
});
|
|
|
|
this.alertmanagerConfigResource.spec.receivers = receiversMinusDeletedItem;
|
|
// After saving the AlertmanagerConfig, the resource has been deleted.
|
|
this.alertmanagerConfigResource.save(...arguments);
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<Loading v-if="$fetchState.pending" />
|
|
<CruResource
|
|
v-else
|
|
class="route"
|
|
:done-route="doneRoute"
|
|
:errors="errors"
|
|
:mode="mode"
|
|
:resource="value"
|
|
:subtypes="[]"
|
|
:cancel-event="true"
|
|
@error="e=>errors = e"
|
|
@finish="save"
|
|
@cancel="done"
|
|
>
|
|
<NameNsDescription
|
|
v-model="value"
|
|
:mode="mode"
|
|
:namespaced="isNamespaced"
|
|
/>
|
|
|
|
<Tabbed>
|
|
<Tab
|
|
:label="t('monitoring.route.label')"
|
|
:weight="1"
|
|
name="route"
|
|
>
|
|
<RouteConfig
|
|
:value="value.spec.route"
|
|
:mode="mode"
|
|
:receiver-options="receiverOptions"
|
|
/>
|
|
</Tab>
|
|
<Tab
|
|
:label="t('alertmanagerConfigReceiver.receivers')"
|
|
:weight="2"
|
|
name="receivers"
|
|
>
|
|
<ResourceTable
|
|
:headers="receiverTableHeaders"
|
|
:schema="receiverSchema"
|
|
:rows="value.spec.receivers || []"
|
|
:get-custom-detail-link="getReceiverDetailLink"
|
|
:table-actions="false"
|
|
:custom-actions="value.receiverActions"
|
|
@clickedActionButton="setActionMenuState"
|
|
>
|
|
<template #header-button>
|
|
<nuxt-link
|
|
v-if="createReceiverLink && createReceiverLink.name"
|
|
:to="mode !== create ? createReceiverLink : {}"
|
|
>
|
|
<button
|
|
class="btn role-primary"
|
|
:disabled="mode === create"
|
|
:tooltip="t('monitoring.alertmanagerConfig.disabledReceiverButton')"
|
|
>
|
|
{{ t('monitoring.receiver.addReceiver') }}
|
|
<i
|
|
v-if="mode === create"
|
|
v-clean-tooltip="t('monitoring.alertmanagerConfig.disabledReceiverButton')"
|
|
class="icon icon-info"
|
|
/>
|
|
</button>
|
|
</nuxt-link>
|
|
</template>
|
|
</ResourceTable>
|
|
</Tab>
|
|
</Tabbed>
|
|
<ActionMenu
|
|
:custom-actions="receiverActions"
|
|
:open="receiverActionMenuIsOpen"
|
|
:use-custom-target-element="true"
|
|
:custom-target-element="actionMenuTargetElement"
|
|
:custom-target-event="actionMenuTargetEvent"
|
|
@close="receiverActionMenuIsOpen = false"
|
|
@goToEdit="goToEdit"
|
|
@goToEditYaml="goToEditYaml"
|
|
@promptRemove="promptRemove"
|
|
/>
|
|
</CruResource>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
h3 {
|
|
margin-top: 2em;
|
|
}
|
|
input {
|
|
margin-top: 1em;
|
|
}
|
|
.route {
|
|
&[real-mode=view] .label {
|
|
color: var(--input-label);
|
|
}
|
|
}
|
|
button {
|
|
margin-left: 0.5em;
|
|
}
|
|
a:hover {
|
|
text-decoration: none;
|
|
}
|
|
</style>
|