Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions shell/edit/networking.k8s.io.ingress/DefaultBackend.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ export default {
const backend = get(this.value.spec, this.value.defaultBackendPath);

this.serviceName = get(backend, this.value.serviceNamePath) || '';
this.servicePort = get(backend, this.value.servicePortPath) || '';
this.servicePort = get(backend, this.value.servicePortPath) ||
get(backend, this.value.servicePortNamePath) ||
'';
},
computed: {
isView() {
Expand Down Expand Up @@ -75,10 +77,14 @@ export default {
},
methods: {
update() {
const backend = get(this.value.spec, this.value.defaultBackendPath) || {};
// Fresh object so the old port path (name vs number) doesn't linger.
const backend = {};
const parsed = Number.parseInt(this.servicePort);
const servicePort = Number.isNaN(parsed) ? this.servicePort : parsed;
const portPath = typeof servicePort === 'number' ? this.value.servicePortPath : this.value.servicePortNamePath;

set(backend, this.value.serviceNamePath, this.serviceName);
set(backend, this.value.servicePortPath, this.servicePort);
set(backend, portPath, servicePort);
set(this.value.spec, this.value.defaultBackendPath, backend);

this.$emit('update:value', this.value);
Expand Down Expand Up @@ -119,10 +125,12 @@ export default {
class="col span-3"
:style="{'margin-right': '0px'}"
>
<!-- :required drives the asterisk; portRequired doesn't have .name === 'required' -->
<LabeledInput
v-if="portOptions.length === 0 || isView"
v-model:value.number="servicePort"
v-model:value="servicePort"
:mode="mode"
:required="true"
:label="t('ingress.defaultBackend.port.label')"
:placeholder="t('ingress.defaultBackend.port.placeholder')"
:rules="rules.port"
Expand All @@ -132,6 +140,7 @@ export default {
v-else
v-model:value="servicePort"
:mode="mode"
:required="true"
:options="portOptions"
:label="t('ingress.defaultBackend.port.label')"
:placeholder="t('ingress.defaultBackend.port.placeholder')"
Expand Down
12 changes: 8 additions & 4 deletions shell/edit/networking.k8s.io.ingress/RulePath.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,24 @@ export default {
set(this.value, 'path', this.value.path || '');
set(this.value, 'pathType', this.value.pathType || this.pathTypes[0]);
set(this.value.backend, this.ingress.serviceNamePath, get(this.value.backend, this.ingress.serviceNamePath) || '');
set(this.value.backend, this.ingress.servicePortPath, get(this.value.backend, this.ingress.servicePortPath) || '');

this.serviceName = get(this.value.backend, this.ingress.serviceNamePath);
this.servicePort = get(this.value.backend, this.ingress.servicePortPath);
this.servicePort = get(this.value.backend, this.ingress.servicePortPath) ||
get(this.value.backend, this.ingress.servicePortNamePath) ||
'';
},
methods: {
update() {
const servicePort = Number.parseInt(this.servicePort) || this.servicePort;
const parsed = Number.parseInt(this.servicePort);
const servicePort = Number.isNaN(parsed) ? this.servicePort : parsed;
const serviceName = this.serviceName.label || this.serviceName;
const out = {
id: this.value.id, backend: {}, path: this.path, pathType: this.pathType
};

set(out.backend, this.ingress.servicePortPath, servicePort);
const portPath = typeof servicePort === 'number' ? this.ingress.servicePortPath : this.ingress.servicePortNamePath;

set(out.backend, portPath, servicePort);
set(out.backend, this.ingress.serviceNamePath, serviceName);

this.$emit('update:value', out);
Expand Down
49 changes: 41 additions & 8 deletions shell/edit/networking.k8s.io.ingress/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export default {
path: 'spec.rules.http.paths.path', rules: ['absolutePath'], translationKey: 'ingress.rules.path.label'
},
{
path: 'spec.rules.http.paths.backend.service.port.number', rules: ['required'], translationKey: 'ingress.rules.port.label'
path: 'spec.rules.http.paths.backend.service.port', rules: ['portRequired', 'portRange'], translationKey: 'ingress.rules.port.label'
},
{
path: 'spec.rules.http.paths.backend.service.name', rules: ['required'], translationKey: 'ingress.rules.target.label'
Expand All @@ -97,11 +97,11 @@ export default {
path: 'spec.defaultBackend.service.name', rules: ['required'], translationKey: 'ingress.defaultBackend.targetService.label'
},
{
path: 'spec.defaultBackend.service.port.number', rules: ['required', 'requiredInt', 'portNumber'], translationKey: 'ingress.defaultBackend.port.label'
path: 'spec.defaultBackend.service.port', rules: ['portRequired', 'portRange'], translationKey: 'ingress.defaultBackend.port.label'
},
{ path: 'spec.tls.hosts', rules: ['required', 'wildcardHostname'] }
],
fvReportedValidationPaths: ['spec.rules.http.paths.backend.service.port.number', 'spec.rules.http.paths.path', 'spec.rules.http.paths.backend.service.name']
fvReportedValidationPaths: ['spec.rules.http.paths.backend.service.port', 'spec.rules.http.paths.path', 'spec.rules.http.paths.backend.service.name']
};
},

Expand All @@ -125,19 +125,52 @@ export default {
}
};

return { backEndOrRules };
const portLabel = this.t('ingress.rules.port.label');

// Built-in `required` won't work: it passes for empty objects like {} or { name: '' }.
const portRequired = (port) => {
if (typeof port === 'string' || typeof port === 'number') {
if (!port) {
return this.t('validation.required', { key: portLabel });
}
} else if (!port || (!port.number && !port.name)) {
return this.t('validation.required', { key: portLabel });
}
};

const portRange = (port) => {
let num;

if (typeof port === 'number') {
num = port;
} else if (typeof port === 'string') {
num = Number.parseInt(port);
} else if (port?.number) {
num = port.number;
}

if (num !== undefined && !Number.isNaN(num) && (num < 1 || num > 65535)) {
return this.t('validation.number.between', {
key: portLabel, min: '1', max: '65535'
});
}
};

return {
backEndOrRules, portRequired, portRange
};
},
tabErrors() {
return {
rules: this.fvGetPathErrors(['spec.rules.host', 'spec.rules.http.paths.path', 'spec.rules.http.paths.backend.service.port.number', 'spec.rules.http.paths.backend.service.name'])?.length > 0,
defaultBackend: this.fvGetPathErrors(['spec.defaultBackend.service.name', 'spec.defaultBackend.service.port.number'])?.length > 0
rules: this.fvGetPathErrors(['spec.rules.host', 'spec.rules.http.paths.path', 'spec.rules.http.paths.backend.service.port', 'spec.rules.http.paths.backend.service.name'])?.length > 0,
defaultBackend: this.fvGetPathErrors(['spec.defaultBackend.service.name', 'spec.defaultBackend.service.port'])?.length > 0
};
},
rulesPathRules() {
return {
requestHost: this.fvGetAndReportPathRules('spec.rules.host'),
path: this.fvGetAndReportPathRules('spec.rules.http.paths.path'),
port: this.fvGetAndReportPathRules('spec.rules.http.paths.backend.service.port.number'),
port: this.fvGetAndReportPathRules('spec.rules.http.paths.backend.service.port'),
target: this.fvGetAndReportPathRules('spec.rules.http.paths.backend.service.name'),

};
Expand All @@ -149,7 +182,7 @@ export default {
if (!rulesExist || defaultBackendExist) {
return {
name: this.fvGetAndReportPathRules('spec.defaultBackend.service.name'),
port: this.fvGetAndReportPathRules('spec.defaultBackend.service.port.number'),
port: this.fvGetAndReportPathRules('spec.defaultBackend.service.port'),
};
}

Expand Down
10 changes: 9 additions & 1 deletion shell/models/networking.k8s.io.ingress.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default class Ingress extends SteveModel {
serviceTargetTo: this.targetTo(workloads, serviceName),
certs: this.certLinks(rule, certificates),
targetLink: this.targetLink(workloads, serviceName),
port: get(path?.backend, this.servicePortPath)
port: get(path?.backend, this.servicePortPath) || get(path?.backend, this.servicePortNamePath)
};
}

Expand Down Expand Up @@ -184,6 +184,14 @@ export default class Ingress extends SteveModel {
return this.useNestedBackendField ? nestedPath : flatPath;
}

get servicePortNamePath() {
const nestedPath = 'service.port.name';
// Flat API has a single `servicePort` field for both name and number.
const flatPath = 'servicePort';

return this.useNestedBackendField ? nestedPath : flatPath;
}

get defaultBackendPath() {
const defaultBackend = this.$rootGetters['cluster/pathExistsInSchema'](this.type, 'spec.defaultBackend');

Expand Down
Loading
Loading