mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-07-19 02:40:33 +00:00
Fixing acceptance tests (#900)
This commit is contained in:
parent
5455220a3a
commit
a4d0e250c9
@ -1,8 +1,7 @@
|
|||||||
const columns = {podName : 1, namespace : 2, tapping : 3};
|
const columns = {podName : 1, namespace : 2, tapping : 3};
|
||||||
const greenStatusImageSrc = '/static/media/success.662997eb.svg';
|
|
||||||
|
|
||||||
function getDomPathInStatusBar(line, column) {
|
function getDomPathInStatusBar(line, column) {
|
||||||
return `.expandedStatusBar > :nth-child(2) > > :nth-child(2) > :nth-child(${line}) > :nth-child(${column})`;
|
return `[data-cy="expandedStatusBar"] > :nth-child(2) > > :nth-child(2) > :nth-child(${line}) > :nth-child(${column})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkLine(line, expectedValues) {
|
export function checkLine(line, expectedValues) {
|
||||||
@ -12,14 +11,14 @@ export function checkLine(line, expectedValues) {
|
|||||||
|
|
||||||
cy.get(getDomPathInStatusBar(line, columns.namespace)).invoke('text').then(namespaceValue => {
|
cy.get(getDomPathInStatusBar(line, columns.namespace)).invoke('text').then(namespaceValue => {
|
||||||
expect(namespaceValue).to.equal(expectedValues.namespace);
|
expect(namespaceValue).to.equal(expectedValues.namespace);
|
||||||
cy.get(getDomPathInStatusBar(line, columns.tapping)).children().should('have.attr', 'src', greenStatusImageSrc);
|
cy.get(getDomPathInStatusBar(line, columns.tapping)).children().should('have.attr', 'src').and("match", /success.*\.svg/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findLineAndCheck(expectedValues) {
|
export function findLineAndCheck(expectedValues) {
|
||||||
cy.get('.expandedStatusBar > :nth-child(2) > > :nth-child(2) > > :nth-child(1)').then(pods => {
|
cy.get('[data-cy="expandedStatusBar"] > :nth-child(2) > > :nth-child(2) > > :nth-child(1)').then(pods => {
|
||||||
cy.get('.expandedStatusBar > :nth-child(2) > > :nth-child(2) > > :nth-child(2)').then(namespaces => {
|
cy.get('[data-cy="expandedStatusBar"] > :nth-child(2) > > :nth-child(2) > > :nth-child(2)').then(namespaces => {
|
||||||
// organizing namespaces array
|
// organizing namespaces array
|
||||||
const podObjectsArray = Object.values(pods ?? {});
|
const podObjectsArray = Object.values(pods ?? {});
|
||||||
const namespacesObjectsArray = Object.values(namespaces ?? {});
|
const namespacesObjectsArray = Object.values(namespaces ?? {});
|
||||||
|
@ -45,7 +45,7 @@ export function leftTextCheck(entryNum, path, expectedText) {
|
|||||||
|
|
||||||
export function leftOnHoverCheck(entryNum, path, filterName) {
|
export function leftOnHoverCheck(entryNum, path, filterName) {
|
||||||
cy.get(`#list #entry-${entryNum} ${path}`).trigger('mouseover');
|
cy.get(`#list #entry-${entryNum} ${path}`).trigger('mouseover');
|
||||||
cy.get(`#list #entry-${entryNum} .Queryable-Tooltip`).invoke('text').should('match', new RegExp(filterName));
|
cy.get(`#list #entry-${entryNum} [data-cy='QueryableTooltip']`).invoke('text').should('match', new RegExp(filterName));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function rightTextCheck(path, expectedText) {
|
export function rightTextCheck(path, expectedText) {
|
||||||
@ -54,7 +54,7 @@ export function rightTextCheck(path, expectedText) {
|
|||||||
|
|
||||||
export function rightOnHoverCheck(path, expectedText) {
|
export function rightOnHoverCheck(path, expectedText) {
|
||||||
cy.get(`#rightSideContainer ${path}`).trigger('mouseover');
|
cy.get(`#rightSideContainer ${path}`).trigger('mouseover');
|
||||||
cy.get(`#rightSideContainer .Queryable-Tooltip`).invoke('text').should('match', new RegExp(expectedText));
|
cy.get(`#rightSideContainer [data-cy='QueryableTooltip']`).invoke('text').should('match', new RegExp(expectedText));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkThatAllEntriesShown() {
|
export function checkThatAllEntriesShown() {
|
||||||
|
@ -8,6 +8,6 @@ it('check', function () {
|
|||||||
cy.visit(`http://localhost:${port}`);
|
cy.visit(`http://localhost:${port}`);
|
||||||
cy.wait('@statusTap').its('response.statusCode').should('match', /^2\d{2}/);
|
cy.wait('@statusTap').its('response.statusCode').should('match', /^2\d{2}/);
|
||||||
|
|
||||||
cy.get('.podsCount').trigger('mouseover');
|
cy.get(`[data-cy="expandedStatusBar"]`).trigger('mouseover',{force: true});
|
||||||
findLineAndCheck(getExpectedDetailsDict(podName, namespace));
|
findLineAndCheck(getExpectedDetailsDict(podName, namespace));
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,7 @@ import {findLineAndCheck, getExpectedDetailsDict} from '../testHelpers/StatusBar
|
|||||||
|
|
||||||
it('opening', function () {
|
it('opening', function () {
|
||||||
cy.visit(Cypress.env('testUrl'));
|
cy.visit(Cypress.env('testUrl'));
|
||||||
cy.get('.podsCount').trigger('mouseover');
|
cy.get(`[data-cy="podsCountText"]`).trigger('mouseover');
|
||||||
});
|
});
|
||||||
|
|
||||||
[1, 2, 3].map(doItFunc);
|
[1, 2, 3].map(doItFunc);
|
||||||
|
@ -3,9 +3,9 @@ import {getExpectedDetailsDict, checkLine} from '../testHelpers/StatusBarHelper'
|
|||||||
|
|
||||||
it('opening', function () {
|
it('opening', function () {
|
||||||
cy.visit(Cypress.env('testUrl'));
|
cy.visit(Cypress.env('testUrl'));
|
||||||
cy.get('.podsCount').trigger('mouseover');
|
cy.get(`[data-cy="podsCountText"]`).trigger('mouseover');
|
||||||
|
|
||||||
cy.get('.expandedStatusBar > :nth-child(2) > > :nth-child(2) >').should('have.length', 1); // one line
|
cy.get('[data-cy="expandedStatusBar"] > :nth-child(2) > > :nth-child(2) >').should('have.length', 1); // one line
|
||||||
|
|
||||||
checkLine(1, getExpectedDetailsDict(Cypress.env('name'), Cypress.env('namespace')));
|
checkLine(1, getExpectedDetailsDict(Cypress.env('name'), Cypress.env('namespace')));
|
||||||
});
|
});
|
||||||
|
@ -26,7 +26,7 @@ it('opening mizu', function () {
|
|||||||
verifyMinimumEntries();
|
verifyMinimumEntries();
|
||||||
|
|
||||||
it('top bar check', function () {
|
it('top bar check', function () {
|
||||||
cy.get('.podsCount').trigger('mouseover');
|
cy.get(`[data-cy="podsCountText"]`).trigger('mouseover');
|
||||||
podsArray.map(findLineAndCheck);
|
podsArray.map(findLineAndCheck);
|
||||||
cy.reload();
|
cy.reload();
|
||||||
});
|
});
|
||||||
@ -205,6 +205,7 @@ function checkFilter(filterDetails){
|
|||||||
// checks the hover on the last entry (the only one in DOM at the beginning)
|
// checks the hover on the last entry (the only one in DOM at the beginning)
|
||||||
leftOnHoverCheck(totalEntries - 1, leftSidePath, name);
|
leftOnHoverCheck(totalEntries - 1, leftSidePath, name);
|
||||||
|
|
||||||
|
cy.get('.w-tc-editor-text').clear();
|
||||||
// applying the filter with alt+enter or with the button
|
// applying the filter with alt+enter or with the button
|
||||||
cy.get('.w-tc-editor-text').type(`${name}${applyByEnter ? '{alt+enter}' : ''}`);
|
cy.get('.w-tc-editor-text').type(`${name}${applyByEnter ? '{alt+enter}' : ''}`);
|
||||||
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', Cypress.env('greenFilterColor'));
|
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', Cypress.env('greenFilterColor'));
|
||||||
|
@ -5,10 +5,10 @@ import Api, {getWebsocketUrl} from "./api";
|
|||||||
|
|
||||||
const api = Api.getInstance()
|
const api = Api.getInstance()
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const {message,error,isOpen, openSocket, closeSocket, sendQuery} = useWS(getWebsocketUrl())
|
const {message,error,isOpen, openSocket, closeSocket, sendQueryWhenWsOpen} = useWS(getWebsocketUrl())
|
||||||
const trafficViewerApi = {...api, webSocket:{open : openSocket, close: closeSocket, sendQuery: sendQuery}}
|
const trafficViewerApi = {...api, webSocket:{open : openSocket, close: closeSocket, sendQueryWhenWsOpen: sendQueryWhenWsOpen}}
|
||||||
sendQuery(DEFAULT_QUERY);
|
sendQueryWhenWsOpen(DEFAULT_QUERY);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () =>{
|
return () =>{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@up9/mizu-common",
|
"name": "@up9/mizu-common",
|
||||||
"version": "1.0.125",
|
"version": "1.0.128",
|
||||||
"description": "Made with create-react-library",
|
"description": "Made with create-react-library",
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -30,7 +30,6 @@
|
|||||||
"react":"^17.0.2",
|
"react":"^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"recoil": "^0.5.2",
|
"recoil": "^0.5.2",
|
||||||
|
|
||||||
"react-copy-to-clipboard": "^5.0.3",
|
"react-copy-to-clipboard": "^5.0.3",
|
||||||
"@types/jest": "^26.0.22",
|
"@types/jest": "^26.0.22",
|
||||||
"@types/node": "^12.20.10"
|
"@types/node": "^12.20.10"
|
||||||
|
@ -8,7 +8,8 @@ import { EntryDetailed } from "./EntryDetailed";
|
|||||||
import playIcon from 'assets/run.svg';
|
import playIcon from 'assets/run.svg';
|
||||||
import pauseIcon from 'assets/pause.svg';
|
import pauseIcon from 'assets/pause.svg';
|
||||||
import variables from '../../variables.module.scss';
|
import variables from '../../variables.module.scss';
|
||||||
import { toast } from 'react-toastify';
|
import { toast,ToastContainer } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import { RecoilRoot, RecoilState, useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
import { RecoilRoot, RecoilState, useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
||||||
import entriesAtom from "../../recoil/entries";
|
import entriesAtom from "../../recoil/entries";
|
||||||
@ -21,7 +22,6 @@ import TrafficViewerApi from "./TrafficViewerApi";
|
|||||||
import { StatusBar } from "../UI/StatusBar";
|
import { StatusBar } from "../UI/StatusBar";
|
||||||
import tappingStatusAtom from "../../recoil/tappingStatus/atom";
|
import tappingStatusAtom from "../../recoil/tappingStatus/atom";
|
||||||
|
|
||||||
|
|
||||||
const useLayoutStyles = makeStyles(() => ({
|
const useLayoutStyles = makeStyles(() => ({
|
||||||
details: {
|
details: {
|
||||||
flex: "0 0 50%",
|
flex: "0 0 50%",
|
||||||
@ -45,26 +45,22 @@ const useLayoutStyles = makeStyles(() => ({
|
|||||||
interface TrafficViewerProps {
|
interface TrafficViewerProps {
|
||||||
setAnalyzeStatus?: (status: any) => void;
|
setAnalyzeStatus?: (status: any) => void;
|
||||||
api?: any
|
api?: any
|
||||||
message?: {}
|
|
||||||
error?: {}
|
|
||||||
isWebSocketOpen: boolean
|
|
||||||
trafficViewerApiProp: TrafficViewerApi,
|
trafficViewerApiProp: TrafficViewerApi,
|
||||||
actionButtons?: JSX.Element,
|
actionButtons?: JSX.Element,
|
||||||
isShowStatusBar?: boolean
|
isShowStatusBar?: boolean,
|
||||||
|
webSocketUrl : string
|
||||||
}
|
}
|
||||||
|
|
||||||
const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message, error, isWebSocketOpen, trafficViewerApiProp, actionButtons, isShowStatusBar }) => {
|
export const TrafficViewer : React.FC<TrafficViewerProps> = ({setAnalyzeStatus, trafficViewerApiProp, actionButtons,isShowStatusBar,webSocketUrl}) => {
|
||||||
|
|
||||||
const classes = useLayoutStyles();
|
const classes = useLayoutStyles();
|
||||||
|
|
||||||
const [entries, setEntries] = useRecoilState(entriesAtom);
|
const [entries, setEntries] = useRecoilState(entriesAtom);
|
||||||
const [focusedEntryId, setFocusedEntryId] = useRecoilState(focusedEntryIdAtom);
|
const [focusedEntryId, setFocusedEntryId] = useRecoilState(focusedEntryIdAtom);
|
||||||
const [wsConnection, setWsConnection] = useRecoilState(websocketConnectionAtom);
|
const [wsConnection, setWsConnection] = useRecoilState(websocketConnectionAtom);
|
||||||
const query = useRecoilValue(queryAtom);
|
const query = useRecoilValue(queryAtom);
|
||||||
const [queryToSend, setQueryToSend] = useState("")
|
|
||||||
const setTrafficViewerApiState = useSetRecoilState(trafficViewerApiAtom as RecoilState<TrafficViewerApi>)
|
const setTrafficViewerApiState = useSetRecoilState(trafficViewerApiAtom as RecoilState<TrafficViewerApi>)
|
||||||
const [tappingStatus, setTappingStatus] = useRecoilState(tappingStatusAtom);
|
const [tappingStatus, setTappingStatus] = useRecoilState(tappingStatusAtom);
|
||||||
|
|
||||||
|
|
||||||
const [noMoreDataTop, setNoMoreDataTop] = useState(false);
|
const [noMoreDataTop, setNoMoreDataTop] = useState(false);
|
||||||
const [isSnappedToBottom, setIsSnappedToBottom] = useState(true);
|
const [isSnappedToBottom, setIsSnappedToBottom] = useState(true);
|
||||||
|
|
||||||
@ -107,6 +103,7 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
|
|||||||
handleQueryChange(query);
|
handleQueryChange(query);
|
||||||
}, [query, handleQueryChange]);
|
}, [query, handleQueryChange]);
|
||||||
|
|
||||||
|
const ws = useRef(null);
|
||||||
|
|
||||||
const listEntry = useRef(null);
|
const listEntry = useRef(null);
|
||||||
const openWebSocket = (query: string, resetEntries: boolean) => {
|
const openWebSocket = (query: string, resetEntries: boolean) => {
|
||||||
@ -117,98 +114,99 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
|
|||||||
setLeftOffTop(null);
|
setLeftOffTop(null);
|
||||||
setNoMoreDataTop(false);
|
setNoMoreDataTop(false);
|
||||||
}
|
}
|
||||||
setQueryToSend(query)
|
ws.current = new WebSocket(webSocketUrl);
|
||||||
trafficViewerApiProp.webSocket.open();
|
ws.current.onopen = () => {
|
||||||
}
|
setWsConnection(WsConnectionStatus.Connected);
|
||||||
|
sendQueryWhenWsOpen(query);
|
||||||
const onmessage = useCallback((e) => {
|
|
||||||
if (!e?.data) return;
|
|
||||||
const message = JSON.parse(e.data);
|
|
||||||
switch (message.messageType) {
|
|
||||||
case "entry":
|
|
||||||
const entry = message.data;
|
|
||||||
if (!focusedEntryId) setFocusedEntryId(entry.id.toString());
|
|
||||||
const newEntries = [...entries, entry];
|
|
||||||
if (newEntries.length === 10001) {
|
|
||||||
setLeftOffTop(newEntries[0].entry.id);
|
|
||||||
newEntries.shift();
|
|
||||||
setNoMoreDataTop(false);
|
|
||||||
}
|
|
||||||
setEntries(newEntries);
|
|
||||||
break;
|
|
||||||
case "status":
|
|
||||||
setTappingStatus(message.tappingStatus);
|
|
||||||
break;
|
|
||||||
case "analyzeStatus":
|
|
||||||
setAnalyzeStatus(message.analyzeStatus);
|
|
||||||
break;
|
|
||||||
case "outboundLink":
|
|
||||||
onTLSDetected(message.Data.DstIP);
|
|
||||||
break;
|
|
||||||
case "toast":
|
|
||||||
toast[message.data.type](message.data.text, {
|
|
||||||
position: "bottom-right",
|
|
||||||
theme: "colored",
|
|
||||||
autoClose: message.data.autoClose,
|
|
||||||
hideProgressBar: false,
|
|
||||||
closeOnClick: true,
|
|
||||||
pauseOnHover: true,
|
|
||||||
draggable: true,
|
|
||||||
progress: undefined,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "queryMetadata":
|
|
||||||
setQueriedCurrent(queriedCurrent + message.data.current);
|
|
||||||
setQueriedTotal(message.data.total);
|
|
||||||
setLeftOffBottom(message.data.leftOff);
|
|
||||||
setTruncatedTimestamp(message.data.truncatedTimestamp);
|
|
||||||
if (leftOffTop === null) {
|
|
||||||
setLeftOffTop(message.data.leftOff - 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "startTime":
|
|
||||||
setStartTime(message.data);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.error(
|
|
||||||
`unsupported websocket message type, Got: ${message.messageType}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
ws.current.onclose = () => {
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
setWsConnection(WsConnectionStatus.Closed);
|
||||||
}, [message]);
|
}
|
||||||
|
ws.current.onerror = (event) => {
|
||||||
useEffect(() => {
|
console.error("WebSocket error:", event);
|
||||||
onmessage(message)
|
if (query) {
|
||||||
}, [message, onmessage])
|
openWebSocket(`(${query}) and leftOff(${leftOffBottom})`, false);
|
||||||
|
} else {
|
||||||
useEffect(() => {
|
openWebSocket(`leftOff(${leftOffBottom})`, false);
|
||||||
onerror(error)
|
}
|
||||||
}, [error])
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
isWebSocketOpen ? setWsConnection(WsConnectionStatus.Connected) : setWsConnection(WsConnectionStatus.Closed)
|
|
||||||
trafficViewerApiProp.webSocket.sendQuery(queryToSend)
|
|
||||||
}, [isWebSocketOpen, queryToSend, setWsConnection])
|
|
||||||
|
|
||||||
const onerror = (event) => {
|
|
||||||
console.error("WebSocket error:", event);
|
|
||||||
if (query) {
|
|
||||||
openWebSocket(`(${query}) and leftOff(${leftOffBottom})`, false);
|
|
||||||
} else {
|
|
||||||
openWebSocket(`leftOff(${leftOffBottom})`, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sendQueryWhenWsOpen = (query) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (ws?.current?.readyState === WebSocket.OPEN) {
|
||||||
|
ws.current.send(JSON.stringify({"query": query, "enableFullEntries": false}));
|
||||||
|
} else {
|
||||||
|
sendQueryWhenWsOpen(query);
|
||||||
|
}
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws.current) {
|
||||||
|
ws.current.onmessage = (e) => {
|
||||||
|
if (!e?.data) return;
|
||||||
|
const message = JSON.parse(e.data);
|
||||||
|
switch (message.messageType) {
|
||||||
|
case "entry":
|
||||||
|
const entry = message.data;
|
||||||
|
if (!focusedEntryId) setFocusedEntryId(entry.id.toString());
|
||||||
|
const newEntries = [...entries, entry];
|
||||||
|
if (newEntries.length === 10001) {
|
||||||
|
setLeftOffTop(newEntries[0].entry.id);
|
||||||
|
newEntries.shift();
|
||||||
|
setNoMoreDataTop(false);
|
||||||
|
}
|
||||||
|
setEntries(newEntries);
|
||||||
|
break;
|
||||||
|
case "status":
|
||||||
|
setTappingStatus(message.tappingStatus);
|
||||||
|
break;
|
||||||
|
case "analyzeStatus":
|
||||||
|
setAnalyzeStatus(message.analyzeStatus);
|
||||||
|
break;
|
||||||
|
case "outboundLink":
|
||||||
|
onTLSDetected(message.Data.DstIP);
|
||||||
|
break;
|
||||||
|
case "toast":
|
||||||
|
toast[message.data.type](message.data.text, {
|
||||||
|
position: "bottom-right",
|
||||||
|
theme: "colored",
|
||||||
|
autoClose: message.data.autoClose,
|
||||||
|
hideProgressBar: false,
|
||||||
|
closeOnClick: true,
|
||||||
|
pauseOnHover: true,
|
||||||
|
draggable: true,
|
||||||
|
progress: undefined,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "queryMetadata":
|
||||||
|
setQueriedCurrent(queriedCurrent + message.data.current);
|
||||||
|
setQueriedTotal(message.data.total);
|
||||||
|
setLeftOffBottom(message.data.leftOff);
|
||||||
|
setTruncatedTimestamp(message.data.truncatedTimestamp);
|
||||||
|
if (leftOffTop === null) {
|
||||||
|
setLeftOffTop(message.data.leftOff - 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "startTime":
|
||||||
|
setStartTime(message.data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(
|
||||||
|
`unsupported websocket message type, Got: ${message.messageType}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setTrafficViewerApiState({...trafficViewerApiProp, webSocket : {close : () => ws.current.close()}});
|
||||||
(async () => {
|
(async () => {
|
||||||
setTrafficViewerApiState(trafficViewerApiProp)
|
|
||||||
openWebSocket("leftOff(-1)", true);
|
openWebSocket("leftOff(-1)", true);
|
||||||
try {
|
try{
|
||||||
const tapStatusResponse = await trafficViewerApiProp.tapStatus();
|
const tapStatusResponse = await trafficViewerApiProp.tapStatus();
|
||||||
setTappingStatus(tapStatusResponse);
|
setTappingStatus(tapStatusResponse);
|
||||||
if (setAnalyzeStatus) {
|
if(setAnalyzeStatus) {
|
||||||
const analyzeStatusResponse = await trafficViewerApiProp.analyzeStatus();
|
const analyzeStatusResponse = await trafficViewerApiProp.analyzeStatus();
|
||||||
setAnalyzeStatus(analyzeStatusResponse);
|
setAnalyzeStatus(analyzeStatusResponse);
|
||||||
}
|
}
|
||||||
@ -220,8 +218,8 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const toggleConnection = () => {
|
const toggleConnection = () => {
|
||||||
if (wsConnection === WsConnectionStatus.Closed) {
|
ws.current.close();
|
||||||
|
if (wsConnection !== WsConnectionStatus.Connected) {
|
||||||
if (query) {
|
if (query) {
|
||||||
openWebSocket(`(${query}) and leftOff(-1)`, true);
|
openWebSocket(`(${query}) and leftOff(-1)`, true);
|
||||||
} else {
|
} else {
|
||||||
@ -230,10 +228,6 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
|
|||||||
scrollableRef.current.jumpToBottom();
|
scrollableRef.current.jumpToBottom();
|
||||||
setIsSnappedToBottom(true);
|
setIsSnappedToBottom(true);
|
||||||
}
|
}
|
||||||
else if (wsConnection === WsConnectionStatus.Connected) {
|
|
||||||
trafficViewerApiProp.webSocket.close()
|
|
||||||
setWsConnection(WsConnectionStatus.Closed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const onTLSDetected = (destAddress: string) => {
|
const onTLSDetected = (destAddress: string) => {
|
||||||
@ -270,7 +264,7 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
|
|||||||
const onSnapBrokenEvent = () => {
|
const onSnapBrokenEvent = () => {
|
||||||
setIsSnappedToBottom(false);
|
setIsSnappedToBottom(false);
|
||||||
if (wsConnection === WsConnectionStatus.Connected) {
|
if (wsConnection === WsConnectionStatus.Connected) {
|
||||||
trafficViewerApiProp.webSocket.close()
|
ws.current.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,16 +324,17 @@ const TrafficViewer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message
|
|||||||
setAddressesWithTLS={setAddressesWithTLS}
|
setAddressesWithTLS={setAddressesWithTLS}
|
||||||
userDismissedTLSWarning={userDismissedTLSWarning}
|
userDismissedTLSWarning={userDismissedTLSWarning}
|
||||||
setUserDismissedTLSWarning={setUserDismissedTLSWarning} />
|
setUserDismissedTLSWarning={setUserDismissedTLSWarning} />
|
||||||
|
<ToastContainer/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const MemoiedTrafficViewer = React.memo(TrafficViewer)
|
const MemoiedTrafficViewer = React.memo(TrafficViewer)
|
||||||
const TrafficViewerContainer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, message, isWebSocketOpen, trafficViewerApiProp, actionButtons, isShowStatusBar = true }) => {
|
const TrafficViewerContainer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, trafficViewerApiProp, actionButtons, isShowStatusBar = true ,webSocketUrl}) => {
|
||||||
return <RecoilRoot>
|
return <RecoilRoot>
|
||||||
<MemoiedTrafficViewer message={message} isWebSocketOpen={isWebSocketOpen} actionButtons={actionButtons} isShowStatusBar={isShowStatusBar}
|
<MemoiedTrafficViewer actionButtons={actionButtons} isShowStatusBar={isShowStatusBar} webSocketUrl={webSocketUrl}
|
||||||
trafficViewerApiProp={trafficViewerApiProp} setAnalyzeStatus={setAnalyzeStatus} />
|
trafficViewerApiProp={trafficViewerApiProp} setAnalyzeStatus={setAnalyzeStatus} />
|
||||||
</RecoilRoot>
|
</RecoilRoot>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TrafficViewerContainer
|
export default TrafficViewerContainer
|
||||||
|
@ -6,10 +6,8 @@ type TrafficViewerApi = {
|
|||||||
getEntry : (entryId : any, query:string) => any
|
getEntry : (entryId : any, query:string) => any
|
||||||
getRecentTLSLinks : () => any,
|
getRecentTLSLinks : () => any,
|
||||||
webSocket : {
|
webSocket : {
|
||||||
open : () => {},
|
close : () => {}
|
||||||
close : () => {},
|
|
||||||
sendQuery : (query:string) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TrafficViewerApi
|
export default TrafficViewerApi
|
||||||
|
BIN
ui-common/src/components/TrafficViewer/assets/ebpf.png
Normal file
BIN
ui-common/src/components/TrafficViewer/assets/ebpf.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
@ -54,7 +54,7 @@ const Queryable: React.FC<Props> = ({query, style, iconStyle, className, useTool
|
|||||||
{flipped && addButton}
|
{flipped && addButton}
|
||||||
{children}
|
{children}
|
||||||
{!flipped && addButton}
|
{!flipped && addButton}
|
||||||
{useTooltip && showTooltip && <span className={QueryableStyle.QueryableTooltip} style={tooltipStyle}>{query}</span>}
|
{useTooltip && showTooltip && <span data-cy={"QueryableTooltip"} className={QueryableStyle.QueryableTooltip} style={tooltipStyle}>{query}</span>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -11,15 +11,14 @@ const pluralize = (noun: string, amount: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const StatusBar = () => {
|
export const StatusBar = () => {
|
||||||
|
|
||||||
const tappingStatus = useRecoilValue(tappingStatusAtom);
|
const tappingStatus = useRecoilValue(tappingStatusAtom);
|
||||||
const [expandedBar, setExpandedBar] = useState(false);
|
const [expandedBar, setExpandedBar] = useState(false);
|
||||||
const {uniqueNamespaces, amountOfPods, amountOfTappedPods, amountOfUntappedPods} = useRecoilValue(tappingStatusDetails);
|
const {uniqueNamespaces, amountOfPods, amountOfTappedPods, amountOfUntappedPods} = useRecoilValue(tappingStatusDetails);
|
||||||
|
|
||||||
return <div className={`${style.statusBar} ${(expandedBar ? `${style.expandedStatusBar}` : "")}`} onMouseOver={() => setExpandedBar(true)} onMouseLeave={() => setExpandedBar(false)}>
|
return <div className={`${style.statusBar} ${(expandedBar ? `${style.expandedStatusBar}` : "")}`} onMouseOver={() => setExpandedBar(true)} onMouseLeave={() => setExpandedBar(false)} data-cy="expandedStatusBar">
|
||||||
<div className={style.podsCount}>
|
<div className={style.podsCount}>
|
||||||
{tappingStatus.some(pod => !pod.isTapped) && <img src={warningIcon} alt="warning"/>}
|
{tappingStatus.some(pod => !pod.isTapped) && <img src={warningIcon} alt="warning"/>}
|
||||||
<span className={style.podsCountText}>
|
<span className={style.podsCountText} data-cy="podsCountText">
|
||||||
{`Tapping ${amountOfUntappedPods > 0 ? amountOfTappedPods + " / " + amountOfPods : amountOfPods} ${pluralize('pod', amountOfPods)} in ${pluralize('namespace', uniqueNamespaces.length)} ${uniqueNamespaces.join(", ")}`}
|
{`Tapping ${amountOfUntappedPods > 0 ? amountOfTappedPods + " / " + amountOfPods : amountOfPods} ${pluralize('pod', amountOfPods)} in ${pluralize('namespace', uniqueNamespaces.length)} ${uniqueNamespaces.join(", ")}`}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,7 +18,9 @@ const useWS = (wsUrl: string) => {
|
|||||||
const onMessage = (e) => { setMessage(e) }
|
const onMessage = (e) => { setMessage(e) }
|
||||||
const onError = (e) => setError(e)
|
const onError = (e) => setError(e)
|
||||||
const onOpen = () => { setisOpen(true) }
|
const onOpen = () => { setisOpen(true) }
|
||||||
const onClose = () => setisOpen(false)
|
const onClose = () => {
|
||||||
|
setisOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
const openSocket = () => {
|
const openSocket = () => {
|
||||||
ws.current = new WebSocket(wsUrl)
|
ws.current = new WebSocket(wsUrl)
|
||||||
@ -36,13 +38,17 @@ const useWS = (wsUrl: string) => {
|
|||||||
ws.current.removeEventListener("close", onClose)
|
ws.current.removeEventListener("close", onClose)
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendQuery = (query: string) => {
|
const sendQueryWhenWsOpen = (query) => {
|
||||||
if (ws.current && (ws.current.readyState === WebSocketReadyState.OPEN)) {
|
setTimeout(() => {
|
||||||
ws.current.send(JSON.stringify({ "query": query, "enableFullEntries": false }));
|
if (ws?.current?.readyState === WebSocket.OPEN) {
|
||||||
}
|
ws.current.send(JSON.stringify({"query": query, "enableFullEntries": false}));
|
||||||
|
} else {
|
||||||
|
sendQueryWhenWsOpen(query);
|
||||||
|
}
|
||||||
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
return { message, error, isOpen, openSocket, closeSocket, sendQuery }
|
return { message, error, isOpen, openSocket, closeSocket, sendQueryWhenWsOpen }
|
||||||
}
|
}
|
||||||
|
|
||||||
export default useWS
|
export default useWS
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
"@types/jest": "^26.0.22",
|
"@types/jest": "^26.0.22",
|
||||||
"@types/node": "^12.20.10",
|
"@types/node": "^12.20.10",
|
||||||
"@uiw/react-textarea-code-editor": "^1.4.12",
|
"@uiw/react-textarea-code-editor": "^1.4.12",
|
||||||
"@up9/mizu-common": "1.0.125",
|
"@up9/mizu-common": "^1.0.128",
|
||||||
"axios": "^0.25.0",
|
"axios": "^0.25.0",
|
||||||
"core-js": "^3.20.2",
|
"core-js": "^3.20.2",
|
||||||
"craco-babel-loader": "^1.0.3",
|
"craco-babel-loader": "^1.0.3",
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, {useEffect} from "react";
|
||||||
import { Button } from "@material-ui/core";
|
import { Button } from "@material-ui/core";
|
||||||
import Api, {getWebsocketUrl} from "../../../helpers/api";
|
import Api,{getWebsocketUrl} from "../../../helpers/api";
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import {useSetRecoilState, useRecoilState} from "recoil";
|
import {useSetRecoilState, useRecoilState} from "recoil";
|
||||||
import {useCommonStyles} from "../../../helpers/commonStyle"
|
import {useCommonStyles} from "../../../helpers/commonStyle"
|
||||||
import serviceMapModalOpenAtom from "../../../recoil/serviceMapModalOpen";
|
import serviceMapModalOpenAtom from "../../../recoil/serviceMapModalOpen";
|
||||||
import TrafficViewer ,{useWS,DEFAULT_QUERY} from "@up9/mizu-common"
|
import TrafficViewer from "@up9/mizu-common"
|
||||||
import "@up9/mizu-common/dist/index.css"
|
import "@up9/mizu-common/dist/index.css"
|
||||||
import oasModalOpenAtom from "../../../recoil/oasModalOpen/atom";
|
import oasModalOpenAtom from "../../../recoil/oasModalOpen/atom";
|
||||||
import serviceMap from "../../assets/serviceMap.svg";
|
import serviceMap from "../../assets/serviceMap.svg";
|
||||||
@ -22,11 +22,10 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
|
|||||||
const setServiceMapModalOpen = useSetRecoilState(serviceMapModalOpenAtom);
|
const setServiceMapModalOpen = useSetRecoilState(serviceMapModalOpenAtom);
|
||||||
const [openOasModal, setOpenOasModal] = useRecoilState(oasModalOpenAtom);
|
const [openOasModal, setOpenOasModal] = useRecoilState(oasModalOpenAtom);
|
||||||
|
|
||||||
const {message,error,isOpen, openSocket, closeSocket, sendQuery} = useWS(getWebsocketUrl())
|
const trafficViewerApi = {...api}
|
||||||
const trafficViewerApi = {...api, webSocket:{open : openSocket, close: closeSocket, sendQuery: sendQuery}}
|
|
||||||
|
|
||||||
const handleOpenOasModal = () => {
|
const handleOpenOasModal = () => {
|
||||||
closeSocket()
|
//closeSocket() -- Todo: Add Close webSocket
|
||||||
setOpenOasModal(true);
|
setOpenOasModal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,18 +55,16 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
|
|||||||
</Button>}
|
</Button>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
sendQuery(DEFAULT_QUERY);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
closeSocket()
|
//closeSocket()
|
||||||
}
|
}
|
||||||
},[])
|
},[])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TrafficViewer setAnalyzeStatus={setAnalyzeStatus} message={message} error={error} isWebSocketOpen={isOpen}
|
<TrafficViewer setAnalyzeStatus={setAnalyzeStatus} webSocketUrl={getWebsocketUrl()}
|
||||||
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!openOasModal}/>
|
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!openOasModal}/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user