From b17b31ac10863348b6db896354da46292b8f1b20 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 10 Nov 2024 08:22:43 +0000 Subject: [PATCH] add new pages for different modules Signed-off-by: Eric --- public/components/app.tsx | 12 +- public/components/index.tsx | 2 + .../components/kubernetes/cluster/index.tsx | 23 +++ .../kubernetes/cluster/overview.tsx | 131 +++++++++++++ public/components/kubernetes/index.tsx | 8 + .../kubernetes/namespaces/index.tsx | 20 ++ .../kubernetes/namespaces/overview.tsx | 141 ++++++++++++++ public/components/kubernetes/node/details.tsx | 6 + public/components/kubernetes/node/index.tsx | 20 ++ .../components/kubernetes/node/overview.tsx | 132 +++++++++++++ public/components/kubernetes/overview.tsx | 181 ++++++++++++++++++ public/plugin.tsx | 50 ++--- 12 files changed, 688 insertions(+), 38 deletions(-) create mode 100644 public/components/kubernetes/cluster/index.tsx create mode 100644 public/components/kubernetes/index.tsx create mode 100644 public/components/kubernetes/namespaces/index.tsx create mode 100644 public/components/kubernetes/namespaces/overview.tsx create mode 100644 public/components/kubernetes/node/details.tsx create mode 100644 public/components/kubernetes/node/index.tsx create mode 100644 public/components/kubernetes/node/overview.tsx create mode 100644 public/components/kubernetes/overview.tsx diff --git a/public/components/app.tsx b/public/components/app.tsx index 4dc7c759ef..b5235f4dcb 100644 --- a/public/components/app.tsx +++ b/public/components/app.tsx @@ -24,6 +24,11 @@ import { Home as TraceAnalyticsHome } from './trace_analytics/home'; import { Home as GettingStartedHome } from './getting_started/home'; import { Home as OverviewHome } from './overview/home'; import { Home as KubernetesHome } from './kubernetes/home'; +import { ClusterOverview } from './kubernetes/cluster/overview'; +import { clusterOverviewHome } from './kubernetes/cluster'; +import { NodeOverview } from './kubernetes/node/overview'; +import { NamespacesOverviewHome } from './kubernetes/namespaces'; +import { KubernetesOverview } from './kubernetes/overview'; interface ObservabilityAppDeps { CoreStartProp: CoreStart; @@ -57,7 +62,10 @@ const pages = { dataconnections: DataConnectionsHome, gettingStarted: GettingStartedHome, overview: OverviewHome, - kubernetes: KubernetesHome, + kubernetesOverview: KubernetesOverview, + kubernetesCluster: clusterOverviewHome, + kubernetesNode: NodeOverview, + kubernetesNamespaces: NamespacesOverviewHome, }; export const App = ({ @@ -75,6 +83,7 @@ export const App = ({ dataSourceEnabled, savedObjectsMDSClient, defaultRoute, + AppMountParametersProp, }: ObservabilityAppDeps) => { const { chrome, http, notifications, savedObjects: _coreSavedObjects } = CoreStartProp; const parentBreadcrumb = { @@ -111,6 +120,7 @@ export const App = ({ setActionMenu={setActionMenu} savedObjectsMDSClient={savedObjectsMDSClient} defaultRoute={defaultRoute} + AppMountParametersProp={AppMountParametersProp} /> diff --git a/public/components/index.tsx b/public/components/index.tsx index 853d463b3b..db15cfaff8 100644 --- a/public/components/index.tsx +++ b/public/components/index.tsx @@ -28,6 +28,7 @@ export const Observability = ( ) => { const { setHeaderActionMenu } = AppMountParametersProp; const { dataSource } = DepsStart; + console.log('activated?'); ReactDOM.render( , AppMountParametersProp.element ); diff --git a/public/components/kubernetes/cluster/index.tsx b/public/components/kubernetes/cluster/index.tsx new file mode 100644 index 0000000000..5f024f4c1a --- /dev/null +++ b/public/components/kubernetes/cluster/index.tsx @@ -0,0 +1,23 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { Router, Route, Switch } from 'react-router-dom'; +import { ClusterOverview } from './overview'; +import { Home as ClusterDetails } from '../home'; + +export const clusterOverviewHome = (props) => { + console.log('clusterOverviewHome props: ', props); + return ( + + + + + + + ); +}; diff --git a/public/components/kubernetes/cluster/overview.tsx b/public/components/kubernetes/cluster/overview.tsx index a850c1690e..a24aaa10e0 100644 --- a/public/components/kubernetes/cluster/overview.tsx +++ b/public/components/kubernetes/cluster/overview.tsx @@ -2,3 +2,134 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ + +import React from 'react'; +// import { useNavigate } from 'react-router-dom'; +import { + EuiPage, + EuiPageBody, + EuiPageHeader, + EuiPageHeaderSection, + EuiTitle, + EuiFlexGroup, + EuiFlexItem, + EuiCard, + EuiPanel, + EuiTable, + EuiTableHeader, + EuiTableHeaderCell, + EuiTableBody, + EuiTableRow, + EuiTableRowCell, + EuiSpacer, + EuiBadge, + EuiLink, +} from '@elastic/eui'; + +export const ClusterOverview = (props) => { + console.log('clusterOverviewHome props: ', props); + // const navigate = useNavigate(); + const fakeData = [ + { + clusterName: 'eks-cluster-with-vpc', + provider: 'digitalocean', + nodes: 2, + cpuUsage: { avg: '0.607 cores', max: '1.45 cores' }, + memoryUsage: { avg: '4.66 GiB', max: '5.01 GiB' }, + alerts: 2, + resourceUsage: 'low', + }, + ]; + + // const handleClusterClick = (clusterName: string) => { + // navigate(`/${clusterName}`); + // }; + + return ( + + + + + +

Clusters

+
+
+
+ + + + + {/* + + + + + + + + + + + + */} + + + + Cluster + Provider + Nodes + CPU Usage (Average) + CPU Usage (Max) + Memory Usage (Average) + Memory Usage (Max) + Alerts + Resource Usage + + + + {fakeData.map((cluster, index) => ( + + + {/* + {cluster.clusterName} + */} + + {/* handleClusterClick(cluster.clusterName)}> */} + {cluster.clusterName} + + + {cluster.provider} + {cluster.nodes} + {cluster.cpuUsage.avg} + {cluster.cpuUsage.max} + {cluster.memoryUsage.avg} + {cluster.memoryUsage.max} + + {cluster.alerts} + + + + {cluster.resourceUsage} + + + + ))} + + + +
+
+ ); +}; diff --git a/public/components/kubernetes/index.tsx b/public/components/kubernetes/index.tsx new file mode 100644 index 0000000000..9cac8d093b --- /dev/null +++ b/public/components/kubernetes/index.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { Home } from './home'; + +export const kubernetes = (props) => { + console.log('top props: ', props); + return + +}; \ No newline at end of file diff --git a/public/components/kubernetes/namespaces/index.tsx b/public/components/kubernetes/namespaces/index.tsx new file mode 100644 index 0000000000..415c06ab89 --- /dev/null +++ b/public/components/kubernetes/namespaces/index.tsx @@ -0,0 +1,20 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { Router, Route, Switch } from 'react-router-dom'; +import { NamespaceOverview } from './overview'; +import { Home as ClusterDetails } from '../home'; + +export const NamespacesOverviewHome = (props) => { + return ( + + + {/* */} + + + + ); +}; diff --git a/public/components/kubernetes/namespaces/overview.tsx b/public/components/kubernetes/namespaces/overview.tsx new file mode 100644 index 0000000000..cd838bede4 --- /dev/null +++ b/public/components/kubernetes/namespaces/overview.tsx @@ -0,0 +1,141 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { + EuiPage, + EuiPageBody, + EuiPageHeader, + EuiPageHeaderSection, + EuiTitle, + EuiFlexGroup, + EuiFlexItem, + EuiCard, + EuiPanel, + EuiTable, + EuiTableHeader, + EuiTableHeaderCell, + EuiTableBody, + EuiTableRow, + EuiTableRowCell, + EuiBadge, + EuiButton, + EuiSelect, + EuiFieldSearch, + EuiIcon, +} from '@elastic/eui'; + +export const NamespaceOverview = () => { + const fakeData = [ + { + namespace: 'argocd', + cluster: 'do-nyc1-demo-infra', + workloads: 7, + cpuUsage: { avg: '0.0521 cores', max: '0.128 cores' }, + memoryUsage: { avg: '866.37 MiB', max: '1009.99 MiB' }, + alerts: 0, + }, + { + namespace: 'cert-manager', + cluster: 'do-nyc1-demo-infra', + workloads: 3, + cpuUsage: { avg: '0.00199 cores', max: '0.00302 cores' }, + memoryUsage: { avg: '101.07 MiB', max: '101.17 MiB' }, + alerts: 0, + }, + { + namespace: 'ingress-nginx', + cluster: 'do-nyc1-demo-infra', + workloads: 1, + cpuUsage: { avg: '0.176 cores', max: '0.215 cores' }, + memoryUsage: { avg: '92.9 MiB', max: '95.17 MiB' }, + alerts: 1, + }, + // Additional rows with similar structure + ]; + + return ( + + + + + +

Namespaces

+
+
+
+ + {/* + + + + + + + + + + + {}} + isClearable={true} + /> + + + + + */} + + + + + NAMESPACE + CLUSTER + WORKLOADS + CPU USAGE (Average) + CPU USAGE (Max) + MEMORY USAGE (Average) + MEMORY USAGE (Max) + ALERTS + + + + {fakeData.map((namespace, index) => ( + + + {namespace.namespace} + + + {namespace.cluster} + + {namespace.workloads} + {namespace.cpuUsage.avg || 'No data'} + {namespace.cpuUsage.max || 'No data'} + {namespace.memoryUsage.avg || 'No data'} + {namespace.memoryUsage.max || 'No data'} + + {namespace.alerts > 0 ? ( + {namespace.alerts} + ) : ( + None + )} + + + ))} + + + +
+
+ ); +}; diff --git a/public/components/kubernetes/node/details.tsx b/public/components/kubernetes/node/details.tsx new file mode 100644 index 0000000000..89097982e0 --- /dev/null +++ b/public/components/kubernetes/node/details.tsx @@ -0,0 +1,6 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; \ No newline at end of file diff --git a/public/components/kubernetes/node/index.tsx b/public/components/kubernetes/node/index.tsx new file mode 100644 index 0000000000..d0e7d83062 --- /dev/null +++ b/public/components/kubernetes/node/index.tsx @@ -0,0 +1,20 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { Router, Route, Switch } from 'react-router-dom'; +import { NodeOverview } from './overview'; +import { Home as ClusterDetails } from '../home'; + +export const NodeOverviewHome = (props) => { + return ( + + + {/* */} + + + + ); +}; diff --git a/public/components/kubernetes/node/overview.tsx b/public/components/kubernetes/node/overview.tsx new file mode 100644 index 0000000000..d039c80368 --- /dev/null +++ b/public/components/kubernetes/node/overview.tsx @@ -0,0 +1,132 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { + EuiPage, + EuiPageBody, + EuiPageHeader, + EuiPageHeaderSection, + EuiTitle, + EuiFlexGroup, + EuiFlexItem, + EuiCard, + EuiPanel, + EuiTable, + EuiTableHeader, + EuiTableHeaderCell, + EuiTableBody, + EuiTableRow, + EuiTableRowCell, + EuiBadge, + EuiButton, + EuiSelect, + EuiFieldSearch, + EuiLink, +} from '@elastic/eui'; + +export const NodeOverview = () => { + const fakeData = [ + { + nodeName: 'pool-e1ro5g0nq-rk82j', + clusterName: 'eks-cluster-with-vpc', + provider: 'digitalocean', + cpuUsage: { avg: '1.49 cores', max: '1.67 cores' }, + memoryUsage: { avg: '2.79 GiB', max: '2.9 GiB' }, + alerts: 1, + }, + { + nodeName: 'pool-e1ro5g0nq-rk82o', + clusterName: 'eks-cluster-with-vpc', + provider: 'digitalocean', + cpuUsage: { avg: '1.54 cores', max: '1.71 cores' }, + memoryUsage: { avg: '2.05 GiB', max: '2.07 GiB' }, + alerts: 0, + }, + ]; + + return ( + + + + + +

Nodes

+
+
+
+ + {/* + + + + + + + + + + + + + + {}} isClearable={true} /> + + + Show filters + + */} + + + + + NODE + CLUSTER + PROVIDER + CPU USAGE (Average) + CPU USAGE (Max) + MEMORY USAGE (Average) + MEMORY USAGE (Max) + ALERTS + + + + {fakeData.map((node, index) => ( + + + + {node.nodeName} + + + + {node.clusterName} + + {node.provider} + {node.cpuUsage.avg} + {node.cpuUsage.max} + {node.memoryUsage.avg} + {node.memoryUsage.max} + + {node.alerts > 0 ? ( + {node.alerts} + ) : ( + None + )} + + + ))} + + + +
+
+ ); +}; diff --git a/public/components/kubernetes/overview.tsx b/public/components/kubernetes/overview.tsx new file mode 100644 index 0000000000..9718f385e5 --- /dev/null +++ b/public/components/kubernetes/overview.tsx @@ -0,0 +1,181 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { + EuiPage, + EuiPageBody, + EuiPageHeader, + EuiPageHeaderSection, + EuiTitle, + EuiText, + EuiLink, + EuiFlexGroup, + EuiFlexItem, + EuiSelect, + EuiStat, + EuiPanel, + EuiSpacer, + EuiHorizontalRule, + EuiProgress, +} from '@elastic/eui'; +import { Plt } from '../visualizations/plotly/plot'; // Assuming Plt component is in the same directory + +export const KubernetesOverview = () => { + const statsData = [ + { label: 'Clusters', value: 1 }, + { label: 'Nodes', value: 2 }, + { label: 'Namespaces', value: 11 }, + { label: 'Workloads', value: 48 }, + { label: 'Pods', value: 68 }, + { label: 'Containers', value: 96 }, + ]; + + const imageData = [ + { name: 'ghcr.io/grafana/quick...', count: 6 }, + { name: 'docker.io/grafana/allo...', count: 4 }, + { name: 'ghcr.io/jimmidyson/co...', count: 4 }, + { name: 'gke.gcr.io/gke-metrics...', count: 4 }, + { name: 'grafana/k6-httpbin:v0...', count: 4 }, + // Additional items... + ]; + + const cpuUsageData = [ + { + x: ['06:50', '07:00', '07:10', '07:20', '07:30', '07:40'], + y: [20, 21, 19, 20.5, 21, 21.9], + name: 'play-db-cluster', + type: 'scatter', + mode: 'lines+markers', + line: { color: '#1f77b4', width: 2 }, + marker: { size: 6 }, + }, + ]; + + const memoryUsageData = [ + { + x: ['06:50', '07:00', '07:10', '07:20', '07:30', '07:40'], + y: [48, 49, 47, 48.5, 49, 49.1], + name: 'play-db-cluster', + type: 'scatter', + mode: 'lines+markers', + line: { color: '#9467bd', width: 2 }, + marker: { size: 6 }, + }, + ]; + + return ( + + + + + +

Kubernetes Overview

+
+ + For tips on using this overview, visit the{' '} + documentation + +
+
+ + + + {/* Filters */} + + + + + + + + + + + + {/* Summary Stats */} + + {statsData.map((stat, index) => ( + + + + + + ))} + + + + + {/* CPU and Memory Usage Charts */} + + + + +

CPU Usage by Cluster

+
+ + +
+
+ + + +

Memory Usage by Cluster

+
+ + +
+
+
+ + + + {/* Deployed Container Images */} + + +

Deployed Container Images

+
+ + {imageData.map((image, index) => ( +
+ {image.name} + + {image.count} +
+ ))} +
+
+
+ ); +}; diff --git a/public/plugin.tsx b/public/plugin.tsx index 5fbe11b53d..d73c92bc4e 100644 --- a/public/plugin.tsx +++ b/public/plugin.tsx @@ -120,7 +120,7 @@ import { ObservabilityStart, SetupDependencies, } from './types'; -import cluster from 'cluster'; +const KUBERNETES_ID = 'kubernetes-cluster' interface PublicConfig { query_assist: { @@ -276,9 +276,9 @@ export class ObservabilityPlugin order: 5097, }, pod: { - id: 'observability-kubernetes-pod', + id: 'observability-kubernetes-node', label: i18n.translate('core.ui.observabilityNavList.label', { - defaultMessage: 'Pod', + defaultMessage: 'node', }), order: 5098, } @@ -338,6 +338,7 @@ export class ObservabilityPlugin const appMountWithStartPage = (startPage: string, defaultRoute?: string) => async ( params: AppMountParameters ) => { + console.log('AppMountParameters: ', params); const { Observability } = await import('./components/index'); const [coreStart, depsStart] = await core.getStartServices(); const dslService = new DSLService(coreStart.http); @@ -361,23 +362,6 @@ export class ObservabilityPlugin ); }; - // core.application.register({ - // id: 'observability-kubernetes', - // title: 'Kubernetes', - // description: 'OpenSearch Dashboards Kubernetes Plugin', - // category: { - // id: 'opensearch', - // label: 'OpenSearch Plugins', - // order: 2000, - // }, - // order: 4000, - // mount: async (params) => { - // const { renderApp } = await import('./components/kubernetes/home'); - // const [coreStart] = await core.getStartServices(); - // return renderApp(coreStart, params); - // }, - // }); - core.chrome.navGroup.addNavLinksToGroup(OBSERVABILITY_APP_CATEGORIES.kubernetes, [ { id: 'observability-kubernetes', @@ -386,14 +370,6 @@ export class ObservabilityPlugin }, ]); - // core.chrome.navGroup.addNavLinksToGroup(OBSERVABILITY_APP_CATEGORIES.cluster, [ - // { - // id: 'observability-kubernetes-cluster', - // category: DEFAULT_APP_CATEGORIES.observability, - // parentNavLinkId: DEFAULT_APP_CATEGORIES.observability.id, - // }, - // ]); - core.application.register({ id: observabilityMetricsID, title: observabilityMetricsTitle, @@ -514,31 +490,31 @@ export class ObservabilityPlugin title: 'Overview', category: OBSERVABILITY_APP_CATEGORIES.kubernetes, order: 5096, - mount: appMountWithStartPage('kubernetes-overview'), + mount: appMountWithStartPage('kubernetesOverview'), }); core.application.register({ id: 'kubernetes-cluster', - title: 'Cluster', + title: 'Clusters', category: OBSERVABILITY_APP_CATEGORIES.kubernetes, order: 5096, - mount: appMountWithStartPage('kubernetes-cluster'), + mount: appMountWithStartPage('kubernetesCluster'), }); core.application.register({ id: 'kubernetes-namespaces', - title: 'Namespace', + title: 'Namespaces', category: OBSERVABILITY_APP_CATEGORIES.kubernetes, order: 5096, - mount: appMountWithStartPage('kubernetes-namespaces'), + mount: appMountWithStartPage('kubernetesNamespaces'), }); core.application.register({ - id: 'kubernetes-pod', - title: 'Pod', + id: 'kubernetes-node', + title: 'Nodes', category: OBSERVABILITY_APP_CATEGORIES.kubernetes, order: 5096, - mount: appMountWithStartPage('kubernetes-pod'), + mount: appMountWithStartPage('kubernetesNode'), }); const navLinks = [ @@ -555,7 +531,7 @@ export class ObservabilityPlugin parentNavLinkId: OBSERVABILITY_APP_CATEGORIES.kubernetes.id, }, { - id: 'kubernetes-pod', + id: 'kubernetes-node', parentNavLinkId: OBSERVABILITY_APP_CATEGORIES.kubernetes.id, }, ];