mirror of https://github.com/rancher/dashboard.git
Merge pull request #528 from codyrancher/ingress
Fixing up ingress pages
This commit is contained in:
commit
f7aa3d29a1
|
|
@ -118,13 +118,13 @@ export default {
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
margin-left: -1px;
|
margin-left: -1px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.in-input {
|
.in-input {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
||||||
|
|
||||||
& .v-select{
|
&.v-select {
|
||||||
height: 100%;
|
height: initial;
|
||||||
|
|
||||||
.vs__selected {
|
.vs__selected {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
@ -184,6 +184,7 @@ export default {
|
||||||
transform: rotate(180deg) scale(0.75);
|
transform: rotate(180deg) scale(0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,6 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
|
||||||
<div v-if="isView">
|
<div v-if="isView">
|
||||||
<div :class="{'labeled-input': true, raised, focused, empty, [mode]: true}">
|
<div :class="{'labeled-input': true, raised, focused, empty, [mode]: true}">
|
||||||
<label>
|
<label>
|
||||||
|
|
@ -154,7 +153,6 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</v-select>
|
</v-select>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang='scss'>
|
<style lang='scss'>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const serviceName = this.value?.http?.paths[0]?.backend?.serviceName;
|
const serviceName = this.value?.rules?.[0].http?.paths[0]?.backend?.serviceName || this.value?.backend?.serviceName || '';
|
||||||
const targetsWorkload = !serviceName.startsWith('ingress-');
|
const targetsWorkload = !serviceName.startsWith('ingress-');
|
||||||
let name; let params;
|
let name; let params;
|
||||||
|
|
||||||
|
|
@ -34,16 +34,37 @@ export default {
|
||||||
return {
|
return {
|
||||||
name, params, targetsWorkload
|
name, params, targetsWorkload
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
showHost() {
|
||||||
|
return !!this.host;
|
||||||
|
},
|
||||||
|
host() {
|
||||||
|
return this.value?.rules?.[0].host;
|
||||||
|
},
|
||||||
|
pathServiceName() {
|
||||||
|
return this.value?.rules?.[0]?.http?.paths?.[0]?.backend?.serviceName;
|
||||||
|
},
|
||||||
|
backendServiceName() {
|
||||||
|
return this.value?.backend?.serviceName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div v-if="value">
|
||||||
<a rel="nofollow noopener noreferrer" target="_blank" :href="'http://'+value.host">{{ value.host }}</a>
|
<div v-if="pathServiceName">
|
||||||
<i class="icon icon-chevron-right" />
|
<a v-if="showHost" rel="nofollow noopener noreferrer" target="_blank" :href="'http://' + host">{{ host }}</a>
|
||||||
|
<i v-if="showHost" class="icon icon-chevron-right" />
|
||||||
<nuxt-link :to="{name, params}">
|
<nuxt-link :to="{name, params}">
|
||||||
{{ value.http.paths[0].backend.serviceName }}
|
{{ pathServiceName }}
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else-if="backendServiceName">
|
||||||
|
<nuxt-link :to="{name, params}">
|
||||||
|
{{ backendServiceName }}
|
||||||
|
</nuxt-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -392,8 +392,7 @@ export const API_GROUP = {
|
||||||
export const INGRESS_TARGET = {
|
export const INGRESS_TARGET = {
|
||||||
name: 'ingressTarget',
|
name: 'ingressTarget',
|
||||||
label: 'Target',
|
label: 'Target',
|
||||||
value: "$['spec']['rules'][0]",
|
value: "$['spec']",
|
||||||
formatter: 'IngressTarget',
|
formatter: 'IngressTarget',
|
||||||
sort: "$['spec']['rules'][0].host",
|
sort: "$['spec']['rules'][0].host",
|
||||||
}
|
};
|
||||||
;
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import DetailTop from '@/components/DetailTop';
|
||||||
import SortableTable from '@/components/SortableTable';
|
import SortableTable from '@/components/SortableTable';
|
||||||
import Tabbed from '@/components/Tabbed';
|
import Tabbed from '@/components/Tabbed';
|
||||||
import Tab from '@/components/Tabbed/Tab';
|
import Tab from '@/components/Tabbed/Tab';
|
||||||
import KVTable from '@/components/KVTable';
|
import Labels from '@/components/form/Labels';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -13,7 +13,7 @@ export default {
|
||||||
SortableTable,
|
SortableTable,
|
||||||
Tabbed,
|
Tabbed,
|
||||||
Tab,
|
Tab,
|
||||||
KVTable
|
Labels
|
||||||
},
|
},
|
||||||
mixins: [CreateEditView],
|
mixins: [CreateEditView],
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -28,8 +28,8 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
|
|
||||||
detailTopColumns() {
|
detailTopColumns() {
|
||||||
const firstRule = this.value?.spec?.rules[0] || {};
|
const firstRule = this.firstRule || {};
|
||||||
const firstPath = firstRule?.http?.paths[0] || {};
|
const firstPath = firstRule?.http?.paths?.[0] || {};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
|
@ -75,6 +75,22 @@ export default {
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
backendHeaders() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'target',
|
||||||
|
label: 'Target',
|
||||||
|
value: 'serviceName',
|
||||||
|
width: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'port',
|
||||||
|
label: 'Port',
|
||||||
|
value: 'servicePort'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
certHeaders() {
|
certHeaders() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
@ -113,6 +129,14 @@ export default {
|
||||||
return cert;
|
return cert;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
firstRule() {
|
||||||
|
return this.value?.spec?.rules?.[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
ruleRows() {
|
||||||
|
return this.withUrl(this.firstRule?.http?.paths || []);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -150,18 +174,19 @@ export default {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<DetailTop :columns="detailTopColumns" />
|
<DetailTop class="mb-20" :columns="detailTopColumns" />
|
||||||
<div>
|
<div>
|
||||||
<h3 class="mb-20">
|
<h3 class="mb-20">
|
||||||
Rules
|
Rules
|
||||||
</h3>
|
</h3>
|
||||||
|
<div v-if="value.spec.rules">
|
||||||
<div v-for="(rule, i) in value.spec.rules" :key="i" class="rule mb-20">
|
<div v-for="(rule, i) in value.spec.rules" :key="i" class="rule mb-20">
|
||||||
<div class="label-col mb-40">
|
<div class="label-col mb-40">
|
||||||
<span>Hostname</span>
|
<span>Hostname</span>
|
||||||
<code> {{ rule.host }}</code>
|
<code> {{ rule.host }}</code>
|
||||||
</div>
|
</div>
|
||||||
<SortableTable
|
<SortableTable
|
||||||
:rows="withUrl(rule.http.paths)"
|
:rows="ruleRows"
|
||||||
:headers="ruleHeaders"
|
:headers="ruleHeaders"
|
||||||
key-field="path"
|
key-field="path"
|
||||||
:search="false"
|
:search="false"
|
||||||
|
|
@ -170,9 +195,23 @@ export default {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="rule">
|
||||||
|
<div class="mb-10">
|
||||||
|
Use as the default backend
|
||||||
|
</div>
|
||||||
|
<SortableTable
|
||||||
|
:rows="[value.spec.backend]"
|
||||||
|
:headers="backendHeaders"
|
||||||
|
key-field="service"
|
||||||
|
:search="false"
|
||||||
|
:table-actions="false"
|
||||||
|
:row-actions="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<Tabbed default-tab="labels">
|
<Tabbed default-tab="labels">
|
||||||
<Tab name="labels" label="Labels">
|
<Tab name="labels" label="Labels">
|
||||||
<KVTable :rows="value.metadata.labels" />
|
<Labels :spec="value" :mode="mode" />
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab name="certificates" label="Certificates">
|
<Tab name="certificates" label="Certificates">
|
||||||
<SortableTable
|
<SortableTable
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export default {
|
||||||
const { paths = [{ id: random32(1) }] } = http;
|
const { paths = [{ id: random32(1) }] } = http;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
host, paths, ruleMode: 'setHost'
|
host, paths, ruleMode: this.value.asDefault ? 'asDefault' : 'setHost'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -93,7 +93,7 @@ export default {
|
||||||
@remove="e=>removePath(i)"
|
@remove="e=>removePath(i)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<button :style="{'padding':'0px 0px 0px 5px'}" class="btn btn-sm role-link" @click="addPath">
|
<button v-if="ruleMode === 'setHost'" :style="{'padding':'0px 0px 0px 5px'}" class="btn btn-sm role-link" @click="addPath">
|
||||||
add path
|
add path
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import Certificate from './Certificate';
|
import Certificate from './Certificate';
|
||||||
import Rule from './Rule';
|
import Rule from './Rule';
|
||||||
|
|
||||||
import { clone } from '@/utils/object';
|
|
||||||
import { allHash } from '@/utils/promise';
|
import { allHash } from '@/utils/promise';
|
||||||
import { SECRET, TLS_CERT, WORKLOAD_TYPES } from '@/config/types';
|
import { SECRET, TLS_CERT, WORKLOAD_TYPES } from '@/config/types';
|
||||||
import NameNsDescription from '@/components/form/NameNsDescription';
|
import NameNsDescription from '@/components/form/NameNsDescription';
|
||||||
|
|
@ -43,18 +41,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
const { metadata = {}, spec = {} } = clone(this.value);
|
return { allSecrets: [], allWorkloads: [] };
|
||||||
|
|
||||||
if (!spec.rules) {
|
|
||||||
spec.rules = [{}];
|
|
||||||
}
|
|
||||||
if (!spec.tls) {
|
|
||||||
spec.tls = [{ }];
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
metadata, spec, allSecrets: [], allWorkloads: []
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -75,6 +62,31 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
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: {
|
methods: {
|
||||||
async loadDeps() {
|
async loadDeps() {
|
||||||
const hash = await allHash({
|
const hash = await allHash({
|
||||||
|
|
@ -99,30 +111,30 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
addRule() {
|
addRule() {
|
||||||
this.spec.rules = [...this.spec.rules, {}];
|
this.value.spec.rules = [...this.value.spec.rules, {}];
|
||||||
},
|
},
|
||||||
|
|
||||||
removeRule(idx) {
|
removeRule(idx) {
|
||||||
const neu = [...this.spec.rules];
|
const neu = [...this.value.spec.rules];
|
||||||
|
|
||||||
neu.splice(idx, 1);
|
neu.splice(idx, 1);
|
||||||
|
|
||||||
this.$set(this.spec, 'rules', neu);
|
this.$set(this.value.spec, 'rules', neu);
|
||||||
},
|
},
|
||||||
|
|
||||||
updateRule(neu, idx) {
|
updateRule(neu, idx) {
|
||||||
this.$set(this.spec.rules, idx, neu);
|
this.$set(this.value.spec.rules, idx, neu);
|
||||||
},
|
},
|
||||||
|
|
||||||
addCert() {
|
addCert() {
|
||||||
this.spec.tls = [...this.spec.tls, {}];
|
this.value.spec.tls = [...this.value.spec.tls, {}];
|
||||||
},
|
},
|
||||||
|
|
||||||
removeCert(idx) {
|
removeCert(idx) {
|
||||||
const neu = [...this.spec.tls];
|
const neu = [...this.value.spec.tls];
|
||||||
|
|
||||||
neu.splice(idx, 1);
|
neu.splice(idx, 1);
|
||||||
this.$set(this.spec, 'tls', neu);
|
this.$set(this.value.spec, 'tls', neu);
|
||||||
},
|
},
|
||||||
|
|
||||||
// filter a given list of resources by currently selected namespaces
|
// filter a given list of resources by currently selected namespaces
|
||||||
|
|
@ -149,38 +161,31 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
saveIngress(cb) {
|
willSave() {
|
||||||
const defaultRule = this.spec.rules.filter(rule => rule.asDefault)[0];
|
const defaultRule = this.value.spec.rules.filter(rule => rule.asDefault)[0];
|
||||||
const nonDefaultRules = this.spec.rules.filter(rule => !rule.asDefault);
|
|
||||||
const defaultBackend = defaultRule?.http?.paths[0]?.backend;
|
const defaultBackend = defaultRule?.http?.paths[0]?.backend;
|
||||||
|
const nonDefaultRules = this.value.spec.rules.filter(rule => !rule.asDefault);
|
||||||
|
|
||||||
nonDefaultRules.forEach(rule => delete rule.asDefault);
|
nonDefaultRules.forEach(rule => delete rule.asDefault);
|
||||||
|
this.value.spec.rules = nonDefaultRules;
|
||||||
|
|
||||||
if (defaultBackend ) {
|
if (defaultBackend ) {
|
||||||
this.$set(this.spec, 'backend', defaultBackend);
|
this.$set(this.value.spec, 'backend', defaultBackend);
|
||||||
}
|
|
||||||
this.spec.rules = nonDefaultRules;
|
|
||||||
|
|
||||||
this.$set(this.value, 'spec', this.spec);
|
|
||||||
this.$set(this.value, 'metadata', this.metadata);
|
|
||||||
|
|
||||||
const saveUrl = this.value.urlFromAttrs;
|
|
||||||
|
|
||||||
this.save(cb, saveUrl);
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<form>
|
<form>
|
||||||
<NameNsDescription :value="{metadata}" :mode="mode" @input="e=>metadata=e" />
|
<NameNsDescription v-model="value" :mode="mode" @input="e=>metadata=e" />
|
||||||
<div>
|
<div>
|
||||||
<h3>
|
<h3>
|
||||||
Rules
|
Rules
|
||||||
</h3>
|
</h3>
|
||||||
<Rule
|
<Rule
|
||||||
v-for="(rule, i) in spec.rules"
|
v-for="(rule, i) in value.spec.rules"
|
||||||
:key="i"
|
:key="i"
|
||||||
:value="rule"
|
:value="rule"
|
||||||
:workloads="workloads"
|
:workloads="workloads"
|
||||||
|
|
@ -194,15 +199,15 @@ export default {
|
||||||
<div>
|
<div>
|
||||||
<Tabbed :default-tab="'labels'">
|
<Tabbed :default-tab="'labels'">
|
||||||
<Tab name="labels" label="Labels">
|
<Tab name="labels" label="Labels">
|
||||||
<Labels :spec="{metadata:{}}" mode="create" />
|
<Labels :spec="value" mode="create" />
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab label="Certificates" name="certificates">
|
<Tab label="Certificates" name="certificates">
|
||||||
<Certificate
|
<Certificate
|
||||||
v-for="(cert,i) in spec.tls"
|
v-for="(cert,i) in value.spec.tls"
|
||||||
:key="i"
|
:key="i"
|
||||||
:certs="certificates"
|
:certs="certificates"
|
||||||
:value="cert"
|
:value="cert"
|
||||||
@input="e=>$set(spec.tls, i, e)"
|
@input="e=>$set(value.spec.tls, i, e)"
|
||||||
@remove="e=>removeCert(i)"
|
@remove="e=>removeCert(i)"
|
||||||
/>
|
/>
|
||||||
<button class="btn btn-sm role-primary mt-20 " type="button" @click="addCert">
|
<button class="btn btn-sm role-primary mt-20 " type="button" @click="addCert">
|
||||||
|
|
@ -211,6 +216,6 @@ export default {
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabbed>
|
</Tabbed>
|
||||||
</div>
|
</div>
|
||||||
<Footer :errors="errors" :mode="mode" @save="saveIngress" @done="done" />
|
<Footer :errors="errors" :mode="mode" @save="save" @done="done" />
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -774,7 +774,12 @@ export default {
|
||||||
const { metadata:{ namespace = 'default' } } = this;
|
const { metadata:{ namespace = 'default' } } = this;
|
||||||
let url = schema.links.collection;
|
let url = schema.links.collection;
|
||||||
|
|
||||||
const [group, resource] = schema?.attributes;
|
const attributes = schema?.attributes;
|
||||||
|
|
||||||
|
if (!attributes) {
|
||||||
|
throw new Error('Attributes must be present on the schema');
|
||||||
|
}
|
||||||
|
const { group, resource } = attributes;
|
||||||
|
|
||||||
url = `${ url.slice(0, url.indexOf('/v1')) }/apis/${ group }/namespaces/${ namespace }/${ resource }`;
|
url = `${ url.slice(0, url.indexOf('/v1')) }/apis/${ group }/namespaces/${ namespace }/${ resource }`;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue