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

222 lines
5.4 KiB
Vue

<script>
import Certificate from './Certificate';
import Rule from './Rule';
import { allHash } from '@/utils/promise';
import { SECRET, TLS_CERT, WORKLOAD_TYPES } from '@/config/types';
import NameNsDescription from '@/components/form/NameNsDescription';
import CreateEditView from '@/mixins/create-edit-view';
import LoadDeps from '@/mixins/load-deps';
import Tabbed from '@/components/Tabbed';
import Tab from '@/components/Tabbed/Tab';
import Labels from '@/components/form/Labels';
import Footer from '@/components/form/Footer';
export default {
name: 'CRUIngress',
components: {
NameNsDescription,
Rule,
Tabbed,
Tab,
Labels,
Certificate,
Footer
},
mixins: [CreateEditView, LoadDeps],
props: {
value: {
type: Object,
default: () => {
return {};
}
},
mode: {
type: String,
default: 'edit'
}
},
data() {
return { allSecrets: [], allWorkloads: [] };
},
computed: {
workloads() {
return this.filterByNamespace(this.filterByOwner(this.allWorkloads)).reduce((all, workload) => {
all.push(workload?.metadata?.name);
return all;
}, []);
},
certificates() {
return this.filterByNamespace(this.allSecrets.filter(secret => secret._type === TLS_CERT)).map((secret) => {
const { id } = secret;
return id.slice(id.indexOf('/') + 1);
});
},
},
created() {
if (!this.value.spec) {
this.value.spec = {};
}
if (!this.value.spec.rules) {
this.value.spec.rules = [{}];
}
if (this.value.spec.backend) {
if (!this.value.spec.rules[0].http) {
this.value.spec.rules[0].http = { paths: [] };
}
this.value.spec.rules[0].http.paths.push({ backend: this.value.spec.backend });
this.value.spec.rules[0].asDefault = true;
}
if (!this.value.spec.tls) {
this.value.spec.tls = [{ }];
}
this.registerBeforeHook(this.willSave, 'willSave');
},
methods: {
async loadDeps() {
const hash = await allHash({
secrets: this.$store.dispatch('cluster/findAll', { type: SECRET }),
...Object.values(WORKLOAD_TYPES).reduce((all, type) => {
all[type] = this.$store.dispatch('cluster/findAll', { type });
return all;
}, {})
});
const workloads = Object.values(WORKLOAD_TYPES).map(type => hash[type]);
const flattened = workloads.reduce((all, type) => {
all.push(...type);
return all;
}, []);
this.allSecrets = hash.secrets;
this.allWorkloads = flattened;
},
addRule() {
this.value.spec.rules = [...this.value.spec.rules, {}];
},
removeRule(idx) {
const neu = [...this.value.spec.rules];
neu.splice(idx, 1);
this.$set(this.value.spec, 'rules', neu);
},
updateRule(neu, idx) {
this.$set(this.value.spec.rules, idx, neu);
},
addCert() {
this.value.spec.tls = [...this.value.spec.tls, {}];
},
removeCert(idx) {
const neu = [...this.value.spec.tls];
neu.splice(idx, 1);
this.$set(this.value.spec, 'tls', neu);
},
// filter a given list of resources by currently selected namespaces
filterByNamespace(list) {
const namespaces = this.$store.getters['namespaces']();
return list.filter((resource) => {
return !!namespaces[resource.metadata.namespace];
});
},
// filter by ownerReference id OR filter by lack of owner
filterByOwner(list, id) {
return list.filter((resource) => {
const owners = resource.metadata.ownerReferences;
if (!id) {
return !owners;
}
const owner = owners[0] || {};
return (owner.name === id);
});
},
willSave() {
const defaultRule = this.value.spec.rules.filter(rule => rule.asDefault)[0];
const defaultBackend = defaultRule?.http?.paths[0]?.backend;
const nonDefaultRules = this.value.spec.rules.filter(rule => !rule.asDefault);
nonDefaultRules.forEach(rule => delete rule.asDefault);
this.value.spec.rules = nonDefaultRules;
if (defaultBackend ) {
this.$set(this.value.spec, 'backend', defaultBackend);
}
},
}
};
</script>
<template>
<form>
<NameNsDescription :value="value" :mode="mode" />
<div>
<h3>
Rules
</h3>
<Rule
v-for="(rule, i) in value.spec.rules"
:key="i"
:value="rule"
:workloads="workloads"
@remove="e=>removeRule(i)"
@input="e=>updateRule(e,i)"
/>
<button class="btn btn-sm role-primary mt-20 " type="button" @click="addRule">
Add Rule
</button>
</div>
<div>
<Tabbed :default-tab="'labels'">
<Tab name="labels" label="Labels">
<Labels :spec="value" mode="create" />
</Tab>
<Tab label="Certificates" name="certificates">
<Certificate
v-for="(cert,i) in value.spec.tls"
:key="i"
:certs="certificates"
:value="cert"
@input="e=>$set(value.spec.tls, i, e)"
@remove="e=>removeCert(i)"
/>
<button class="btn btn-sm role-primary mt-20 " type="button" @click="addCert">
Add Certificate
</button>
</Tab>
</Tabbed>
</div>
<Footer :errors="errors" :mode="mode" @save="save" @done="done" />
</form>
</template>