├── .env.enc ├── .github └── workflows │ ├── ci.yaml │ └── deploy.yaml ├── .gitignore ├── .vscode ├── settings 2.json └── settings.json ├── Dockerfile ├── README.md ├── client ├── .babelrc ├── .gitignore ├── dist │ ├── 1db0c662795055d2b321.png │ ├── 30b5ef32585e7cbb326b.png │ ├── b01898446ba2e22f2efd.png │ ├── bundle.js │ ├── c66f66b5e7cba717823d.png │ ├── f4fd54124ab0c5aa72cd.png │ ├── f91efdf0cfa77fa4cadf.png │ ├── fbe689dffdd47f67ae34.png │ └── index.html ├── jest.config.js ├── jsconfig.json ├── package-lock.json ├── package.json ├── public │ └── index.html ├── src │ ├── App.js │ ├── assets │ │ ├── aria.png │ │ ├── dashboard.gif │ │ ├── example.gif │ │ ├── g.jpg │ │ ├── gh2.jpg │ │ ├── google.png │ │ ├── grace.png │ │ ├── logingoogle.png │ │ ├── logo.png │ │ ├── nobglogo.png │ │ ├── ploy.png │ │ ├── profile.png │ │ ├── signupgithub.png │ │ ├── signupgoogle.png │ │ └── will.png │ ├── components │ │ ├── Alerts.jsx │ │ ├── Alerts.test.jsx │ │ ├── Export.jsx │ │ ├── FlexBetween.jsx │ │ ├── FlexBetween.test.jsx │ │ ├── LineChart.jsx │ │ ├── Navbar.jsx │ │ ├── PieChart.jsx │ │ ├── Service.jsx │ │ ├── Setting.jsx │ │ ├── Sidebar.jsx │ │ ├── StatusCard.jsx │ │ ├── __snapshots__ │ │ │ └── footer.test.jsx.snap │ │ ├── accSection.jsx │ │ ├── accountDetails.jsx │ │ ├── breadcrumbs.jsx │ │ ├── clusterDetails.jsx │ │ ├── feedback.jsx │ │ ├── feedback.test.jsx │ │ ├── fileMock.js │ │ ├── footer.jsx │ │ ├── footer.test.jsx │ │ ├── home.jsx │ │ ├── info.jsx │ │ ├── login.jsx │ │ └── mockStore.js │ ├── index.css │ ├── index.js │ ├── pages │ │ ├── ClusterMetrics.jsx │ │ ├── Clusters2.jsx │ │ ├── Dashboard.jsx │ │ ├── Layout.jsx │ │ ├── LogsNotification.jsx │ │ ├── Overview.jsx │ │ ├── UserProfile.jsx │ │ ├── accounts.jsx │ │ ├── clusters.jsx │ │ ├── credentials.jsx │ │ ├── getstarted.jsx │ │ ├── home.jsx │ │ ├── login.jsx │ │ ├── signup.jsx │ │ └── team.jsx │ ├── redux │ │ ├── globalSlice.js │ │ ├── notificationSlice.js │ │ ├── rootReducer.js │ │ ├── store.js │ │ ├── userSlice.js │ │ └── wsContext.js │ ├── theme.js │ └── webService │ │ ├── connectWebSocketToLineChart.js │ │ ├── connectWebSocketToNotifications.js │ │ └── connectWebSocketToPieChart.js └── webpack.config.js ├── docker-compose.yml ├── jest.backend.config.js ├── jest.config.js ├── package-lock.json ├── package.json └── server ├── controllers ├── credentialsController.js ├── listController.js ├── metricController.js ├── notificationController.js ├── redisClient.js └── userController.js ├── createDatabase.js ├── database ├── Accounts.db ├── Notifications.db └── Users.db ├── router └── listRouter.js ├── server.js └── tests ├── credentialsController.test.js ├── listController.test.js ├── metricController.test.js ├── notificationController.test.js └── userController.test.js /.env.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/DeClustor/2ed5f0f10f89d1b40c42569bf590be9dabd264aa/.env.enc -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI Pipeline 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | branches: 10 | - main 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout code 18 | uses: actions/checkout@v2 19 | 20 | - name: Set up Node.js 21 | uses: actions/setup-node@v2 22 | with: 23 | node-version: 18.x 24 | 25 | - name: Clean npm cache and install root dependencies 26 | run: | 27 | npm cache clean --force 28 | rm -rf node_modules package-lock.json 29 | npm install --legacy-peer-deps 30 | 31 | - name: Clean and install client dependencies 32 | run: | 33 | cd client 34 | rm -rf node_modules package-lock.json 35 | npm cache clean --force 36 | npm install --legacy-peer-deps 37 | 38 | - name: Run tests 39 | run: npm test 40 | 41 | - name: Build client 42 | run: cd client && npm run build 43 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yaml: -------------------------------------------------------------------------------- 1 | name: Deploy Pipeline 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v2 15 | 16 | - name: Set up Docker Buildx 17 | uses: docker/setup-buildx-action@v2 18 | 19 | - name: Login to Docker Hub 20 | run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin 21 | 22 | - name: Build Docker image 23 | run: docker build -t declustorteam/declustor:latest . 24 | 25 | - name: Push Docker image 26 | run: docker push declustorteam/declustor:latest 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | client/node_modules 2 | node_modules 3 | .env 4 | server/database/Credentials.db 5 | server/database/Users.db 6 | .DS_Store -------------------------------------------------------------------------------- /.vscode/settings 2.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16 2 | WORKDIR /app 3 | COPY package*.json ./ 4 | RUN npm install 5 | COPY server ./server 6 | COPY client ./client 7 | # COPY .env ./ 8 | RUN rm -rf client/node_modules client/package-lock.json 9 | RUN npm cache clean --force 10 | RUN cd client && npm install --legacy-peer-deps 11 | EXPOSE 3000 12 | EXPOSE 8080 13 | CMD ["npm", "run", "start"] 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![DeClustor Logo](https://github.com/oslabs-beta/DeClustor/blob/dev/client/src/assets/nobglogo.png?raw=true) 2 | 3 | - [What is DeClustor?](#introduce) 4 | - [Features](#key-features) 5 | - [Getting Started](#getstart) 6 | - [Meet the Team](#meet-the-team) 7 | 8 | ## What is DeClustor? 9 | 10 | Managing AWS ECS environments can be challenging due to fragmented metrics and real-time performance monitoring across clusters. AWS's dashboard can be confusing and lacks a unified interface. 11 | 12 | DeClustor offers a centralized solution for seamless ECS monitoring and management, enabling effortless tracking of metrics and real-time performance across multiple services within multiple ECS clusters. 13 | 14 | ## Features 15 | 16 | 1. Centralized Dashboard with easy-to-use account management feature 17 | A very powerful dashboard displays which can present users all the real-time metircs based on the service they choose, and users are enabled to manage their AWS accounts easily, as depicted in this demo 18 | 19 | ![dash-ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/1ad4b259-78c5-4ea7-be31-1eb9a61bc18e) 20 | 21 | 2. Logs and data report generation by notification setting 22 | Users are able to customize different types of metrics and set thresholds to monitor their services. They will be noticed once the thresholds are reached. 23 | They can also analyze the sorted logs and export customized reports. 24 | 25 | ![logsnew-ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/a4c80276-302c-41f5-b5e5-6a5cbfdc80ce) 26 | 27 | 3. Task and cluster overview 28 | Users can observe their task data and cluster metrics in detail by easily choosing different accounts, cluster names and services. 29 | 30 | ![taskoverview-ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/f3b6806f-ba2b-4aab-99ae-92c65e9c35b0) 31 | ![clustermetrics-ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/74fc381a-2068-4737-b753-7a61f31b87f7) 32 | 33 | 4. Local database intergration 34 | The security of users' credentials is most valued. Therefore, by providing lightweight and self contained data management, Decluster allows users to store their credentials locally. 35 | 36 | 5. Seamless third-party authentication 37 | Users are provided with easy signup and login options through Google and GitHub OAuth, enhancing security and user experience. 38 | 39 | ## Getting Started 40 | 41 | So what are you waiting for? Follow the instructions below to get started! 42 | 43 | # Using GitHub Repository 44 | 45 | 1. **Pull the Docker Image from [DockerHub](https://hub.docker.com/r/declustorteam/declustor):** 46 | ```sh 47 | docker pull declustorteam/declustor 48 | ``` 49 | 2. Clone this repository from GitHub 50 | 3. Decrypt the the .env file by using the following commands: 51 | ```yml 52 | openssl enc -aes-256-cbc -d -pbkdf2 -iter 100000 -in .env.enc -out .env -k ilovedeclustor 53 | ``` 54 | 4. Run terminal command: 55 | ``` 56 | docker-compose up -build 57 | ``` 58 | 5. Access the application by opening up your web browser and head over to http://localhost:8080 59 | 6. Sign up to make an account 60 | 7. Use our [Google Docs Instructions](https://docs.google.com/document/d/1Vf7OrThD2bj3LU9Dxm4l7vFzVKmexYBO/edit) to create a IAM User for DeClustor to access your AWS account 61 | 8. Select Account → Clusters → Services 62 | 63 | ## Meet the Team 64 | 65 | | Developed By | GitHub | LinkedIn | 66 | | ------------- | ---------------------------------------- | ---------------------------------------------------- | 67 | | Grace Lo | [GitHub](https://github.com/gracelo0717) | [LinkedIn](https://www.linkedin.com/in/gracelo0717) | 68 | | Will Di | [GitHub](https://github.com/xiudou401) | [LinkedIn](https://www.linkedin.com/in/will-di) | 69 | | Aria Liang | [GitHub](https://github.com/Aria-Liang) | [LinkedIn](https://www.linkedin.com/in/arialiang) | 70 | | Ploynapa Yang | [GitHub](https://github.com/Ploynpk) | [LinkedIn](https://www.linkedin.com/in/ploynapa-py/) | 71 | -------------------------------------------------------------------------------- /client/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"], 3 | "plugins": ["@babel/plugin-transform-runtime"] 4 | } 5 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /client/dist/1db0c662795055d2b321.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/DeClustor/2ed5f0f10f89d1b40c42569bf590be9dabd264aa/client/dist/1db0c662795055d2b321.png -------------------------------------------------------------------------------- /client/dist/30b5ef32585e7cbb326b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/DeClustor/2ed5f0f10f89d1b40c42569bf590be9dabd264aa/client/dist/30b5ef32585e7cbb326b.png -------------------------------------------------------------------------------- /client/dist/b01898446ba2e22f2efd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/DeClustor/2ed5f0f10f89d1b40c42569bf590be9dabd264aa/client/dist/b01898446ba2e22f2efd.png -------------------------------------------------------------------------------- /client/dist/c66f66b5e7cba717823d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/DeClustor/2ed5f0f10f89d1b40c42569bf590be9dabd264aa/client/dist/c66f66b5e7cba717823d.png -------------------------------------------------------------------------------- /client/dist/f4fd54124ab0c5aa72cd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/DeClustor/2ed5f0f10f89d1b40c42569bf590be9dabd264aa/client/dist/f4fd54124ab0c5aa72cd.png -------------------------------------------------------------------------------- /client/dist/f91efdf0cfa77fa4cadf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/DeClustor/2ed5f0f10f89d1b40c42569bf590be9dabd264aa/client/dist/f91efdf0cfa77fa4cadf.png -------------------------------------------------------------------------------- /client/dist/fbe689dffdd47f67ae34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/DeClustor/2ed5f0f10f89d1b40c42569bf590be9dabd264aa/client/dist/fbe689dffdd47f67ae34.png -------------------------------------------------------------------------------- /client/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | DeClustor 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /client/jest.config.js: -------------------------------------------------------------------------------- 1 | // jest.config.js 2 | module.exports = { 3 | setupFilesAfterEnv: ['@testing-library/jest-dom'], 4 | testEnvironment: 'jsdom', 5 | moduleNameMapper: { 6 | '\\.(css|less|scss|sass)$': 'identity-obj-proxy', 7 | '\\.(jpg|jpeg|png|gif|webp|svg)$': './fileMock.js', 8 | }, 9 | transform: { 10 | '^.+\\.(js|jsx|ts|tsx)$': 'babel-jest', 11 | }, 12 | transformIgnorePatterns: ['/node_modules/(?!d3-.*|@nivo/.*)'], 13 | 14 | moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'], 15 | }; 16 | -------------------------------------------------------------------------------- /client/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "src" 4 | }, 5 | "include": ["src"] 6 | } 7 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "webpack.config.js", 6 | "scripts": { 7 | "build": "webpack", 8 | "dev": "webpack serve --open", 9 | "test": "jest" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "@emotion/react": "^11.11.4", 16 | "@emotion/styled": "^11.11.5", 17 | "@mui/icons-material": "^5.15.21", 18 | "@mui/material": "^5.16.1", 19 | "@mui/system": "^5.16.1", 20 | "@mui/x-data-grid": "^7.10.0", 21 | "@mui/x-data-grid-pro": "^7.10.0", 22 | "@nivo/bar": "^0.87.0", 23 | "@nivo/core": "^0.87.0", 24 | "@nivo/geo": "^0.87.0", 25 | "@nivo/line": "^0.87.0", 26 | "@nivo/pie": "^0.87.0", 27 | "@reduxjs/toolkit": "^2.2.6", 28 | "assert": "^2.1.0", 29 | "browserify-zlib": "^0.2.0", 30 | "buffer": "^6.0.3", 31 | "crypto-browserify": "^3.12.0", 32 | "d3": "^7.9.0", 33 | "esm": "^3.2.25", 34 | "file-loader": "^6.2.0", 35 | "html-webpack-plugin": "^5.6.0", 36 | "https-browserify": "^1.0.0", 37 | "lodash": "^4.17.21", 38 | "os-browserify": "^0.3.0", 39 | "pkg-dir": "^4.2.0", 40 | "process": "^0.11.10", 41 | "react": "^18.3.1", 42 | "react-datepicker": "^7.2.0", 43 | "react-dom": "^18.3.1", 44 | "react-redux": "^8.1.3", 45 | "react-router-dom": "^6.24.0", 46 | "redux": "^4.0.5", 47 | "redux-persist": "^6.0.0", 48 | "sqlite3": "^5.1.7", 49 | "stream-browserify": "^3.0.0", 50 | "stream-http": "^3.2.0", 51 | "url": "^0.11.3", 52 | "util": "^0.12.5", 53 | "vm-browserify": "^1.1.2" 54 | }, 55 | "devDependencies": { 56 | "@babel/cli": "^7.24.7", 57 | "@babel/core": "^7.24.9", 58 | "@babel/plugin-transform-runtime": "^7.24.7", 59 | "@babel/preset-env": "^7.24.8", 60 | "@babel/preset-react": "^7.24.7", 61 | "@react-oauth/google": "^0.12.1", 62 | "@testing-library/dom": "^10.4.0", 63 | "@testing-library/jest-dom": "^6.4.8", 64 | "@testing-library/react": "^16.0.0", 65 | "babel-jest": "^29.7.0", 66 | "babel-loader": "^9.1.3", 67 | "css-loader": "^7.1.2", 68 | "jest": "^29.7.0", 69 | "jest-environment-jsdom": "^29.7.0", 70 | "nodemon": "^3.1.3", 71 | "react-redux": "^7.2.2", 72 | "redux": "^5.0.1", 73 | "redux-mock-store": "^1.5.4", 74 | "redux-thunk": "^3.1.0", 75 | "sass": "^1.77.6", 76 | "sass-loader": "^14.2.1", 77 | "style-loader": "^4.0.0", 78 | "webpack": "^5.92.0", 79 | "webpack-cli": "^5.1.4", 80 | "webpack-dev-server": "^5.0.4" 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | DeClustor 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /client/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { useMemo } from 'react' 2 | import { 3 | BrowserRouter as Router, 4 | Navigate, 5 | Route, 6 | Routes, 7 | } from 'react-router-dom' 8 | import { CssBaseline, ThemeProvider, Box } from '@mui/material' 9 | import { createTheme } from '@mui/material/styles' 10 | import { useSelector } from 'react-redux' 11 | import { themeSettings } from './theme' 12 | import Layout from './pages/Layout' 13 | import Dashboard from './pages/Dashboard' 14 | import Login from './pages/login' 15 | import Home from './pages/home' 16 | import Signup from './pages/signup' 17 | import Feedback from './components/feedback' 18 | import Footer from './components/footer' 19 | import UserProfile from './pages/UserProfile' 20 | import Credentials from './pages/credentials' 21 | import LogsNotification from './pages/LogsNotification' 22 | import ClusterMetrics from './pages/ClusterMetrics' 23 | import Overview from './pages/Overview' 24 | import Accounts from './pages/accounts' 25 | import AccountDetails from './components/accountDetails' 26 | import Clusters from './pages/Clusters2' 27 | import ClusterDetails from './components/clusterDetails' 28 | 29 | // Main application component 30 | const App = () => { 31 | // Get the current theme mode from Redux store 32 | const mode = useSelector((state) => state.global.mode) 33 | // Generate the theme based on the current mode 34 | const theme = useMemo(() => createTheme(themeSettings(mode)), [mode]) 35 | return ( 36 | 37 | {/* CssBaseline to ensure consistent baseline styles */} 38 | 39 | 40 | 47 | 48 | {/* Define routes for different pages */} 49 | 50 | } /> 51 | } /> 52 | } /> 53 | } /> 54 | } /> 55 | } /> 56 | } /> 57 | }> 58 | } /> 59 | } 62 | /> 63 | } /> 64 | } /> 65 | } /> 66 | } /> 67 | } /> 68 | } 71 | /> 72 | } /> 73 | 74 | 75 | 76 | {/* Feedback and Footer components */} 77 | 78 |