From 41634e1d5057b592eb3f64eae0d751fa978eeb2e Mon Sep 17 00:00:00 2001 From: Pedro Pereira Date: Tue, 10 Sep 2024 17:19:52 +0100 Subject: [PATCH 1/6] migrating project to OSM 16 --- cfs-portal/src/api/api.tsx | 2 +- cfs-portal/src/components/InstanceGrid/index.tsx | 2 +- docker-compose.yml | 8 ++++---- osm-mec-helm-chart/templates/meao-deployment.yaml | 4 ++-- osm-mec-helm-chart/templates/oss-deployment.yaml | 4 ++-- osm-mec-helm-chart/templates/oss-service.yaml | 4 ++-- oss/utils/container_info_thread.py | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cfs-portal/src/api/api.tsx b/cfs-portal/src/api/api.tsx index e6a6baa..77b25a3 100644 --- a/cfs-portal/src/api/api.tsx +++ b/cfs-portal/src/api/api.tsx @@ -1,7 +1,7 @@ import axios from "axios"; const api = axios.create({ - baseURL: 'http://10.255.32.88:8080/oss/v1' + baseURL: 'http://10.255.32.132:30880/oss/v1' }); // App Package diff --git a/cfs-portal/src/components/InstanceGrid/index.tsx b/cfs-portal/src/components/InstanceGrid/index.tsx index 90bd816..34daf02 100644 --- a/cfs-portal/src/components/InstanceGrid/index.tsx +++ b/cfs-portal/src/components/InstanceGrid/index.tsx @@ -74,7 +74,7 @@ const InstanceGrid = ({ minimalConfig = false, instanceCount }: InstanceGridProp }, []); useEffect(() => { - const ws = new WebSocket('ws://10.255.32.88:8001'); + const ws = new WebSocket('ws://10.255.32.132:30801'); setSocket(ws); }, []); diff --git a/docker-compose.yml b/docker-compose.yml index 0ef0408..a535d78 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,10 +23,10 @@ services: depends_on: - mongo environment: - - OSM_HOSTNAME=10.255.32.88:9999 + - OSM_HOSTNAME=nbi.10.255.32.132.nip.io - OSS_PORT=8080 - OSS_WS_PORT=8001 - - KAFKA_BOOTSTRAP_SERVERS=10.255.32.88:9999:14000 + - KAFKA_BOOTSTRAP_SERVERS=10.255.32.132:31402 - MONGO_USER=root - MONGO_PASSWORD=pass restart: on-failure @@ -42,8 +42,8 @@ services: # - zookeeper - mongo environment: - - OSM_HOSTNAME=10.255.32.88:9999 - - KAFKA_BOOTSTRAP_SERVERS=10.255.32.88:9999:14000 + - OSM_HOSTNAME=nbi.10.255.32.132.nip.io + - KAFKA_BOOTSTRAP_SERVERS=10.255.32.132:31402 - MONGO_USER=root - MONGO_PASSWORD=pass restart: on-failure diff --git a/osm-mec-helm-chart/templates/meao-deployment.yaml b/osm-mec-helm-chart/templates/meao-deployment.yaml index 7a75187..8ee6107 100644 --- a/osm-mec-helm-chart/templates/meao-deployment.yaml +++ b/osm-mec-helm-chart/templates/meao-deployment.yaml @@ -19,13 +19,13 @@ spec: containers: - env: - name: KAFKA_BOOTSTRAP_SERVERS - value: 10.255.32.88:14000 + value: 10.255.32.132:31402 - name: MONGO_PASSWORD value: pass - name: MONGO_USER value: root - name: OSM_HOSTNAME - value: 10.255.32.88:9999 + value: 10.255.32.132.nip.io image: localhost:5000/meao:latest imagePullPolicy: Always name: meao diff --git a/osm-mec-helm-chart/templates/oss-deployment.yaml b/osm-mec-helm-chart/templates/oss-deployment.yaml index 64cedd8..58342a7 100644 --- a/osm-mec-helm-chart/templates/oss-deployment.yaml +++ b/osm-mec-helm-chart/templates/oss-deployment.yaml @@ -19,13 +19,13 @@ spec: containers: - env: - name: KAFKA_BOOTSTRAP_SERVERS - value: 10.255.32.88:9999:14000 + value: 10.255.32.132:31402 - name: MONGO_PASSWORD value: pass - name: MONGO_USER value: root - name: OSM_HOSTNAME - value: 10.255.32.88:9999 + value: nbi.10.255.32.132.nip.io - name: OSS_PORT value: "8080" - name: OSS_WS_PORT diff --git a/osm-mec-helm-chart/templates/oss-service.yaml b/osm-mec-helm-chart/templates/oss-service.yaml index febc290..f2f1e99 100644 --- a/osm-mec-helm-chart/templates/oss-service.yaml +++ b/osm-mec-helm-chart/templates/oss-service.yaml @@ -10,10 +10,10 @@ spec: - name: "8080" port: 8080 targetPort: 8080 - nodePort: 8080 + nodePort: 30880 - name: "8001" port: 8001 targetPort: 8001 - nodePort: 8001 + nodePort: 30801 selector: app: oss diff --git a/oss/utils/container_info_thread.py b/oss/utils/container_info_thread.py index 1fdbe6a..46c15e4 100644 --- a/oss/utils/container_info_thread.py +++ b/oss/utils/container_info_thread.py @@ -25,10 +25,10 @@ def start(self): def get_containers_info(): while True: try: - response = requests.get("http://container-data-api:8000/containerInfo") + response = requests.get("http://10.255.32.132:8000/containerInfo") for container in response.json()["ContainerInfo"]: node_specs = requests.get( - "http://container-data-api:8000/nodeSpecs/" + container["node"] + "http://10.255.32.132:8000/nodeSpecs/" + container["node"] ).json() containers[container["id"]] = { "ns": container["ns_id"], From 67e0821cb37d24fb8da4369d09b300e8facccfeb Mon Sep 17 00:00:00 2001 From: Pedro Pereira Date: Wed, 11 Sep 2024 17:44:39 +0100 Subject: [PATCH 2/6] small change --- oss/utils/container_info_thread.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oss/utils/container_info_thread.py b/oss/utils/container_info_thread.py index 46c15e4..9e2aeca 100644 --- a/oss/utils/container_info_thread.py +++ b/oss/utils/container_info_thread.py @@ -25,10 +25,10 @@ def start(self): def get_containers_info(): while True: try: - response = requests.get("http://10.255.32.132:8000/containerInfo") + response = requests.get("http://meao-monitoring:8000/containerInfo") for container in response.json()["ContainerInfo"]: node_specs = requests.get( - "http://10.255.32.132:8000/nodeSpecs/" + container["node"] + "http://meao-monitoring:8000/nodeSpecs/" + container["node"] ).json() containers[container["id"]] = { "ns": container["ns_id"], From 538a12d0078cabf71c2a7d1896aab6fb3ccfbeb8 Mon Sep 17 00:00:00 2001 From: Pedro Pereira Date: Mon, 23 Sep 2024 00:10:23 +0100 Subject: [PATCH 3/6] changed the OSS and MEAO communication to use the Kafka bus --- docker-compose.yml | 4 +- .../templates/meao-deployment.yaml | 2 +- .../templates/oss-deployment.yaml | 2 +- oss/app.py | 8 +-- oss/utils/container_info_thread.py | 42 --------------- .../kafka/callbacks/get_container_info.py | 27 ++++++++++ oss/utils/kafka/callbacks/get_latency.py | 6 +-- oss/utils/kafka/callbacks/get_metrics.py | 2 +- oss/utils/threads/__init__.py | 1 + oss/utils/threads/container_info_thread.py | 54 ------------------- oss/utils/threads/mec_apps_thread.py | 42 +++++++++++++++ 11 files changed, 82 insertions(+), 108 deletions(-) delete mode 100644 oss/utils/container_info_thread.py create mode 100644 oss/utils/kafka/callbacks/get_container_info.py delete mode 100644 oss/utils/threads/container_info_thread.py create mode 100644 oss/utils/threads/mec_apps_thread.py diff --git a/docker-compose.yml b/docker-compose.yml index a535d78..9af048e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,7 +26,7 @@ services: - OSM_HOSTNAME=nbi.10.255.32.132.nip.io - OSS_PORT=8080 - OSS_WS_PORT=8001 - - KAFKA_BOOTSTRAP_SERVERS=10.255.32.132:31402 + - KAFKA_BOOTSTRAP_SERVERS=10.255.32.132:31999 - MONGO_USER=root - MONGO_PASSWORD=pass restart: on-failure @@ -43,7 +43,7 @@ services: - mongo environment: - OSM_HOSTNAME=nbi.10.255.32.132.nip.io - - KAFKA_BOOTSTRAP_SERVERS=10.255.32.132:31402 + - KAFKA_BOOTSTRAP_SERVERS=10.255.32.132:31999 - MONGO_USER=root - MONGO_PASSWORD=pass restart: on-failure diff --git a/osm-mec-helm-chart/templates/meao-deployment.yaml b/osm-mec-helm-chart/templates/meao-deployment.yaml index 8ee6107..36b36cd 100644 --- a/osm-mec-helm-chart/templates/meao-deployment.yaml +++ b/osm-mec-helm-chart/templates/meao-deployment.yaml @@ -19,7 +19,7 @@ spec: containers: - env: - name: KAFKA_BOOTSTRAP_SERVERS - value: 10.255.32.132:31402 + value: 10.255.32.132:31999 - name: MONGO_PASSWORD value: pass - name: MONGO_USER diff --git a/osm-mec-helm-chart/templates/oss-deployment.yaml b/osm-mec-helm-chart/templates/oss-deployment.yaml index 58342a7..d73008a 100644 --- a/osm-mec-helm-chart/templates/oss-deployment.yaml +++ b/osm-mec-helm-chart/templates/oss-deployment.yaml @@ -19,7 +19,7 @@ spec: containers: - env: - name: KAFKA_BOOTSTRAP_SERVERS - value: 10.255.32.132:31402 + value: 10.255.32.132:31999 - name: MONGO_PASSWORD value: pass - name: MONGO_USER diff --git a/oss/app.py b/oss/app.py index 8faf746..5a8786e 100644 --- a/oss/app.py +++ b/oss/app.py @@ -7,8 +7,9 @@ from utils.kafka.callbacks.error_handler import callback as error_handler from utils.kafka.callbacks.get_metrics import callback as get_metrics from utils.kafka.callbacks.get_latency import callback as get_latency -from utils.threads import (ContainerInfoThread, KafkaConsumerThread, - WebSocketServiceThread) +from utils.kafka.callbacks.get_container_info import callback as get_container_info +from utils.threads import (KafkaConsumerThread, + WebSocketServiceThread, SendMECAppsThread) def main(): @@ -17,8 +18,9 @@ def main(): KafkaConsumerThread(cherrypy.engine, "responses", error_handler).subscribe() KafkaConsumerThread(cherrypy.engine, "k8s-cluster", get_metrics).subscribe() KafkaConsumerThread(cherrypy.engine, "ue-lat", get_latency).subscribe() - ContainerInfoThread(cherrypy.engine).subscribe() + KafkaConsumerThread(cherrypy.engine, "meao-oss", get_container_info).subscribe() WebSocketServiceThread(cherrypy.engine).subscribe() + SendMECAppsThread(cherrypy.engine).subscribe() dispatcher = set_routes() diff --git a/oss/utils/container_info_thread.py b/oss/utils/container_info_thread.py deleted file mode 100644 index 9e2aeca..0000000 --- a/oss/utils/container_info_thread.py +++ /dev/null @@ -1,42 +0,0 @@ -import threading -import time - -import requests -from cherrypy.process import plugins - -containers = {} - - -class ContainerInfoThread(plugins.SimplePlugin): - """Background thread that mapps container id to ns id""" - - def __init__(self, bus): - super().__init__(bus) - self.t = None - - def start(self): - """Plugin entrypoint""" - - self.t = threading.Thread(target=get_containers_info) - self.t.daemon = True - self.t.start() - - -def get_containers_info(): - while True: - try: - response = requests.get("http://meao-monitoring:8000/containerInfo") - for container in response.json()["ContainerInfo"]: - node_specs = requests.get( - "http://meao-monitoring:8000/nodeSpecs/" + container["node"] - ).json() - containers[container["id"]] = { - "ns": container["ns_id"], - "node_specs": node_specs["NodeSpecs"], - } - containers[container["id"]]["node_specs"]["prev_cpu"] = 0 - containers[container["id"]]["node_specs"]["prev_timestamp"] = 0 - except Exception as e: - pass - - time.sleep(15) diff --git a/oss/utils/kafka/callbacks/get_container_info.py b/oss/utils/kafka/callbacks/get_container_info.py new file mode 100644 index 0000000..e91b87f --- /dev/null +++ b/oss/utils/kafka/callbacks/get_container_info.py @@ -0,0 +1,27 @@ +from ...threads.mec_apps_thread import containers +from ...threads.websocket_service_thread import lat_queue + + +def callback(data): + if "containerInfo" in data and "nodeSpecs" in data: + print(data) + idsMonitored = [] + for containerName, container in data["containerInfo"].items(): + idsMonitored.append(containerName) + node_specs = data["nodeSpecs"] + if containerName not in containers: + containers[containerName] = { + "ns": container["ns_id"], + "node": container["node"], + "node_specs": node_specs[container["node"]], + } + containers[containerName]["node_specs"]["prev_cpu"] = 0 + containers[containerName]["node_specs"]["prev_timestamp"] = 0 + idsToDelete = [] + for container_id in containers.keys(): + if container_id not in idsMonitored: + idsToDelete.append(container_id) + for id in idsToDelete: + del containers[id] + elif "warning" in data: + pass \ No newline at end of file diff --git a/oss/utils/kafka/callbacks/get_latency.py b/oss/utils/kafka/callbacks/get_latency.py index 25ee43e..ede9aab 100644 --- a/oss/utils/kafka/callbacks/get_latency.py +++ b/oss/utils/kafka/callbacks/get_latency.py @@ -1,9 +1,8 @@ -from ...threads.container_info_thread import containers +from ...threads.mec_apps_thread import containers from ...threads.websocket_service_thread import lat_queue def callback(data): - print(containers.keys()) for container_id in containers.keys(): temp_data = { "k3s-worker1-pedrocjdpereira": data["k3s-worker1-pedrocjdpereira"], @@ -11,5 +10,4 @@ def callback(data): } temp_data["node"] = containers[container_id]["node"] temp_data["appi_id"] = containers[container_id]["ns"] - lat_queue.put(temp_data) - print(temp_data) \ No newline at end of file + lat_queue.put(temp_data) \ No newline at end of file diff --git a/oss/utils/kafka/callbacks/get_metrics.py b/oss/utils/kafka/callbacks/get_metrics.py index 6f409a6..ae70b47 100644 --- a/oss/utils/kafka/callbacks/get_metrics.py +++ b/oss/utils/kafka/callbacks/get_metrics.py @@ -1,4 +1,4 @@ -from ...threads.container_info_thread import containers +from ...threads.mec_apps_thread import containers from ...threads.websocket_service_thread import metrics_queue diff --git a/oss/utils/threads/__init__.py b/oss/utils/threads/__init__.py index ecc7627..a782aa1 100644 --- a/oss/utils/threads/__init__.py +++ b/oss/utils/threads/__init__.py @@ -1,3 +1,4 @@ from .container_info_thread import ContainerInfoThread from .kafka_consumer_thread import KafkaConsumerThread from .websocket_service_thread import WebSocketServiceThread +from .mec_apps_thread import SendMECAppsThread diff --git a/oss/utils/threads/container_info_thread.py b/oss/utils/threads/container_info_thread.py deleted file mode 100644 index 7f1afc4..0000000 --- a/oss/utils/threads/container_info_thread.py +++ /dev/null @@ -1,54 +0,0 @@ -import threading -import time - -import requests -from cherrypy.process import plugins - -containers = {} - - -class ContainerInfoThread(plugins.SimplePlugin): - """Background thread that mapps container id to ns id""" - - def __init__(self, bus): - super().__init__(bus) - self.t = None - - def start(self): - """Plugin entrypoint""" - - self.t = threading.Thread(target=get_containers_info) - self.t.daemon = True - self.t.start() - - -def get_containers_info(): - while True: - try: - response = requests.get("http://meao-monitoring:8000/containerInfo") - print(response) - idsMonitored = [] - for containerName, container in (response.json()["ContainerInfo"]).items(): - idsMonitored.append(containerName) - node_specs = requests.get( - "http://meao-monitoring:8000/nodeSpecs/" + container["node"] - ).json() - if containerName not in containers: - containers[containerName] = { - "ns": container["ns_id"], - "node": container["node"], - "node_specs": node_specs["NodeSpecs"], - } - containers[containerName]["node_specs"]["prev_cpu"] = 0 - containers[containerName]["node_specs"]["prev_timestamp"] = 0 - idsToDelete = [] - for container_id in containers.keys(): - if container_id not in idsMonitored: - idsToDelete.append(container_id) - for id in idsToDelete: - del containers[id] - - except Exception as e: - pass - - time.sleep(15) diff --git a/oss/utils/threads/mec_apps_thread.py b/oss/utils/threads/mec_apps_thread.py new file mode 100644 index 0000000..b19660f --- /dev/null +++ b/oss/utils/threads/mec_apps_thread.py @@ -0,0 +1,42 @@ +import threading +import time +import json + +from cherrypy.process import plugins + +from utils.db import DB +from utils.kafka import KafkaUtils, producer + +containers = {} + +class SendMECAppsThread(plugins.SimplePlugin): + """Background thread that sends MEC Apps information""" + + def __init__(self, bus): + super().__init__(bus) + self.t = None + + def start(self): + """Plugin entrypoint""" + self.t = threading.Thread(target=send_mec_apps) + self.t.daemon = True + self.t.start() + + +def send_mec_apps(): + while True: + try: + mec_apps = DB._list("appis") + for mec_app in mec_apps: + if '_id' in mec_app: + mec_app['_id'] = str(mec_app['_id']) + + KafkaUtils.send_message( + producer, + "meao-oss", + {"mec_apps": mec_apps}, + ) + + time.sleep(5) + except Exception as e: + raise e \ No newline at end of file From fb940301e1c80be117b439cc238e67fc04ad28c4 Mon Sep 17 00:00:00 2001 From: Pedro Pereira Date: Mon, 23 Sep 2024 00:30:04 +0100 Subject: [PATCH 4/6] small fixes --- oss/utils/kafka/get_metrics.py | 2 +- oss/utils/threads/__init__.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/oss/utils/kafka/get_metrics.py b/oss/utils/kafka/get_metrics.py index 5436733..46722ea 100644 --- a/oss/utils/kafka/get_metrics.py +++ b/oss/utils/kafka/get_metrics.py @@ -1,4 +1,4 @@ -from ..container_info_thread import containers +from ..threads.mec_apps_thread import containers def callback(data): diff --git a/oss/utils/threads/__init__.py b/oss/utils/threads/__init__.py index a782aa1..199b422 100644 --- a/oss/utils/threads/__init__.py +++ b/oss/utils/threads/__init__.py @@ -1,4 +1,3 @@ -from .container_info_thread import ContainerInfoThread from .kafka_consumer_thread import KafkaConsumerThread from .websocket_service_thread import WebSocketServiceThread from .mec_apps_thread import SendMECAppsThread From 37ee8eff3aee0923c9caafb40424388d6c58ee69 Mon Sep 17 00:00:00 2001 From: Pedro Pereira Date: Mon, 23 Sep 2024 23:22:49 +0100 Subject: [PATCH 5/6] addition of warnings from the MEAO to the OSS to be displayed on the dashboard when no suitable nodes are found for migration --- .../src/components/InstanceGrid/index.tsx | 34 +++++++++++++++---- .../kafka/callbacks/get_container_info.py | 26 ++++++++++++-- oss/utils/kafka/callbacks/get_metrics.py | 1 + 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/cfs-portal/src/components/InstanceGrid/index.tsx b/cfs-portal/src/components/InstanceGrid/index.tsx index 34daf02..ffb01c3 100644 --- a/cfs-portal/src/components/InstanceGrid/index.tsx +++ b/cfs-portal/src/components/InstanceGrid/index.tsx @@ -86,22 +86,22 @@ const InstanceGrid = ({ minimalConfig = false, instanceCount }: InstanceGridProp socket.onmessage = (event) => { const data = JSON.parse(event.data); setMetrics((prevMetrics) => { - console.log(data) console.log(prevMetrics) - if(data.appi_id != undefined){ + if(data.appi_id !== undefined){ if(!prevMetrics){ prevMetrics = {} } if (!(data.appi_id in prevMetrics)){ prevMetrics[data.appi_id] = {} } - if (data.mem_load != undefined && data.cpu_load != undefined) { + if (data.mem_load !== undefined && data.cpu_load !== undefined && data.warning !== undefined) { return { ...prevMetrics, [data.appi_id]: { ...prevMetrics[data.appi_id], memLoad: data.mem_load, cpuLoad: data.cpu_load, + warning: data.warning, } }; } @@ -170,7 +170,7 @@ const InstanceGrid = ({ minimalConfig = false, instanceCount }: InstanceGridProp const node = metrics && metrics[params.row.id as string]?.node; return ( - {node != undefined ? ( + {node !== undefined ? ( <> - {lat != undefined ? ( + {lat !== undefined ? ( <> - {memLoad != undefined ? ( + {memLoad !== undefined ? ( <> - {cpuLoad != undefined ? ( + {cpuLoad !== undefined ? ( <> renderConfigStatus(params.row['config-status'] as ConfigStatus) }], + ...minimalConfig ? [] : [{ + field: 'warnings', + headerName: '', + width: 100, + renderCell: (params: any) => { + const warning = metrics && metrics[params.row.id as string]?.warning; + + if (warning !== null) { + return ( + + + {renderOperationalStatus(OperationalStatus.FAILED)} + + + ); + } + + } + }], ...minimalConfig ? [] : [{ field: 'actions', headerName: '', diff --git a/oss/utils/kafka/callbacks/get_container_info.py b/oss/utils/kafka/callbacks/get_container_info.py index e91b87f..7d3db13 100644 --- a/oss/utils/kafka/callbacks/get_container_info.py +++ b/oss/utils/kafka/callbacks/get_container_info.py @@ -1,10 +1,10 @@ +import time from ...threads.mec_apps_thread import containers from ...threads.websocket_service_thread import lat_queue def callback(data): if "containerInfo" in data and "nodeSpecs" in data: - print(data) idsMonitored = [] for containerName, container in data["containerInfo"].items(): idsMonitored.append(containerName) @@ -23,5 +23,27 @@ def callback(data): idsToDelete.append(container_id) for id in idsToDelete: del containers[id] + elif "warning" in data: - pass \ No newline at end of file + current_time = time.time() + + warning = data["warning"] + container_name = warning["containerName"] + + if container_name in containers: + containers[container_name]["warning"] = { + "msg": warning["msg"], + "timer": current_time + } + + for container_name, container in containers.items(): + if "warning" not in container: + container["warning"] = { + "msg": None, + "timer": None, + } + elif container["warning"] and container["warning"]["timer"]: + current_time = time.time() + if current_time - container["warning"]["timer"] > 60: + container["warning"]["timer"] = None + container["warning"]["msg"] = None \ No newline at end of file diff --git a/oss/utils/kafka/callbacks/get_metrics.py b/oss/utils/kafka/callbacks/get_metrics.py index ae70b47..ef8e152 100644 --- a/oss/utils/kafka/callbacks/get_metrics.py +++ b/oss/utils/kafka/callbacks/get_metrics.py @@ -12,6 +12,7 @@ def callback(data): "appi_id": appi_id, "mem_load": get_mem_load(data, node_specs), "cpu_load": get_cpu_load(data, node_specs, container_id), + "warning" : containers[container_id]["warning"]["msg"], } metrics_queue.put(metrics) From 8a8b06af57614075f13c8f4d5190d657871b06e5 Mon Sep 17 00:00:00 2001 From: Pedro Pereira Date: Wed, 25 Sep 2024 10:04:46 +0100 Subject: [PATCH 6/6] small fix --- cfs-portal/src/components/InstanceGrid/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfs-portal/src/components/InstanceGrid/index.tsx b/cfs-portal/src/components/InstanceGrid/index.tsx index ffb01c3..ac23ad6 100644 --- a/cfs-portal/src/components/InstanceGrid/index.tsx +++ b/cfs-portal/src/components/InstanceGrid/index.tsx @@ -347,7 +347,7 @@ const InstanceGrid = ({ minimalConfig = false, instanceCount }: InstanceGridProp renderCell: (params: any) => { const warning = metrics && metrics[params.row.id as string]?.warning; - if (warning !== null) { + if (warning !== undefined && warning !== null) { return (