mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-09-14 05:40:16 +00:00
Mizu enterprise preparing (#567)
This commit is contained in:
@@ -23,16 +23,3 @@
|
|||||||
font-size: 11px
|
font-size: 11px
|
||||||
font-weight: bold
|
font-weight: bold
|
||||||
color: $light-blue-color
|
color: $light-blue-color
|
||||||
|
|
||||||
.httpsDomains
|
|
||||||
display: none
|
|
||||||
margin: 0
|
|
||||||
padding: 0
|
|
||||||
list-style: none
|
|
||||||
|
|
||||||
.customWarningStyle
|
|
||||||
&:hover
|
|
||||||
overflow-y: scroll
|
|
||||||
height: 85px
|
|
||||||
.httpsDomains
|
|
||||||
display: block
|
|
||||||
|
138
ui/src/App.tsx
138
ui/src/App.tsx
@@ -1,51 +1,15 @@
|
|||||||
import React, {useEffect, useState} from 'react';
|
import React, {useState} from 'react';
|
||||||
import './App.sass';
|
import './App.sass';
|
||||||
import logo from './components/assets/Mizu-logo.svg';
|
|
||||||
import logo_up9 from './components/assets/logo_up9.svg';
|
|
||||||
import {Button, Snackbar} from "@material-ui/core";
|
|
||||||
import {TrafficPage} from "./components/TrafficPage";
|
import {TrafficPage} from "./components/TrafficPage";
|
||||||
import Tooltip from "./components/UI/Tooltip";
|
import {TLSWarning} from "./components/TLSWarning/TLSWarning";
|
||||||
import {makeStyles} from "@material-ui/core/styles";
|
import {Header} from "./components/Header/Header";
|
||||||
import MuiAlert from '@material-ui/lab/Alert';
|
|
||||||
import Api from "./helpers/api";
|
|
||||||
|
|
||||||
|
|
||||||
const useStyles = makeStyles(() => ({
|
|
||||||
tooltip: {
|
|
||||||
backgroundColor: "#3868dc",
|
|
||||||
color: "white",
|
|
||||||
fontSize: 13,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const api = new Api();
|
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
|
||||||
const classes = useStyles();
|
|
||||||
|
|
||||||
const [analyzeStatus, setAnalyzeStatus] = useState(null);
|
const [analyzeStatus, setAnalyzeStatus] = useState(null);
|
||||||
const [showTLSWarning, setShowTLSWarning] = useState(false);
|
const [showTLSWarning, setShowTLSWarning] = useState(false);
|
||||||
const [userDismissedTLSWarning, setUserDismissedTLSWarning] = useState(false);
|
const [userDismissedTLSWarning, setUserDismissedTLSWarning] = useState(false);
|
||||||
const [addressesWithTLS, setAddressesWithTLS] = useState(new Set());
|
const [addressesWithTLS, setAddressesWithTLS] = useState(new Set<string>());
|
||||||
const [statusAuth, setStatusAuth] = useState(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
try {
|
|
||||||
const recentTLSLinks = await api.getRecentTLSLinks();
|
|
||||||
if (recentTLSLinks?.length > 0) {
|
|
||||||
setAddressesWithTLS(new Set(recentTLSLinks));
|
|
||||||
setShowTLSWarning(true);
|
|
||||||
}
|
|
||||||
const auth = await api.getAuthStatus();
|
|
||||||
setStatusAuth(auth);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
})();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onTLSDetected = (destAddress: string) => {
|
const onTLSDetected = (destAddress: string) => {
|
||||||
addressesWithTLS.add(destAddress);
|
addressesWithTLS.add(destAddress);
|
||||||
@@ -56,96 +20,16 @@ const App = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const analysisMessage = analyzeStatus?.isRemoteReady ?
|
|
||||||
<span>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>Status</td>
|
|
||||||
<td><b>Available</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Messages</td>
|
|
||||||
<td><b>{analyzeStatus?.sentCount}</b></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</span> :
|
|
||||||
analyzeStatus?.sentCount > 0 ?
|
|
||||||
<span>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>Status</td>
|
|
||||||
<td><b>Processing</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Messages</td>
|
|
||||||
<td><b>{analyzeStatus?.sentCount}</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colSpan={2}> Please allow a few minutes for the analysis to complete</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</span> :
|
|
||||||
<span>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td>Status</td>
|
|
||||||
<td><b>Waiting for traffic</b></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Messages</td>
|
|
||||||
<td><b>{analyzeStatus?.sentCount}</b></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</span>
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mizuApp">
|
<div className="mizuApp">
|
||||||
<div className="header">
|
<Header analyzeStatus={analyzeStatus}/>
|
||||||
<div style={{display: "flex", alignItems: "center"}}>
|
|
||||||
<div className="title"><img src={logo} alt="logo"/></div>
|
|
||||||
<div className="description">Traffic viewer for Kubernetes</div>
|
|
||||||
</div>
|
|
||||||
<div style={{display: "flex", alignItems: "center"}}>
|
|
||||||
|
|
||||||
{analyzeStatus?.isAnalyzing &&
|
|
||||||
<div>
|
|
||||||
<Tooltip title={analysisMessage} isSimple classes={classes}>
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
style={{fontFamily: "system-ui",
|
|
||||||
fontWeight: 600,
|
|
||||||
fontSize: 12,
|
|
||||||
padding: 8}}
|
|
||||||
size={"small"}
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
startIcon={<img style={{height: 24, maxHeight: "none", maxWidth: "none"}} src={logo_up9} alt={"up9"}/>}
|
|
||||||
disabled={!analyzeStatus?.isRemoteReady}
|
|
||||||
onClick={() => {
|
|
||||||
window.open(analyzeStatus?.remoteUrl)
|
|
||||||
}}>
|
|
||||||
Analysis
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{statusAuth?.email && <div style={{display: "flex", borderLeft: "2px #87878759 solid", paddingLeft: 10, marginLeft: 10}}>
|
|
||||||
<div style={{color: "rgba(0,0,0,0.75)"}}>
|
|
||||||
<div style={{fontWeight: 600, fontSize: 13}}>{statusAuth.email}</div>
|
|
||||||
<div style={{fontSize:11}}>{statusAuth.model}</div>
|
|
||||||
</div>
|
|
||||||
</div>}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<TrafficPage setAnalyzeStatus={setAnalyzeStatus} onTLSDetected={onTLSDetected}/>
|
<TrafficPage setAnalyzeStatus={setAnalyzeStatus} onTLSDetected={onTLSDetected}/>
|
||||||
<Snackbar open={showTLSWarning && !userDismissedTLSWarning}>
|
<TLSWarning showTLSWarning={showTLSWarning}
|
||||||
<MuiAlert classes={{ filledWarning: 'customWarningStyle' }} elevation={6} variant="filled" onClose={() => setUserDismissedTLSWarning(true)} severity="warning">
|
setShowTLSWarning={setShowTLSWarning}
|
||||||
Mizu is detecting TLS traffic, this type of traffic will not be displayed.
|
addressesWithTLS={addressesWithTLS}
|
||||||
{addressesWithTLS.size > 0 && <ul className="httpsDomains"> {Array.from(addressesWithTLS, address => <li>{address}</li>)} </ul>}
|
setAddressesWithTLS={setAddressesWithTLS}
|
||||||
</MuiAlert>
|
userDismissedTLSWarning={userDismissedTLSWarning}
|
||||||
</Snackbar>
|
setUserDismissedTLSWarning={setUserDismissedTLSWarning}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
86
ui/src/components/AnalyzeButton/AnalyzeButton.tsx
Normal file
86
ui/src/components/AnalyzeButton/AnalyzeButton.tsx
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import {Button} from "@material-ui/core";
|
||||||
|
import React from "react";
|
||||||
|
import Tooltip from "../UI/Tooltip";
|
||||||
|
import logo_up9 from "../assets/logo_up9.svg";
|
||||||
|
import {makeStyles} from "@material-ui/core/styles";
|
||||||
|
|
||||||
|
const useStyles = makeStyles(() => ({
|
||||||
|
tooltip: {
|
||||||
|
backgroundColor: "#3868dc",
|
||||||
|
color: "white",
|
||||||
|
fontSize: 13,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
interface AnalyseButtonProps {
|
||||||
|
analyzeStatus: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AnalyzeButton: React.FC<AnalyseButtonProps> = ({analyzeStatus}) => {
|
||||||
|
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
const analysisMessage = analyzeStatus?.isRemoteReady ?
|
||||||
|
<span>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Status</td>
|
||||||
|
<td><b>Available</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Messages</td>
|
||||||
|
<td><b>{analyzeStatus?.sentCount}</b></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</span> :
|
||||||
|
analyzeStatus?.sentCount > 0 ?
|
||||||
|
<span>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Status</td>
|
||||||
|
<td><b>Processing</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Messages</td>
|
||||||
|
<td><b>{analyzeStatus?.sentCount}</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}> Please allow a few minutes for the analysis to complete</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</span> :
|
||||||
|
<span>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Status</td>
|
||||||
|
<td><b>Waiting for traffic</b></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Messages</td>
|
||||||
|
<td><b>{analyzeStatus?.sentCount}</b></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
return ( <div>
|
||||||
|
<Tooltip title={analysisMessage} isSimple classes={classes}>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
style={{fontFamily: "system-ui",
|
||||||
|
fontWeight: 600,
|
||||||
|
fontSize: 12,
|
||||||
|
padding: 8}}
|
||||||
|
size={"small"}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
startIcon={<img style={{height: 24, maxHeight: "none", maxWidth: "none"}} src={logo_up9} alt={"up9"}/>}
|
||||||
|
disabled={!analyzeStatus?.isRemoteReady}
|
||||||
|
onClick={() => {
|
||||||
|
window.open(analyzeStatus?.remoteUrl)
|
||||||
|
}}>
|
||||||
|
Analysis
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
</div>);
|
||||||
|
}
|
13
ui/src/components/AuthPresentation/AuthPresentation.sass
Normal file
13
ui/src/components/AuthPresentation/AuthPresentation.sass
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.authPresentationContainer
|
||||||
|
display: flex
|
||||||
|
border-left: 2px #87878759 solid
|
||||||
|
padding-left: 10px
|
||||||
|
margin-left: 10px
|
||||||
|
color: rgba(0,0,0,0.75)
|
||||||
|
|
||||||
|
.authEmail
|
||||||
|
font-weight: 600
|
||||||
|
font-size: 13px
|
||||||
|
|
||||||
|
.authModel
|
||||||
|
font-size: 11px
|
30
ui/src/components/AuthPresentation/AuthPresentation.tsx
Normal file
30
ui/src/components/AuthPresentation/AuthPresentation.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import Api from "../../helpers/api";
|
||||||
|
import './AuthPresentation.sass';
|
||||||
|
|
||||||
|
const api = new Api();
|
||||||
|
|
||||||
|
export const AuthPresentation = () => {
|
||||||
|
|
||||||
|
const [statusAuth, setStatusAuth] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const auth = await api.getAuthStatus();
|
||||||
|
setStatusAuth(auth);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return <>
|
||||||
|
{statusAuth?.email && <div className="authPresentationContainer">
|
||||||
|
<div>
|
||||||
|
<div className="authEmail">{statusAuth.email}</div>
|
||||||
|
<div className="authModel">{statusAuth.model}</div>
|
||||||
|
</div>
|
||||||
|
</div>}
|
||||||
|
</>;
|
||||||
|
}
|
22
ui/src/components/Header/Header.tsx
Normal file
22
ui/src/components/Header/Header.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {AuthPresentation} from "../AuthPresentation/AuthPresentation";
|
||||||
|
import {AnalyzeButton} from "../AnalyzeButton/AnalyzeButton";
|
||||||
|
import logo from '../assets/Mizu-logo.svg';
|
||||||
|
|
||||||
|
interface HeaderProps {
|
||||||
|
analyzeStatus: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Header: React.FC<HeaderProps> = ({analyzeStatus}) => {
|
||||||
|
|
||||||
|
return <div className="header">
|
||||||
|
<div style={{display: "flex", alignItems: "center"}}>
|
||||||
|
<div className="title"><img src={logo} alt="logo"/></div>
|
||||||
|
<div className="description">Traffic viewer for Kubernetes</div>
|
||||||
|
</div>
|
||||||
|
<div style={{display: "flex", alignItems: "center"}}>
|
||||||
|
{analyzeStatus?.isAnalyzing && <AnalyzeButton analyzeStatus={analyzeStatus}/>}
|
||||||
|
<AuthPresentation/>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}
|
12
ui/src/components/TLSWarning/TLSWarning.sass
Normal file
12
ui/src/components/TLSWarning/TLSWarning.sass
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.httpsDomains
|
||||||
|
display: none
|
||||||
|
margin: 0
|
||||||
|
padding: 0
|
||||||
|
list-style: none
|
||||||
|
|
||||||
|
.customWarningStyle
|
||||||
|
&:hover
|
||||||
|
overflow-y: scroll
|
||||||
|
height: 85px
|
||||||
|
.httpsDomains
|
||||||
|
display: block
|
42
ui/src/components/TLSWarning/TLSWarning.tsx
Normal file
42
ui/src/components/TLSWarning/TLSWarning.tsx
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import {Snackbar} from "@material-ui/core";
|
||||||
|
import MuiAlert from "@material-ui/lab/Alert";
|
||||||
|
import React, {useEffect} from "react";
|
||||||
|
import Api from "../../helpers/api";
|
||||||
|
import './TLSWarning.sass';
|
||||||
|
|
||||||
|
const api = new Api();
|
||||||
|
|
||||||
|
interface TLSWarningProps {
|
||||||
|
showTLSWarning: boolean
|
||||||
|
setShowTLSWarning: (show: boolean) => void
|
||||||
|
addressesWithTLS: Set<string>
|
||||||
|
setAddressesWithTLS: (addresses: Set<string>) => void
|
||||||
|
userDismissedTLSWarning: boolean
|
||||||
|
setUserDismissedTLSWarning: (flag: boolean) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TLSWarning: React.FC<TLSWarningProps> = ({showTLSWarning, setShowTLSWarning, addressesWithTLS, setAddressesWithTLS, userDismissedTLSWarning, setUserDismissedTLSWarning}) => {
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const recentTLSLinks = await api.getRecentTLSLinks();
|
||||||
|
if (recentTLSLinks?.length > 0) {
|
||||||
|
setAddressesWithTLS(new Set(recentTLSLinks));
|
||||||
|
setShowTLSWarning(true);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (<Snackbar open={showTLSWarning && !userDismissedTLSWarning}>
|
||||||
|
<MuiAlert classes={{filledWarning: 'customWarningStyle'}} elevation={6} variant="filled"
|
||||||
|
onClose={() => setUserDismissedTLSWarning(true)} severity="warning">
|
||||||
|
Mizu is detecting TLS traffic, this type of traffic will not be displayed.
|
||||||
|
{addressesWithTLS.size > 0 &&
|
||||||
|
<ul className="httpsDomains"> {Array.from(addressesWithTLS, address => <li>{address}</li>)} </ul>}
|
||||||
|
</MuiAlert>
|
||||||
|
</Snackbar>);
|
||||||
|
}
|
Reference in New Issue
Block a user