├── .eslintrc.json ├── .gitignore ├── README.md ├── app ├── App.tsx ├── Components │ └── namespace │ │ ├── Namespace.tsx │ │ └── namespaceSlice.ts ├── Containers │ └── SidebarContainer.tsx ├── assets │ ├── LogeWhiteBG.png │ ├── MaestroSmall.png │ ├── Node-pod-overview.gif │ ├── homepage-logs3.gif │ ├── logo-cube.png │ ├── maestro-logo-white.ai │ ├── maestro-logo-white.png │ └── metrics-page.gif ├── global.d.ts ├── home │ ├── Components │ │ ├── AlertCard.tsx │ │ ├── EventCard.tsx │ │ ├── HomeGraphCard.tsx │ │ ├── LineChartTemplate.tsx │ │ ├── LogCard.tsx │ │ ├── StatusBubble.tsx │ │ ├── StatusCard.tsx │ │ └── utils │ │ │ ├── GraphColors.tsx │ │ │ └── customSelectTheme.tsx │ └── Containers │ │ ├── BubblesContainer.tsx │ │ ├── DashboardContainer.tsx │ │ ├── EventsCardContainer.tsx │ │ ├── EventsContainer.tsx │ │ ├── HomeGraphContainer.tsx │ │ ├── MainContainer.tsx │ │ ├── OverviewContainer.tsx │ │ ├── StatusContainer.tsx │ │ └── utils │ │ └── edgeCaseHandling.tsx ├── index.html ├── index.tsx ├── metrics │ └── Container │ │ ├── GraphContainer.tsx │ │ └── MetricsContainer.tsx ├── state │ ├── hooks.ts │ └── store.ts ├── styles │ └── index.css └── types.ts ├── electron ├── dataController │ ├── formatData │ │ ├── formatAlerts.ts │ │ ├── formatEvents.ts │ │ ├── formatMatrixData.ts │ │ └── formatk8sApiData.ts │ └── getData │ │ └── getMatrixData.ts ├── main.ts ├── preload.ts └── utils.ts ├── package-lock.json ├── package.json ├── tsconfig.json └── webpack.config.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "airbnb", 8 | "airbnb-typescript", 9 | "eslint:recommended", 10 | "plugin:react/recommended", 11 | "plugin:@typescript-eslint/recommended" 12 | ], 13 | "parser": "@typescript-eslint/parser", 14 | "parserOptions": { 15 | "ecmaFeatures": { 16 | "jsx": true 17 | }, 18 | "ecmaVersion": "latest", 19 | "sourceType": "module" 20 | }, 21 | "plugins": [ 22 | "react", 23 | "@typescript-eslint" 24 | ], 25 | "rules": { 26 | "react/jsx-filename-extension": [2, { "extensions": [".js", ".jsx", ".ts", ".tsx"] }] 27 | }, 28 | "settings": { 29 | "import/resolver": { 30 | "node": { 31 | "extensions": [".js", ".jsx", ".ts", ".tsx"] 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Maestro Logo](./app/assets/maestro-logo-white.png?raw=true) 2 | 3 | # MAESTRO 4 | 5 | A Kubernetes monitoring tool built on electron. 6 | 7 | ## Summary 8 | 9 | Maestro is an open-source monitoring tool for keeping track of the health of your Kubernetes cluster. Maestro is lightweight and allows users to view key metrics at a glance. This tool leverages the K8s API to obtain important cluster data, and promQL queries to scrape key metrics and display them in a digestible format. 10 | 11 | ## Features 12 | 13 | 1. At a glance overview of nodes, pods, services, and deployments visualized as cubes. Hover over any cube to see which node, pod, deployment, or service you are looking at. 14 | 15 | ![props](./app/assets/Node-pod-overview.gif) 16 | 17 | 2. Log GUI to quickly view alerts and events in an easy to read format, with the ability to sort by severity. 18 | 19 | ![logs](./app/assets/homepage-logs3.gif) 20 | 21 | 3. Graphs displaying key metrics such at CPU usage, memory usage, and network I/O. Multi-colored line graphs map to corresponding properties in the legend, where you can remove properties tht you want to get a more narrowly focused graph. 22 | 23 | ![metrics](./app/assets/metrics-page.gif) 24 | 25 | ## Getting Started 26 | 27 | ### 1. Prerequisites 28 | Users must have Prometheus installed on their Kubernetes cluster. 29 | 30 | ### 2. Clone this repo using the following command 31 | 32 | ``` 33 | https://github.com/oslabs-beta/maestro.git 34 | ``` 35 | 36 | ### 3. Make sure your cluster is ported forward to port 9090 using the following command 37 | 38 | ``` 39 | kubectl port-forward -n default svc/prometheus-kube-prometheus-prometheus 9090 40 | ``` 41 | 42 | ### 4. In the Maestro directory in your terminal, run the following commands 43 | 44 | ``` 45 | npm install 46 | npm run webpack-start 47 | npm run start 48 | ``` 49 | 50 | ### 5. Enjoy your Maestro experience! 51 | 52 | ## Built With 53 | 54 | - [Electron](https://www.electronjs.org/) 55 | - [React](https://reactjs.org/) 56 | - [React Router](https://reactrouter.com/) 57 | - [Redux](https://redux.js.org/) 58 | - [Node](https://nodejs.org/) 59 | - [Kubernetes-client](https://github.com/kubernetes-client/) 60 | - [Prometheus](https://prometheus.io/) 61 | - [Material UI](https://mui.com/) 62 | - [Chart.js](https://www.chartjs.org/) 63 | 64 | ## The Team 65 | 66 | - Peter Kennedy [Github](https://github.com/peterkennedy97) [LinkedIn](https://www.linkedin.com/in/peter-kennedy/) 67 | - Aliya Yano [Github](https://github.com/ajyano22) [LinkedIn](https://www.linkedin.com/in/aliya-yano-8a2548126/) 68 | - Jakob Schillinger [Github](https://github.com/gandalf77) 69 | - Alex Ryu [Github](https://github.com/RyuBoyCoding) [LinkedIn](www.linkedin.com/in/ryu-alex) 70 | -------------------------------------------------------------------------------- /app/App.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import DashboardContainer from "./home/Containers/DashboardContainer"; 3 | import "./styles/index.css"; 4 | 5 | function App() { 6 | return ( 7 | 8 | ); 9 | } 10 | 11 | export default App; 12 | -------------------------------------------------------------------------------- /app/Components/namespace/Namespace.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, useCallback } from "react"; 2 | import { useAppDispatch } from "../../state/hooks"; 3 | import { setCurrentNamespace } from "./namespaceSlice"; 4 | import { getNamespacesForState } from "./namespaceSlice"; 5 | import Select from "react-select"; 6 | import { customSelectStyles } from "../../home/Components/utils/customSelectTheme"; 7 | import { customSelectThemeNamespaces } from "../../home/Components/utils/customSelectTheme"; 8 | 9 | const Namespace: React.FC = () => { 10 | const dispatch = useAppDispatch(); 11 | const [namespaces, setNamespaces] = useState([]); 12 | 13 | const initApp = useCallback(async () => { 14 | await dispatch(getNamespacesForState()); 15 | }, [dispatch]); 16 | 17 | useEffect(() => { 18 | initApp(); 19 | getNamespaces(); 20 | }, []); 21 | 22 | const getNamespaces = async () => { 23 | const namespaces = await window.electron.getNamespacesList(); 24 | setNamespaces(namespaces); 25 | }; 26 | 27 | const options: any = namespaces.map((el: string) => { 28 | return { value: el, label: el }; 29 | }); 30 | 31 | const handleNamespaceChange = (e: any) => 32 | dispatch(setCurrentNamespace(e.value)); 33 | 34 | return ( 35 |
36 | 41 | 42 |