diff --git a/cyclops-ctrl/pkg/cluster/k8sclient/modules.go b/cyclops-ctrl/pkg/cluster/k8sclient/modules.go index c8880349..f592e93a 100644 --- a/cyclops-ctrl/pkg/cluster/k8sclient/modules.go +++ b/cyclops-ctrl/pkg/cluster/k8sclient/modules.go @@ -817,6 +817,7 @@ func (k *KubernetesClient) getPodsForNetworkPolicy(policy networkingv1.NetworkPo out = append(out, dto.Pod{ Name: item.Name, + Namespace: item.Namespace, Containers: containers, Node: item.Spec.NodeName, PodPhase: string(item.Status.Phase), diff --git a/cyclops-ui/src/components/k8s-resources/NetworkPolicy.tsx b/cyclops-ui/src/components/k8s-resources/NetworkPolicy.tsx new file mode 100644 index 00000000..751a7fa2 --- /dev/null +++ b/cyclops-ui/src/components/k8s-resources/NetworkPolicy.tsx @@ -0,0 +1,142 @@ +import { Divider, Alert, Table, Spin } from "antd"; +import React, { useCallback, useEffect, useState } from "react"; +import { mapResponseError } from "../../utils/api/errors"; +import { useResourceListActions } from "./ResourceList/ResourceListActionsContext"; +import ReactAce from "react-ace"; +import YAML from "yaml"; + +interface Props { + namespace: string; + name: string; +} + +interface NetworkPolicyData { + pods: []; + ingress: {}; + egress: {}; +} + +const NetworkPolicy = ({ namespace, name }: Props) => { + const [loading, setLoading] = useState(true); + const { fetchResource } = useResourceListActions(); + + const [networkPolicy, setNetworkPolicy] = useState({ + pods: [], + ingress: {}, + egress: {}, + }); + + const [error, setError] = useState({ + message: "", + description: "", + }); + + const fetchNetworkPolicy = useCallback(() => { + fetchResource("networking.k8s.io", "v1", "NetworkPolicy", namespace, name)() + .then((res) => { + setNetworkPolicy(res); + setLoading(false); + }) + .catch((error) => { + setError(mapResponseError(error)); + setLoading(false); + }); + }, [name, namespace, fetchResource]); + + useEffect(() => { + fetchNetworkPolicy(); + + const interval = setInterval(() => fetchNetworkPolicy(), 15000); + return () => { + clearInterval(interval); + }; + }, [fetchNetworkPolicy]); + + const editorHeight = (lines: number) => { + if (lines > 20) { + return "320px"; + } else { + return `${lines * 16}px`; + } + }; + + const stringifyRulesToYaml = (obj: any) => { + try { + return YAML.stringify(obj); + } catch (error) { + console.error("YAML stringify error:", error); + return `YAML stringify error: ${error}`; + } + }; + + if (loading) return ; + + return ( +
+ {error.message.length !== 0 && ( + { + setError({ + message: "", + description: "", + }); + }} + style={{ marginBottom: "20px" }} + /> + )} + + Ingress + + + + Egress + + + + Target pods + + + + +
+
+ ); +}; + +export default NetworkPolicy; diff --git a/cyclops-ui/src/components/k8s-resources/ResourceList/ResourceList.tsx b/cyclops-ui/src/components/k8s-resources/ResourceList/ResourceList.tsx index f1f95272..30f88f9c 100644 --- a/cyclops-ui/src/components/k8s-resources/ResourceList/ResourceList.tsx +++ b/cyclops-ui/src/components/k8s-resources/ResourceList/ResourceList.tsx @@ -47,6 +47,7 @@ import { mapResponseError } from "../../../utils/api/errors"; import { CheckboxChangeEvent } from "antd/es/checkbox"; import { Workload } from "../../../utils/k8s/workload"; import { useResourceListActions } from "./ResourceListActionsContext"; +import NetworkPolicy from "../NetworkPolicy"; interface Props { loadResources: boolean; @@ -340,6 +341,11 @@ const ResourceList = ({ case "ClusterRole": resourceDetails = ; break; + case "NetworkPolicy": + resourceDetails = ( + + ); + break; } let deletedWarning =

;