mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-03-06 04:32:12 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ef6afa395 | ||
|
|
f8c0ddd69a | ||
|
|
2253737625 | ||
|
|
4a0294c61a | ||
|
|
9053c58146 | ||
|
|
5d5b13fc86 | ||
|
|
af61c69fb6 | ||
|
|
94dfa68858 | ||
|
|
50c0062db4 | ||
|
|
720969bbe6 |
@@ -183,6 +183,7 @@ func resolveIP(connectionInfo *tapApi.ConnectionInfo) (resolvedSource string, re
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resolvedSource = resolvedSourceObject.FullAddress
|
resolvedSource = resolvedSourceObject.FullAddress
|
||||||
|
namespace = resolvedSourceObject.Namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
unresolvedDestination := fmt.Sprintf("%s:%s", connectionInfo.ServerIP, connectionInfo.ServerPort)
|
unresolvedDestination := fmt.Sprintf("%s:%s", connectionInfo.ServerIP, connectionInfo.ServerPort)
|
||||||
@@ -194,7 +195,11 @@ func resolveIP(connectionInfo *tapApi.ConnectionInfo) (resolvedSource string, re
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resolvedDestination = resolvedDestinationObject.FullAddress
|
resolvedDestination = resolvedDestinationObject.FullAddress
|
||||||
namespace = resolvedDestinationObject.Namespace
|
// Overwrite namespace (if it was set according to the source)
|
||||||
|
// Only overwrite if non-empty
|
||||||
|
if resolvedDestinationObject.Namespace != "" {
|
||||||
|
namespace = resolvedDestinationObject.Namespace
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resolvedSource, resolvedDestination, namespace
|
return resolvedSource, resolvedDestination, namespace
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ func UpdateTapTargets(newTapTargets []v1.Pod) {
|
|||||||
|
|
||||||
tapTargets = newTapTargets
|
tapTargets = newTapTargets
|
||||||
|
|
||||||
packetSourceManager.UpdatePods(tapTargets)
|
packetSourceManager.UpdatePods(tapTargets, !*nodefrag, mainPacketInputChan)
|
||||||
|
|
||||||
if tlsTapperInstance != nil {
|
if tlsTapperInstance != nil {
|
||||||
if err := tlstapper.UpdateTapTargets(tlsTapperInstance, &tapTargets, *procfs); err != nil {
|
if err := tlstapper.UpdateTapTargets(tlsTapperInstance, &tapTargets, *procfs); err != nil {
|
||||||
@@ -198,12 +198,8 @@ func initializePacketSources() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if packetSourceManager, err = source.NewPacketSourceManager(*procfs, *fname, *iface, *servicemesh, tapTargets, behaviour); err != nil {
|
packetSourceManager, err = source.NewPacketSourceManager(*procfs, *fname, *iface, *servicemesh, tapTargets, behaviour, !*nodefrag, mainPacketInputChan)
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
packetSourceManager.ReadPackets(!*nodefrag, mainPacketInputChan)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func initializePassiveTapper(opts *TapOpts, outputItems chan *api.OutputChannelItem) (*tcpStreamMap, *tcpAssembler) {
|
func initializePassiveTapper(opts *TapOpts, outputItems chan *api.OutputChannelItem) (*tcpStreamMap, *tcpAssembler) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ type PacketSourceManager struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewPacketSourceManager(procfs string, filename string, interfaceName string,
|
func NewPacketSourceManager(procfs string, filename string, interfaceName string,
|
||||||
mtls bool, pods []v1.Pod, behaviour TcpPacketSourceBehaviour) (*PacketSourceManager, error) {
|
mtls bool, pods []v1.Pod, behaviour TcpPacketSourceBehaviour, ipdefrag bool, packets chan<- TcpPacketInfo) (*PacketSourceManager, error) {
|
||||||
hostSource, err := newHostPacketSource(filename, interfaceName, behaviour)
|
hostSource, err := newHostPacketSource(filename, interfaceName, behaviour)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -43,7 +43,7 @@ func NewPacketSourceManager(procfs string, filename string, interfaceName string
|
|||||||
behaviour: behaviour,
|
behaviour: behaviour,
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceManager.UpdatePods(pods)
|
go hostSource.readPackets(ipdefrag, packets)
|
||||||
return sourceManager, nil
|
return sourceManager, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,16 +64,16 @@ func newHostPacketSource(filename string, interfaceName string,
|
|||||||
return source, nil
|
return source, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PacketSourceManager) UpdatePods(pods []v1.Pod) {
|
func (m *PacketSourceManager) UpdatePods(pods []v1.Pod, ipdefrag bool, packets chan<- TcpPacketInfo) {
|
||||||
if m.config.mtls {
|
if m.config.mtls {
|
||||||
m.updateMtlsPods(m.config.procfs, pods, m.config.interfaceName, m.config.behaviour)
|
m.updateMtlsPods(m.config.procfs, pods, m.config.interfaceName, m.config.behaviour, ipdefrag, packets)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.setBPFFilter(pods)
|
m.setBPFFilter(pods)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PacketSourceManager) updateMtlsPods(procfs string, pods []v1.Pod,
|
func (m *PacketSourceManager) updateMtlsPods(procfs string, pods []v1.Pod,
|
||||||
interfaceName string, behaviour TcpPacketSourceBehaviour) {
|
interfaceName string, behaviour TcpPacketSourceBehaviour, ipdefrag bool, packets chan<- TcpPacketInfo) {
|
||||||
|
|
||||||
relevantPids := m.getRelevantPids(procfs, pods)
|
relevantPids := m.getRelevantPids(procfs, pods)
|
||||||
logger.Log.Infof("Updating mtls pods (new: %v) (current: %v)", relevantPids, m.sources)
|
logger.Log.Infof("Updating mtls pods (new: %v) (current: %v)", relevantPids, m.sources)
|
||||||
@@ -90,6 +90,7 @@ func (m *PacketSourceManager) updateMtlsPods(procfs string, pods []v1.Pod,
|
|||||||
source, err := newNetnsPacketSource(procfs, pid, interfaceName, behaviour)
|
source, err := newNetnsPacketSource(procfs, pid, interfaceName, behaviour)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
go source.readPackets(ipdefrag, packets)
|
||||||
m.sources[pid] = source
|
m.sources[pid] = source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,12 +154,6 @@ func (m *PacketSourceManager) setBPFFilter(pods []v1.Pod) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PacketSourceManager) ReadPackets(ipdefrag bool, packets chan<- TcpPacketInfo) {
|
|
||||||
for _, src := range m.sources {
|
|
||||||
go src.readPackets(ipdefrag, packets)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *PacketSourceManager) Close() {
|
func (m *PacketSourceManager) Close() {
|
||||||
for _, src := range m.sources {
|
for _, src := range m.sources {
|
||||||
src.close()
|
src.close()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import { Button } from "@material-ui/core";
|
import { Button } from "@material-ui/core";
|
||||||
import Api,{getWebsocketUrl} from "../../../helpers/api";
|
import Api, { MizuWebsocketURL } 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"
|
||||||
@@ -65,7 +65,7 @@ const trafficViewerApi = {...api}
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TrafficViewer setAnalyzeStatus={setAnalyzeStatus} webSocketUrl={getWebsocketUrl()} isCloseWebSocket={!openWebSocket}
|
<TrafficViewer setAnalyzeStatus={setAnalyzeStatus} webSocketUrl={MizuWebsocketURL} isCloseWebSocket={!openWebSocket}
|
||||||
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!openOasModal} isDemoBannerView={false}/>
|
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!openOasModal} isDemoBannerView={false}/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ export const ServiceMapModal: React.FC<ServiceMapModalProps> = ({ isOpen, onOpen
|
|||||||
const commonClasses = useCommonStyles();
|
const commonClasses = useCommonStyles();
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||||
const [graphData, setGraphData] = useState<GraphData>({ nodes: [], edges: [] });
|
const [graphData, setGraphData] = useState<GraphData>({ nodes: [], edges: [] });
|
||||||
|
const [graphOptions, setGraphOptions] = useState(ServiceMapOptions);
|
||||||
|
|
||||||
const getServiceMapData = useCallback(async () => {
|
const getServiceMapData = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
@@ -149,6 +150,14 @@ export const ServiceMapModal: React.FC<ServiceMapModalProps> = ({ isOpen, onOpen
|
|||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, [isOpen])
|
}, [isOpen])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(graphData?.nodes?.length === 0) return;
|
||||||
|
let options = {...graphOptions};
|
||||||
|
options.physics.barnesHut.avoidOverlap = graphData?.nodes?.length > 10 ? 0 : 1;
|
||||||
|
setGraphOptions(options);
|
||||||
|
// eslint-disable-next-line
|
||||||
|
},[graphData?.nodes?.length])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getServiceMapData();
|
getServiceMapData();
|
||||||
return () => setGraphData({ nodes: [], edges: [] })
|
return () => setGraphData({ nodes: [], edges: [] })
|
||||||
@@ -180,7 +189,7 @@ export const ServiceMapModal: React.FC<ServiceMapModalProps> = ({ isOpen, onOpen
|
|||||||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
startIcon={<img src={refresh} className="custom" alt="refresh" style={{ marginRight: "8%" }}></img>}
|
startIcon={<img src={refresh} className="custom" alt="refresh" style={{ marginRight: "8%" }}/>}
|
||||||
size="medium"
|
size="medium"
|
||||||
variant="contained"
|
variant="contained"
|
||||||
className={commonClasses.outlinedButton + " " + commonClasses.imagedButton}
|
className={commonClasses.outlinedButton + " " + commonClasses.imagedButton}
|
||||||
@@ -189,20 +198,20 @@ export const ServiceMapModal: React.FC<ServiceMapModalProps> = ({ isOpen, onOpen
|
|||||||
Refresh
|
Refresh
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<img src={close} alt="close" onClick={() => onClose()} style={{ cursor: "pointer" }}></img>
|
<img src={close} alt="close" onClick={() => onClose()} style={{ cursor: "pointer" }}/>
|
||||||
</div>
|
</div>
|
||||||
<Graph
|
<Graph
|
||||||
graph={graphData}
|
graph={graphData}
|
||||||
options={ServiceMapOptions}
|
options={graphOptions}
|
||||||
/>
|
/>
|
||||||
<div className='legend-scale'>
|
<div className='legend-scale'>
|
||||||
<ul className='legend-labels'>
|
<ul className='legend-labels'>
|
||||||
<li><span style={{ background: '#205cf5' }}></span>HTTP</li>
|
<li><span style={{ background: '#205cf5' }}/>HTTP</li>
|
||||||
<li><span style={{ background: '#244c5a' }}></span>HTTP/2</li>
|
<li><span style={{ background: '#244c5a' }}/>HTTP/2</li>
|
||||||
<li><span style={{ background: '#244c5a' }}></span>gRPC</li>
|
<li><span style={{ background: '#244c5a' }}/>gRPC</li>
|
||||||
<li><span style={{ background: '#ff6600' }}></span>AMQP</li>
|
<li><span style={{ background: '#ff6600' }}/>AMQP</li>
|
||||||
<li><span style={{ background: '#000000' }}></span>KAFKA</li>
|
<li><span style={{ background: '#000000' }}/>KAFKA</li>
|
||||||
<li><span style={{ background: '#a41e11' }}></span>REDIS</li>
|
<li><span style={{ background: '#a41e11' }}/>REDIS</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
@@ -211,4 +220,4 @@ export const ServiceMapModal: React.FC<ServiceMapModalProps> = ({ isOpen, onOpen
|
|||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ const ServiceMapOptions = {
|
|||||||
springLength: 180,
|
springLength: 180,
|
||||||
springConstant: 0.04,
|
springConstant: 0.04,
|
||||||
damping: 0.2,
|
damping: 0.2,
|
||||||
avoidOverlap: 1
|
avoidOverlap: 0
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
layout: {
|
layout: {
|
||||||
@@ -171,4 +171,4 @@ const ServiceMapOptions = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ServiceMapOptions
|
export default ServiceMapOptions
|
||||||
|
|||||||
@@ -3,13 +3,10 @@ import * as axios from "axios";
|
|||||||
export const MizuWebsocketURL = process.env.REACT_APP_OVERRIDE_WS_URL ? process.env.REACT_APP_OVERRIDE_WS_URL :
|
export const MizuWebsocketURL = process.env.REACT_APP_OVERRIDE_WS_URL ? process.env.REACT_APP_OVERRIDE_WS_URL :
|
||||||
window.location.protocol === 'https:' ? `wss://${window.location.host}/ws` : `ws://${window.location.host}/ws`;
|
window.location.protocol === 'https:' ? `wss://${window.location.host}/ws` : `ws://${window.location.host}/ws`;
|
||||||
|
|
||||||
export const FormValidationErrorType = "formError";
|
|
||||||
|
|
||||||
const CancelToken = axios.CancelToken;
|
const CancelToken = axios.CancelToken;
|
||||||
|
|
||||||
const apiURL = process.env.REACT_APP_OVERRIDE_API_URL ? process.env.REACT_APP_OVERRIDE_API_URL : `${window.location.origin}/`;
|
const apiURL = process.env.REACT_APP_OVERRIDE_API_URL ? process.env.REACT_APP_OVERRIDE_API_URL : `${window.location.origin}/`;
|
||||||
|
|
||||||
let token = ""
|
|
||||||
let client = null
|
let client = null
|
||||||
let source = null
|
let source = null
|
||||||
|
|
||||||
@@ -24,8 +21,6 @@ export default class Api {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
token = localStorage.getItem("token");
|
|
||||||
|
|
||||||
client = this.getAxiosClient();
|
client = this.getAxiosClient();
|
||||||
source = null;
|
source = null;
|
||||||
}
|
}
|
||||||
@@ -125,20 +120,10 @@ export default class Api {
|
|||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
persistToken = (tk) => {
|
|
||||||
token = tk;
|
|
||||||
client = this.getAxiosClient();
|
|
||||||
localStorage.setItem('token', token);
|
|
||||||
}
|
|
||||||
|
|
||||||
getAxiosClient = () => {
|
getAxiosClient = () => {
|
||||||
const headers = {
|
const headers = {
|
||||||
Accept: "application/json"
|
Accept: "application/json"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token) {
|
|
||||||
headers['x-session-token'] = `${token}`; // we use `x-session-token` instead of `Authorization` because the latter is reserved by kubectl proxy, making mizu view not work
|
|
||||||
}
|
|
||||||
return axios.create({
|
return axios.create({
|
||||||
baseURL: apiURL,
|
baseURL: apiURL,
|
||||||
timeout: 31000,
|
timeout: 31000,
|
||||||
@@ -146,12 +131,3 @@ export default class Api {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getWebsocketUrl() {
|
|
||||||
let websocketUrl = MizuWebsocketURL;
|
|
||||||
if (token) {
|
|
||||||
websocketUrl += `/${token}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return websocketUrl;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user