mirror of
https://github.com/portainer/portainer.git
synced 2025-07-25 08:19:40 +02:00
fix(ingress): allow none controller type EE-4420 (#7883)
Co-authored-by: testA113 <alex.harris@portainer.io>
This commit is contained in:
parent
e48ceb15e9
commit
55211ef00e
23 changed files with 243 additions and 76 deletions
|
@ -157,7 +157,9 @@ export function CreateIngressView() {
|
|||
const existingIngressClass = useMemo(
|
||||
() =>
|
||||
ingressControllersResults.data?.find(
|
||||
(i) => i.ClassName === ingressRule.IngressClassName
|
||||
(i) =>
|
||||
i.ClassName === ingressRule.IngressClassName ||
|
||||
(i.Type === 'custom' && ingressRule.IngressClassName === '')
|
||||
),
|
||||
[ingressControllersResults.data, ingressRule.IngressClassName]
|
||||
);
|
||||
|
@ -177,10 +179,11 @@ export function CreateIngressView() {
|
|||
ingressRule.IngressClassName &&
|
||||
!ingressControllersResults.isLoading
|
||||
) {
|
||||
const optionLabel = !ingressRule.IngressType
|
||||
? `${ingressRule.IngressClassName} - NOT FOUND`
|
||||
: `${ingressRule.IngressClassName} - DISALLOWED`;
|
||||
ingressClassOptions.push({
|
||||
label: !ingressRule.IngressType
|
||||
? `${ingressRule.IngressClassName} - NOT FOUND`
|
||||
: `${ingressRule.IngressClassName} - DISALLOWED`,
|
||||
label: optionLabel,
|
||||
value: ingressRule.IngressClassName,
|
||||
});
|
||||
}
|
||||
|
@ -206,6 +209,7 @@ export function CreateIngressView() {
|
|||
!!params.name &&
|
||||
ingressesResults.data &&
|
||||
!ingressRule.IngressName &&
|
||||
!ingressControllersResults.isLoading &&
|
||||
!ingressControllersResults.isLoading
|
||||
) {
|
||||
// if it is an edit screen, prepare the rule from the ingress
|
||||
|
@ -214,9 +218,11 @@ export function CreateIngressView() {
|
|||
);
|
||||
if (ing) {
|
||||
const type = ingressControllersResults.data?.find(
|
||||
(c) => c.ClassName === ing.ClassName
|
||||
(c) =>
|
||||
c.ClassName === ing.ClassName ||
|
||||
(c.Type === 'custom' && !ing.ClassName)
|
||||
)?.Type;
|
||||
const r = prepareRuleFromIngress(ing);
|
||||
const r = prepareRuleFromIngress(ing, type);
|
||||
r.IngressType = type || r.IngressType;
|
||||
setIngressRule(r);
|
||||
}
|
||||
|
@ -636,7 +642,7 @@ export function CreateIngressView() {
|
|||
setIngressRule(rule);
|
||||
}
|
||||
|
||||
function addNewAnnotation(type?: 'rewrite' | 'regex') {
|
||||
function addNewAnnotation(type?: 'rewrite' | 'regex' | 'ingressClass') {
|
||||
const rule = { ...ingressRule };
|
||||
|
||||
const annotation: Annotation = {
|
||||
|
@ -644,13 +650,21 @@ export function CreateIngressView() {
|
|||
Value: '',
|
||||
ID: uuidv4(),
|
||||
};
|
||||
if (type === 'rewrite') {
|
||||
annotation.Key = 'nginx.ingress.kubernetes.io/rewrite-target';
|
||||
annotation.Value = '/$1';
|
||||
}
|
||||
if (type === 'regex') {
|
||||
annotation.Key = 'nginx.ingress.kubernetes.io/use-regex';
|
||||
annotation.Value = 'true';
|
||||
switch (type) {
|
||||
case 'rewrite':
|
||||
annotation.Key = 'nginx.ingress.kubernetes.io/rewrite-target';
|
||||
annotation.Value = '/$1';
|
||||
break;
|
||||
case 'regex':
|
||||
annotation.Key = 'nginx.ingress.kubernetes.io/use-regex';
|
||||
annotation.Value = 'true';
|
||||
break;
|
||||
case 'ingressClass':
|
||||
annotation.Key = 'kubernetes.io/ingress.class';
|
||||
annotation.Value = '';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rule.Annotations = rule.Annotations || [];
|
||||
rule.Annotations?.push(annotation);
|
||||
|
@ -690,10 +704,13 @@ export function CreateIngressView() {
|
|||
function handleCreateIngressRules() {
|
||||
const rule = { ...ingressRule };
|
||||
|
||||
const classNameToSend =
|
||||
rule.IngressClassName === 'none' ? '' : rule.IngressClassName;
|
||||
|
||||
const ingress: Ingress = {
|
||||
Namespace: namespace,
|
||||
Name: rule.IngressName,
|
||||
ClassName: rule.IngressClassName,
|
||||
ClassName: classNameToSend,
|
||||
Hosts: rule.Hosts.map((host) => host.Host),
|
||||
Paths: preparePaths(rule.IngressName, rule.Hosts),
|
||||
TLS: prepareTLS(rule.Hosts),
|
||||
|
|
|
@ -47,7 +47,7 @@ interface Props {
|
|||
|
||||
addNewIngressHost: (noHost?: boolean) => void;
|
||||
addNewIngressRoute: (hostIndex: number) => void;
|
||||
addNewAnnotation: (type?: 'rewrite' | 'regex') => void;
|
||||
addNewAnnotation: (type?: 'rewrite' | 'regex' | 'ingressClass') => void;
|
||||
|
||||
handleNamespaceChange: (val: string) => void;
|
||||
handleHostChange: (hostIndex: number, val: string) => void;
|
||||
|
@ -249,9 +249,10 @@ export function IngressForm({
|
|||
onClick={() => addNewAnnotation('rewrite')}
|
||||
icon={Plus}
|
||||
title="When the exposed URLs for your applications differ from the specified paths in the ingress, use the rewrite target annotation to denote the path to redirect to."
|
||||
data-cy="add-rewrite-annotation"
|
||||
>
|
||||
{' '}
|
||||
add rewrite annotation
|
||||
Add rewrite annotation
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
|
@ -259,11 +260,23 @@ export function IngressForm({
|
|||
onClick={() => addNewAnnotation('regex')}
|
||||
icon={Plus}
|
||||
title="When the exposed URLs for your applications differ from the specified paths in the ingress, use the rewrite target annotation to denote the path to redirect to."
|
||||
data-cy="add-regex-annotation"
|
||||
>
|
||||
add regular expression annotation
|
||||
Add regular expression annotation
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{rule.IngressType === 'custom' && (
|
||||
<Button
|
||||
className="btn btn-sm btn-light mb-2 ml-2"
|
||||
onClick={() => addNewAnnotation('ingressClass')}
|
||||
icon={Plus}
|
||||
data-cy="add-ingress-class-annotation"
|
||||
>
|
||||
Add kubernetes.io/ingress.class annotation
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="col-sm-12 px-0 text-muted">Rules</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { Annotation } from '@/kubernetes/react/views/networks/ingresses/components/annotations/types';
|
||||
import { SupportedIngControllerTypes } from '@/react/kubernetes/cluster/ingressClass/types';
|
||||
|
||||
import { TLS, Ingress } from '../types';
|
||||
|
||||
|
@ -62,7 +63,7 @@ export function prepareRuleHostsFromIngress(ing: Ingress) {
|
|||
h.Host = host;
|
||||
h.Secret = getSecretByHost(host, ing.TLS);
|
||||
h.Paths = [];
|
||||
ing.Paths.forEach((path) => {
|
||||
ing.Paths?.forEach((path) => {
|
||||
if (path.Host === host) {
|
||||
h.Paths.push({
|
||||
Route: path.Path,
|
||||
|
@ -99,12 +100,15 @@ export function getAnnotationsForEdit(
|
|||
return result;
|
||||
}
|
||||
|
||||
export function prepareRuleFromIngress(ing: Ingress): Rule {
|
||||
export function prepareRuleFromIngress(
|
||||
ing: Ingress,
|
||||
type?: SupportedIngControllerTypes
|
||||
): Rule {
|
||||
return {
|
||||
Key: uuidv4(),
|
||||
IngressName: ing.Name,
|
||||
Namespace: ing.Namespace,
|
||||
IngressClassName: ing.ClassName,
|
||||
IngressClassName: type === 'custom' ? 'none' : ing.ClassName,
|
||||
Hosts: prepareRuleHostsFromIngress(ing) || [],
|
||||
Annotations: ing.Annotations ? getAnnotationsForEdit(ing.Annotations) : [],
|
||||
IngressType: ing.Type,
|
||||
|
|
|
@ -96,8 +96,11 @@ export function useIngresses(
|
|||
const serviceNamesInNamespace = servicesInNamespace?.map(
|
||||
(service) => service.Name
|
||||
);
|
||||
ing.Paths.forEach((path, pIndex) => {
|
||||
if (!serviceNamesInNamespace?.includes(path.ServiceName)) {
|
||||
ing.Paths?.forEach((path, pIndex) => {
|
||||
if (
|
||||
!serviceNamesInNamespace?.includes(path.ServiceName) &&
|
||||
filteredIngresses[iIndex].Paths
|
||||
) {
|
||||
filteredIngresses[iIndex].Paths[pIndex].HasService = false;
|
||||
} else {
|
||||
filteredIngresses[iIndex].Paths[pIndex].HasService = true;
|
||||
|
@ -186,6 +189,7 @@ export function useIngressControllers(
|
|||
},
|
||||
{
|
||||
enabled: !!namespace,
|
||||
cacheTime: 0,
|
||||
...withError('Unable to get ingress controllers'),
|
||||
}
|
||||
);
|
||||
|
|
|
@ -2,6 +2,7 @@ import {
|
|||
PaginationTableSettings,
|
||||
SortableTableSettings,
|
||||
} from '@/react/components/datatables/types';
|
||||
import { SupportedIngControllerTypes } from '@/react/kubernetes/cluster/ingressClass/types';
|
||||
|
||||
export interface TableSettings
|
||||
extends SortableTableSettings,
|
||||
|
@ -42,6 +43,6 @@ export interface IngressController {
|
|||
Name: string;
|
||||
ClassName: string;
|
||||
Availability: string;
|
||||
Type: string;
|
||||
Type: SupportedIngControllerTypes;
|
||||
New: boolean;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue