From 0b1b715af6937254dd01f48f779d32eb57f742f1 Mon Sep 17 00:00:00 2001 From: Oliwia Gowor Date: Tue, 20 Aug 2024 11:06:51 +0200 Subject: [PATCH 1/5] ingress with ports in status --- public/i18n/en.yaml | 1 + src/resources/Ingresses/IngressDetails.js | 127 ++++++++++++++++++++-- 2 files changed, 118 insertions(+), 10 deletions(-) diff --git a/public/i18n/en.yaml b/public/i18n/en.yaml index 04531a5995..9c4a2c2089 100644 --- a/public/i18n/en.yaml +++ b/public/i18n/en.yaml @@ -343,6 +343,7 @@ common: resources: Resources nodeInfo: Node Info node-details: Node Details + specification: Specification started-at: Started At status: Status value: Value diff --git a/src/resources/Ingresses/IngressDetails.js b/src/resources/Ingresses/IngressDetails.js index 3e6c23afa6..d4b35fcaaf 100644 --- a/src/resources/Ingresses/IngressDetails.js +++ b/src/resources/Ingresses/IngressDetails.js @@ -7,11 +7,49 @@ import { Rules } from './Rules'; import { DefaultBackendPanel } from './DefaultBackendPanel'; import IngressCreate from './IngressCreate'; import { ResourceDescription } from 'resources/Ingresses'; +import { EventsList } from 'shared/components/EventsList'; +import { filterByResource } from 'hooks/useMessageList'; +import { UI5Panel } from 'shared/components/UI5Panel/UI5Panel'; +import { LayoutPanelRow } from 'shared/components/LayoutPanelRow/LayoutPanelRow'; +import { StatusBadge } from 'shared/components/StatusBadge/StatusBadge'; + +const exampleStatus = { + loadBalancer: { + ingress: [ + { + hostname: 'example-lb1.example.com', + ip: '192.0.2.1', + ports: [ + { + port: 80, + protocol: 'TCP', + error: 'ServicePortConflict', + }, + { + port: 443, + protocol: 'TCP', + }, + ], + }, + { + hostname: 'example-lb2.example.com', + ip: '192.0.2.2', + ports: [ + { + port: 80, + protocol: 'TCP', + }, + ], + }, + ], + }, +}; export function IngressDetails(props) { const { t } = useTranslation(); const getLoadBalancer = ingress => { + ingress.status = exampleStatus; if (ingress.status.loadBalancer?.ingress) { return ingress.status.loadBalancer?.ingress .map(endpoint => endpoint.ip || endpoint.hostname) @@ -21,19 +59,48 @@ export function IngressDetails(props) { } }; - const customColumns = [ - { - header: t('ingresses.labels.load-balancers'), - value: getLoadBalancer, - }, - { - header: t('ingresses.labels.ingress-class-name'), - value: ingress => ingress.spec.ingressClassName, - }, - ]; + const calculateTotalPorts = ingress => { + //ingress.status = exampleStatus; + + const totalPorts = + ingress?.status?.loadBalancer?.ingress?.reduce((total, endpoint) => { + return total + (endpoint?.ports ? endpoint?.ports?.length : 0); + }, 0) ?? 0; + + return totalPorts; + }; + + const calculatePortsWithoutErrors = ingress => { + //ingress.status = exampleStatus; + + const totalPortsWithoutErrors = + ingress?.status?.loadBalancer?.ingress?.reduce((total, endpoint) => { + return ( + total + + (endpoint?.ports + ? endpoint?.ports.filter(port => !port?.error)?.length + : 0) + ); + }, 0) ?? 0; + + return totalPortsWithoutErrors; + }; + + const customColumns = []; const customComponents = []; + customComponents.push(resource => ( + + {resource.spec.ingressClassName && ( + + )} + + )); + customComponents.push(resource => resource.spec.defaultBackend ? ( ( + + )); + + const customStatusColumns = [ + { + header: t('ingresses.labels.load-balancers'), + value: getLoadBalancer, + }, + { + header: 'Ports', + value: resource => calculateTotalPorts(resource), + }, + ]; + + const statusBadge = resource => { + const portsNoError = calculatePortsWithoutErrors(resource); + const allPorts = calculateTotalPorts(resource); + const portsStatus = + allPorts === 0 + ? 'Information' + : allPorts === portsNoError + ? 'Success' + : 'Error'; + + return ( + {`${portsNoError} / ${allPorts}`} + ); + }; + return ( ); From e912fe5810b112cf15d1d6a52237f1f142979c51 Mon Sep 17 00:00:00 2001 From: Oliwia Gowor Date: Wed, 21 Aug 2024 11:00:37 +0200 Subject: [PATCH 2/5] add ports and tls --- public/i18n/en.yaml | 7 ++ src/resources/Ingresses/IngressDetails.js | 93 ++++++----------- .../Ingresses/IngressSpecification.js | 35 +++++++ src/resources/Ingresses/IngressStatus.js | 99 +++++++++++++++++++ src/resources/Ingresses/IngressStatus.scss | 17 ++++ .../ConditionList/ConditionList.tsx | 13 ++- .../ExpandableListItem/ExpandableListItem.tsx | 36 ++++--- 7 files changed, 219 insertions(+), 81 deletions(-) create mode 100644 src/resources/Ingresses/IngressSpecification.js create mode 100644 src/resources/Ingresses/IngressStatus.js create mode 100644 src/resources/Ingresses/IngressStatus.scss diff --git a/public/i18n/en.yaml b/public/i18n/en.yaml index 9c4a2c2089..755a6ac77d 100644 --- a/public/i18n/en.yaml +++ b/public/i18n/en.yaml @@ -878,17 +878,24 @@ ingresses: backend: Backend default-backend: Default Backend host: Host + host-name: Host name + hosts: Hosts ingress-class-name: Ingress class name + ip: IP kind: Kind load-balancers: Load Balancers path: Path path-type: Path type paths: Paths port: Port + ports: Ports port-name: Port name port-number: Port number + protocol: Protocol rules: Rules + secret-name: Secret name service-name: Service name + tls: TLS message: rules-not-found: Rules not found name_singular: Ingress diff --git a/src/resources/Ingresses/IngressDetails.js b/src/resources/Ingresses/IngressDetails.js index d4b35fcaaf..7b13fe5771 100644 --- a/src/resources/Ingresses/IngressDetails.js +++ b/src/resources/Ingresses/IngressDetails.js @@ -1,7 +1,6 @@ import { useTranslation } from 'react-i18next'; import { ResourceDetails } from 'shared/components/ResourceDetails/ResourceDetails'; -import { EMPTY_TEXT_PLACEHOLDER } from 'shared/constants'; import { Rules } from './Rules'; import { DefaultBackendPanel } from './DefaultBackendPanel'; @@ -9,16 +8,16 @@ import IngressCreate from './IngressCreate'; import { ResourceDescription } from 'resources/Ingresses'; import { EventsList } from 'shared/components/EventsList'; import { filterByResource } from 'hooks/useMessageList'; -import { UI5Panel } from 'shared/components/UI5Panel/UI5Panel'; -import { LayoutPanelRow } from 'shared/components/LayoutPanelRow/LayoutPanelRow'; import { StatusBadge } from 'shared/components/StatusBadge/StatusBadge'; +import { IngressStatus } from './IngressStatus'; +import { IngressSpecification } from './IngressSpecification'; +import { useEffect, useState } from 'react'; const exampleStatus = { loadBalancer: { ingress: [ { hostname: 'example-lb1.example.com', - ip: '192.0.2.1', ports: [ { port: 80, @@ -32,7 +31,6 @@ const exampleStatus = { ], }, { - hostname: 'example-lb2.example.com', ip: '192.0.2.2', ports: [ { @@ -47,58 +45,38 @@ const exampleStatus = { export function IngressDetails(props) { const { t } = useTranslation(); - - const getLoadBalancer = ingress => { - ingress.status = exampleStatus; - if (ingress.status.loadBalancer?.ingress) { - return ingress.status.loadBalancer?.ingress - .map(endpoint => endpoint.ip || endpoint.hostname) - .join(', '); - } else { - return EMPTY_TEXT_PLACEHOLDER; - } - }; + const [totalPods, setTotalPods] = useState(0); + const [healthyPods, setHealthyPods] = useState(0); const calculateTotalPorts = ingress => { - //ingress.status = exampleStatus; + if (ingress.metadata.name === 'cafe-ingress') + ingress.status = exampleStatus; + let allPorts = 0; - const totalPorts = - ingress?.status?.loadBalancer?.ingress?.reduce((total, endpoint) => { - return total + (endpoint?.ports ? endpoint?.ports?.length : 0); - }, 0) ?? 0; + ingress?.status?.loadBalancer?.ingress?.forEach(element => { + element?.ports?.forEach(() => allPorts++); + }); - return totalPorts; + setTotalPods(allPorts); }; const calculatePortsWithoutErrors = ingress => { //ingress.status = exampleStatus; + let healthyPods = 0; - const totalPortsWithoutErrors = - ingress?.status?.loadBalancer?.ingress?.reduce((total, endpoint) => { - return ( - total + - (endpoint?.ports - ? endpoint?.ports.filter(port => !port?.error)?.length - : 0) - ); - }, 0) ?? 0; - - return totalPortsWithoutErrors; - }; + ingress?.status?.loadBalancer?.ingress?.forEach(element => { + element?.ports?.forEach(port => { + if (!port.error) healthyPods++; + }); + }); - const customColumns = []; + setHealthyPods(healthyPods); + }; const customComponents = []; customComponents.push(resource => ( - - {resource.spec.ingressClassName && ( - - )} - + )); customComponents.push(resource => @@ -125,24 +103,13 @@ export function IngressDetails(props) { /> )); - const customStatusColumns = [ - { - header: t('ingresses.labels.load-balancers'), - value: getLoadBalancer, - }, - { - header: 'Ports', - value: resource => calculateTotalPorts(resource), - }, - ]; - const statusBadge = resource => { - const portsNoError = calculatePortsWithoutErrors(resource); - const allPorts = calculateTotalPorts(resource); + calculateTotalPorts(resource); + calculatePortsWithoutErrors(resource); const portsStatus = - allPorts === 0 + totalPods === 0 ? 'Information' - : allPorts === portsNoError + : totalPods === healthyPods ? 'Success' : 'Error'; @@ -150,18 +117,22 @@ export function IngressDetails(props) { {`${portsNoError} / ${allPorts}`} + >{`${healthyPods} / ${totalPods}`} ); }; return ( , + }, + ]} {...props} /> ); diff --git a/src/resources/Ingresses/IngressSpecification.js b/src/resources/Ingresses/IngressSpecification.js new file mode 100644 index 0000000000..8463451996 --- /dev/null +++ b/src/resources/Ingresses/IngressSpecification.js @@ -0,0 +1,35 @@ +import { useTranslation } from 'react-i18next'; +import { GenericList } from 'shared/components/GenericList/GenericList'; +import { LayoutPanelRow } from 'shared/components/LayoutPanelRow/LayoutPanelRow'; +import { UI5Panel } from 'shared/components/UI5Panel/UI5Panel'; + +export const IngressSpecification = ({ resource }) => { + const { t } = useTranslation(); + + return ( + <> + + {resource.spec && ( + + )} + {resource.spec?.tls && ( + [ + t('ingresses.labels.hosts'), + t('ingresses.labels.secret-name'), + ]} + rowRenderer={tls => [tls?.hosts.join(', '), tls?.secretName]} + entries={resource.spec?.tls} + searchSettings={{ + showSearchField: false, + }} + /> + )} + + + ); +}; diff --git a/src/resources/Ingresses/IngressStatus.js b/src/resources/Ingresses/IngressStatus.js new file mode 100644 index 0000000000..cff020fe74 --- /dev/null +++ b/src/resources/Ingresses/IngressStatus.js @@ -0,0 +1,99 @@ +import { useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { ConditionList } from 'shared/components/ConditionList/ConditionList'; +import { EMPTY_TEXT_PLACEHOLDER } from 'shared/constants'; +import { spacing } from '@ui5/webcomponents-react-base'; +import './IngressStatus.scss'; +import { Label } from 'shared/ResourceForm/components/Label'; +import { Badge } from 'components/Extensibility/components/Badge'; + +export const IngressStatus = ({ resource }) => { + const { t } = useTranslation(); + const ingresses = useMemo(() => { + return resource?.status?.loadBalancer?.ingress?.map(ingress => ingress); + }, [resource]); + + return ingresses ? ( + ({ + header: { + titleText: ingress.hostname ? ( +
+ {`${ingress.hostname}`} + +
+ ) : ( +
+ {`${ingress.ip}`} + +
+ ), + }, + customContent: [ + ...(ingress.hostname + ? [ + { + header: t('ingresses.labels.host-name'), + value: ingress.hostname, + className: 'load-balancers__content', + }, + ] + : []), + ...(ingress.ip + ? [ + { + header: t('ingresses.labels.ip'), + value: ingress.ip, + className: 'load-balancers__content', + }, + ] + : []), + { + header: t('ingresses.labels.ports'), + value: ingress.ports ? ( + { + return { + header: { + titleText: port.port, + status: port.error ? 'Error' : '', + }, + customContent: [ + port.protocol + ? { + header: t('ingresses.labels.protocol'), + value: port.protocol, + } + : {}, + ...(port.error + ? [ + { + header: 'Error', + value: port.error, + }, + ] + : []), + ], + }; + })} + /> + ) : ( + EMPTY_TEXT_PLACEHOLDER + ), + }, + ], + }))} + /> + ) : ( +
+ {EMPTY_TEXT_PLACEHOLDER} +
+ ); +}; diff --git a/src/resources/Ingresses/IngressStatus.scss b/src/resources/Ingresses/IngressStatus.scss new file mode 100644 index 0000000000..fa2474261c --- /dev/null +++ b/src/resources/Ingresses/IngressStatus.scss @@ -0,0 +1,17 @@ +.load-balancers { + &__header { + display: flex; + align-items: center; + gap: 1rem; + } + + .expandable-item__message:not(.load-balancers__content) { + .title { + margin-left: 0.5rem !important; + } + } + + &__content { + margin-left: 1.5rem !important; + } +} diff --git a/src/shared/components/ConditionList/ConditionList.tsx b/src/shared/components/ConditionList/ConditionList.tsx index c92d6a1d1a..397c7390b5 100644 --- a/src/shared/components/ConditionList/ConditionList.tsx +++ b/src/shared/components/ConditionList/ConditionList.tsx @@ -3,27 +3,32 @@ import { CustomContent, ExpandableListItem, } from '../ExpandableListItem/ExpandableListItem'; +import { ReactNode } from 'react'; type ConditionListProps = { conditions: [ConditionItem]; + className?: string; }; type ConditionItem = { - message: string; header: ConditionHeader; + message?: string; customContent?: CustomContent[]; }; type ConditionHeader = { - titleText: string; + titleText: string | ReactNode; status?: string; }; -export const ConditionList = ({ conditions }: ConditionListProps) => { +export const ConditionList = ({ + conditions, + className, +}: ConditionListProps) => { if (!conditions) { return null; } return ( - + {conditions?.map((cond, index) => ( {expanded && ( <> -
-
- {`${t('common.headers.message')}:`} + {content && ( +
+
+ {`${t('common.headers.message')}:`} +
+ {content}
- {content} -
+ )} {customContent && - customContent.map(element => ( + customContent.map((element, index) => (
{`${element.header}:`} From 558bd889554a6033a15f15385b20b4d6505ac0b3 Mon Sep 17 00:00:00 2001 From: Oliwia Gowor Date: Wed, 21 Aug 2024 15:01:43 +0200 Subject: [PATCH 3/5] add labels & cleanup --- src/resources/Ingresses/IngressDetails.js | 35 +--------------------- src/resources/Ingresses/IngressStatus.js | 20 +++++++++---- src/resources/Ingresses/IngressStatus.scss | 6 ---- 3 files changed, 15 insertions(+), 46 deletions(-) diff --git a/src/resources/Ingresses/IngressDetails.js b/src/resources/Ingresses/IngressDetails.js index 7b13fe5771..0487a99d98 100644 --- a/src/resources/Ingresses/IngressDetails.js +++ b/src/resources/Ingresses/IngressDetails.js @@ -11,37 +11,7 @@ import { filterByResource } from 'hooks/useMessageList'; import { StatusBadge } from 'shared/components/StatusBadge/StatusBadge'; import { IngressStatus } from './IngressStatus'; import { IngressSpecification } from './IngressSpecification'; -import { useEffect, useState } from 'react'; - -const exampleStatus = { - loadBalancer: { - ingress: [ - { - hostname: 'example-lb1.example.com', - ports: [ - { - port: 80, - protocol: 'TCP', - error: 'ServicePortConflict', - }, - { - port: 443, - protocol: 'TCP', - }, - ], - }, - { - ip: '192.0.2.2', - ports: [ - { - port: 80, - protocol: 'TCP', - }, - ], - }, - ], - }, -}; +import { useState } from 'react'; export function IngressDetails(props) { const { t } = useTranslation(); @@ -49,8 +19,6 @@ export function IngressDetails(props) { const [healthyPods, setHealthyPods] = useState(0); const calculateTotalPorts = ingress => { - if (ingress.metadata.name === 'cafe-ingress') - ingress.status = exampleStatus; let allPorts = 0; ingress?.status?.loadBalancer?.ingress?.forEach(element => { @@ -61,7 +29,6 @@ export function IngressDetails(props) { }; const calculatePortsWithoutErrors = ingress => { - //ingress.status = exampleStatus; let healthyPods = 0; ingress?.status?.loadBalancer?.ingress?.forEach(element => { diff --git a/src/resources/Ingresses/IngressStatus.js b/src/resources/Ingresses/IngressStatus.js index cff020fe74..9dd1c6338e 100644 --- a/src/resources/Ingresses/IngressStatus.js +++ b/src/resources/Ingresses/IngressStatus.js @@ -4,8 +4,6 @@ import { ConditionList } from 'shared/components/ConditionList/ConditionList'; import { EMPTY_TEXT_PLACEHOLDER } from 'shared/constants'; import { spacing } from '@ui5/webcomponents-react-base'; import './IngressStatus.scss'; -import { Label } from 'shared/ResourceForm/components/Label'; -import { Badge } from 'components/Extensibility/components/Badge'; export const IngressStatus = ({ resource }) => { const { t } = useTranslation(); @@ -19,14 +17,24 @@ export const IngressStatus = ({ resource }) => { conditions={ingresses.map(ingress => ({ header: { titleText: ingress.hostname ? ( -
+
+ + {`${t('ingresses.labels.host-name')}:`} + {`${ingress.hostname}`} -
) : ( -
+
+ + {`${t('ingresses.labels.ip')}:`} + {`${ingress.ip}`} -
), }, diff --git a/src/resources/Ingresses/IngressStatus.scss b/src/resources/Ingresses/IngressStatus.scss index fa2474261c..4657204950 100644 --- a/src/resources/Ingresses/IngressStatus.scss +++ b/src/resources/Ingresses/IngressStatus.scss @@ -1,10 +1,4 @@ .load-balancers { - &__header { - display: flex; - align-items: center; - gap: 1rem; - } - .expandable-item__message:not(.load-balancers__content) { .title { margin-left: 0.5rem !important; From 97a9ae5135acfa388321e79e58eaed55a79ab82b Mon Sep 17 00:00:00 2001 From: Oliwia Gowor Date: Wed, 21 Aug 2024 22:56:59 +0200 Subject: [PATCH 4/5] fixes & adjust tests --- src/resources/Ingresses/IngressDetails.js | 9 ++++++--- src/resources/Ingresses/IngressSpecification.js | 8 ++++++-- tests/integration/fixtures/test-ingress.yaml | 4 ++++ tests/integration/tests/namespace/test-ingresses.spec.js | 8 ++++++++ 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/resources/Ingresses/IngressDetails.js b/src/resources/Ingresses/IngressDetails.js index 0487a99d98..da136300b7 100644 --- a/src/resources/Ingresses/IngressDetails.js +++ b/src/resources/Ingresses/IngressDetails.js @@ -42,9 +42,12 @@ export function IngressDetails(props) { const customComponents = []; - customComponents.push(resource => ( - - )); + customComponents.push( + resource => + (resource.spec?.ingressClassName || resource.spec?.tls) && ( + + ), + ); customComponents.push(resource => resource.spec.defaultBackend ? ( diff --git a/src/resources/Ingresses/IngressSpecification.js b/src/resources/Ingresses/IngressSpecification.js index 8463451996..60febcd983 100644 --- a/src/resources/Ingresses/IngressSpecification.js +++ b/src/resources/Ingresses/IngressSpecification.js @@ -2,6 +2,7 @@ import { useTranslation } from 'react-i18next'; import { GenericList } from 'shared/components/GenericList/GenericList'; import { LayoutPanelRow } from 'shared/components/LayoutPanelRow/LayoutPanelRow'; import { UI5Panel } from 'shared/components/UI5Panel/UI5Panel'; +import { EMPTY_TEXT_PLACEHOLDER } from 'shared/constants'; export const IngressSpecification = ({ resource }) => { const { t } = useTranslation(); @@ -9,7 +10,7 @@ export const IngressSpecification = ({ resource }) => { return ( <> - {resource.spec && ( + {resource.spec.ingressClassName && ( { t('ingresses.labels.hosts'), t('ingresses.labels.secret-name'), ]} - rowRenderer={tls => [tls?.hosts.join(', '), tls?.secretName]} + rowRenderer={tls => [ + tls?.hosts?.join(', ') ?? EMPTY_TEXT_PLACEHOLDER, + tls?.secretName ?? EMPTY_TEXT_PLACEHOLDER, + ]} entries={resource.spec?.tls} searchSettings={{ showSearchField: false, diff --git a/tests/integration/fixtures/test-ingress.yaml b/tests/integration/fixtures/test-ingress.yaml index 60f4f4781e..53afa36d4b 100644 --- a/tests/integration/fixtures/test-ingress.yaml +++ b/tests/integration/fixtures/test-ingress.yaml @@ -27,3 +27,7 @@ spec: name: web port: number: 8080 + tls: + - hosts: + - test.com + secretName: tests-tls-secret diff --git a/tests/integration/tests/namespace/test-ingresses.spec.js b/tests/integration/tests/namespace/test-ingresses.spec.js index c7ca1ec89a..3e4e9917e7 100644 --- a/tests/integration/tests/namespace/test-ingresses.spec.js +++ b/tests/integration/tests/namespace/test-ingresses.spec.js @@ -47,6 +47,14 @@ context('Test Ingresses', () => { .contains('ui5-title', NAME) .should('be.visible'); + cy.getMidColumn() + .contains(/specification/i) + .should('be.visible'); + + cy.getMidColumn() + .contains(/tls/i) + .should('be.visible'); + cy.getMidColumn() .get('#content-wrap') .contains(/rules/i) From 2be4655c2afcadf09799014723eb7f53041d18ee Mon Sep 17 00:00:00 2001 From: Oliwia Gowor Date: Thu, 22 Aug 2024 11:01:13 +0200 Subject: [PATCH 5/5] review adjustments --- src/resources/Ingresses/IngressCreate.js | 6 ++- src/resources/Ingresses/IngressDetails.js | 32 +++++------- .../Ingresses/IngressSpecification.js | 7 ++- src/resources/Ingresses/IngressStatus.js | 49 +++++++++---------- .../ExpandableListItem/ExpandableListItem.tsx | 14 ++++-- .../tests/namespace/test-ingresses.spec.js | 10 ++++ 6 files changed, 64 insertions(+), 54 deletions(-) diff --git a/src/resources/Ingresses/IngressCreate.js b/src/resources/Ingresses/IngressCreate.js index 75d8ca04c5..16fdfa9019 100644 --- a/src/resources/Ingresses/IngressCreate.js +++ b/src/resources/Ingresses/IngressCreate.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import * as _ from 'lodash'; @@ -19,6 +19,9 @@ export default function IngressCreate({ const [ingress, setIngress] = useState( _.cloneDeep(initialIngress) || createIngressTemplate(namespaceId), ); + const [initialUnchangedResource] = useState( + initialIngress || createIngressTemplate(namespaceId), + ); const [initialResource] = useState( initialIngress || createIngressTemplate(namespaceId), ); @@ -31,6 +34,7 @@ export default function IngressCreate({ singularName={t('ingresses.name_singular')} resource={ingress} initialResource={initialResource} + initialUnchangedResource={initialUnchangedResource} setResource={setIngress} onlyYaml onChange={onChange} diff --git a/src/resources/Ingresses/IngressDetails.js b/src/resources/Ingresses/IngressDetails.js index da136300b7..ea80654ba5 100644 --- a/src/resources/Ingresses/IngressDetails.js +++ b/src/resources/Ingresses/IngressDetails.js @@ -15,29 +15,22 @@ import { useState } from 'react'; export function IngressDetails(props) { const { t } = useTranslation(); - const [totalPods, setTotalPods] = useState(0); - const [healthyPods, setHealthyPods] = useState(0); + const [totalPorts, setTotalPorts] = useState(0); + const [healthyPorts, setHealthyPorts] = useState(0); - const calculateTotalPorts = ingress => { + const calculatePorts = ingress => { let allPorts = 0; - - ingress?.status?.loadBalancer?.ingress?.forEach(element => { - element?.ports?.forEach(() => allPorts++); - }); - - setTotalPods(allPorts); - }; - - const calculatePortsWithoutErrors = ingress => { - let healthyPods = 0; + let healthyPorts = 0; ingress?.status?.loadBalancer?.ingress?.forEach(element => { element?.ports?.forEach(port => { - if (!port.error) healthyPods++; + allPorts++; + if (!port.error) healthyPorts++; }); }); - setHealthyPods(healthyPods); + setTotalPorts(allPorts); + setHealthyPorts(healthyPorts); }; const customComponents = []; @@ -74,12 +67,11 @@ export function IngressDetails(props) { )); const statusBadge = resource => { - calculateTotalPorts(resource); - calculatePortsWithoutErrors(resource); + calculatePorts(resource); const portsStatus = - totalPods === 0 + totalPorts === 0 ? 'Information' - : totalPods === healthyPods + : totalPorts === healthyPorts ? 'Success' : 'Error'; @@ -87,7 +79,7 @@ export function IngressDetails(props) { {`${healthyPods} / ${totalPods}`} + >{`${healthyPorts} / ${totalPorts}`} ); }; diff --git a/src/resources/Ingresses/IngressSpecification.js b/src/resources/Ingresses/IngressSpecification.js index 60febcd983..52f25f727c 100644 --- a/src/resources/Ingresses/IngressSpecification.js +++ b/src/resources/Ingresses/IngressSpecification.js @@ -1,6 +1,7 @@ import { useTranslation } from 'react-i18next'; import { GenericList } from 'shared/components/GenericList/GenericList'; import { LayoutPanelRow } from 'shared/components/LayoutPanelRow/LayoutPanelRow'; +import { Tokens } from 'shared/components/Tokens'; import { UI5Panel } from 'shared/components/UI5Panel/UI5Panel'; import { EMPTY_TEXT_PLACEHOLDER } from 'shared/constants'; @@ -24,7 +25,11 @@ export const IngressSpecification = ({ resource }) => { t('ingresses.labels.secret-name'), ]} rowRenderer={tls => [ - tls?.hosts?.join(', ') ?? EMPTY_TEXT_PLACEHOLDER, + tls?.hosts ? ( + + ) : ( + EMPTY_TEXT_PLACEHOLDER + ), tls?.secretName ?? EMPTY_TEXT_PLACEHOLDER, ]} entries={resource.spec?.tls} diff --git a/src/resources/Ingresses/IngressStatus.js b/src/resources/Ingresses/IngressStatus.js index 9dd1c6338e..806562e1c7 100644 --- a/src/resources/Ingresses/IngressStatus.js +++ b/src/resources/Ingresses/IngressStatus.js @@ -39,24 +39,20 @@ export const IngressStatus = ({ resource }) => { ), }, customContent: [ - ...(ingress.hostname - ? [ - { - header: t('ingresses.labels.host-name'), - value: ingress.hostname, - className: 'load-balancers__content', - }, - ] - : []), - ...(ingress.ip - ? [ - { - header: t('ingresses.labels.ip'), - value: ingress.ip, - className: 'load-balancers__content', - }, - ] - : []), + ingress.hostname + ? { + header: t('ingresses.labels.host-name'), + value: ingress.hostname, + className: 'load-balancers__content', + } + : null, + ingress.ip + ? { + header: t('ingresses.labels.ip'), + value: ingress.ip, + className: 'load-balancers__content', + } + : null, { header: t('ingresses.labels.ports'), value: ingress.ports ? ( @@ -73,15 +69,13 @@ export const IngressStatus = ({ resource }) => { header: t('ingresses.labels.protocol'), value: port.protocol, } - : {}, - ...(port.error - ? [ - { - header: 'Error', - value: port.error, - }, - ] - : []), + : null, + port.error + ? { + header: 'Error', + value: port.error, + } + : null, ], }; })} @@ -89,6 +83,7 @@ export const IngressStatus = ({ resource }) => { ) : ( EMPTY_TEXT_PLACEHOLDER ), + className: ingress.ports ? '' : 'load-balancers__content', }, ], }))} diff --git a/src/shared/components/ExpandableListItem/ExpandableListItem.tsx b/src/shared/components/ExpandableListItem/ExpandableListItem.tsx index 2f40ba0f8c..545afc3a9b 100644 --- a/src/shared/components/ExpandableListItem/ExpandableListItem.tsx +++ b/src/shared/components/ExpandableListItem/ExpandableListItem.tsx @@ -77,17 +77,21 @@ export const ExpandableListItem = ({ {customContent && customContent.map((element, index) => (
-
- {`${element.header}:`} -
- {element.value} + {element?.header && ( +
+ {`${element?.header}:`} +
+ )} + {element?.value}
))} diff --git a/tests/integration/tests/namespace/test-ingresses.spec.js b/tests/integration/tests/namespace/test-ingresses.spec.js index 3e4e9917e7..863db5e347 100644 --- a/tests/integration/tests/namespace/test-ingresses.spec.js +++ b/tests/integration/tests/namespace/test-ingresses.spec.js @@ -55,6 +55,16 @@ context('Test Ingresses', () => { .contains(/tls/i) .should('be.visible'); + cy.getMidColumn() + .get('ui5-table') + .contains('test.com') + .should('be.visible'); + + cy.getMidColumn() + .get('ui5-table') + .contains('tests-tls-secret') + .should('be.visible'); + cy.getMidColumn() .get('#content-wrap') .contains(/rules/i)