dashboard/edit/networking.k8s.io.ingress/index.vue

156 lines
4.5 KiB
Vue

<script>
import { allHash } from '@/utils/promise';
import { SECRET, SERVICE } from '@/config/types';
import NameNsDescription from '@/components/form/NameNsDescription';
import CreateEditView from '@/mixins/create-edit-view';
import Tab from '@/components/Tabbed/Tab';
import CruResource from '@/components/CruResource';
import Labels from '@/components/form/Labels';
import Tabbed from '@/components/Tabbed';
import { get, set } from '@/utils/object';
import { TYPES } from '@/models/secret.class';
import DefaultBackend from './DefaultBackend';
import Certificates from './Certificates';
import Rules from './Rules';
export default {
name: 'CRUIngress',
components: {
Certificates,
CruResource,
DefaultBackend,
Labels,
NameNsDescription,
Rules,
Tab,
Tabbed
},
mixins: [CreateEditView],
props: {
value: {
type: Object,
default: () => {
return {};
}
},
mode: {
type: String,
default: 'edit'
}
},
async fetch() {
const hash = await allHash({
secrets: this.$store.dispatch('cluster/findAll', { type: SECRET }),
services: this.$store.dispatch('cluster/findAll', { type: SERVICE }),
});
this.allServices = hash.services;
this.allSecrets = hash.secrets;
},
data() {
return { allSecrets: [], allServices: [] };
},
computed: {
serviceTargets() {
return this.filterByCurrentResourceNamespace(this.allServices)
.map(service => ({
label: service.metadata.name,
value: service.metadata.name,
ports: service.spec.ports?.map(p => p.port)
}));
},
firstTabLabel() {
return this.isView ? this.t('ingress.rulesAndCertificates.title') : this.t('ingress.rules.title');
},
certificates() {
return this.filterByNamespace(this.allSecrets.filter(secret => secret._type === TYPES.TLS)).map((secret) => {
const { id } = secret;
return id.slice(id.indexOf('/') + 1);
});
},
},
created() {
this.$set(this.value, 'spec', this.value.spec || {});
this.$set(this.value.spec, 'rules', this.value.spec.rules || [{}]);
this.$set(this.value.spec, 'backend', this.value.spec.backend || {});
if (!this.value.spec.tls || Object.keys(this.value.spec.tls[0] || {}).length === 0) {
this.$set(this.value.spec, 'tls', []);
}
this.registerBeforeHook(this.willSave, 'willSave');
},
methods: {
filterByCurrentResourceNamespace(resources) {
return resources.filter((resource) => {
return resource.metadata.namespace === this.value.metadata.namespace;
});
},
willSave() {
const backend = get(this.value.spec, this.value.defaultBackendPath);
const serviceName = get(backend, this.value.serviceNamePath);
const servicePort = get(backend, this.value.servicePortPath);
if (backend && (!serviceName || !servicePort)) {
const path = this.value.defaultBackendPath;
set(this.value.spec, path, null);
}
},
filterByNamespace(list) {
const namespaces = this.$store.getters['namespaces']();
return list.filter((resource) => {
return !!namespaces[resource.metadata.namespace];
});
},
}
};
</script>
<template>
<CruResource
:done-route="doneRoute"
:mode="mode"
:resource="value"
:subtypes="[]"
:validation-passed="true"
:errors="errors"
@error="e=>errors = e"
@finish="save"
@cancel="done"
>
<NameNsDescription
v-if="!isView"
:value="value"
:mode="mode"
:register-before-hook="registerBeforeHook"
/>
<Tabbed :side-tabs="true">
<Tab :label="firstTabLabel" name="rules" :weight="3">
<Rules v-model="value" :mode="mode" :service-targets="serviceTargets" :certificates="certificates" />
</Tab>
<Tab :label="t('ingress.defaultBackend.label')" name="default-backend" :weight="2">
<DefaultBackend v-model="value" :service-targets="serviceTargets" :mode="mode" />
</Tab>
<Tab v-if="!isView" :label="t('ingress.certificates.label')" name="certificates" :weight="1">
<Certificates v-model="value" :mode="mode" :certificates="certificates" />
</Tab>
<Tab
v-if="!isView"
name="labels-and-annotations"
label-key="generic.labelsAndAnnotations"
:weight="0"
>
<Labels
default-container-class="labels-and-annotations-container"
:value="value"
:mode="mode"
:display-side-by-side="false"
/>
</Tab>
</Tabbed>
</CruResource>
</template>