mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-02-24 07:33:07 +00:00
Compare commits
9 Commits
30.0-dev21
...
30.0-dev29
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e7704eb15 | ||
|
|
dbcb776139 | ||
|
|
a3de34f544 | ||
|
|
99667984d6 | ||
|
|
763b0e7362 | ||
|
|
e07e04377f | ||
|
|
3c8f63ed92 | ||
|
|
11a2246cb9 | ||
|
|
a2595afd5e |
@@ -77,8 +77,8 @@ RUN go build -ldflags="-extldflags=-static -s -w \
|
||||
-X 'github.com/up9inc/mizu/agent/pkg/version.Ver=${VER}'" -o mizuagent .
|
||||
|
||||
# Download Basenine executable, verify the sha1sum
|
||||
ADD https://github.com/up9inc/basenine/releases/download/v0.6.5/basenine_linux_${GOARCH} ./basenine_linux_${GOARCH}
|
||||
ADD https://github.com/up9inc/basenine/releases/download/v0.6.5/basenine_linux_${GOARCH}.sha256 ./basenine_linux_${GOARCH}.sha256
|
||||
ADD https://github.com/up9inc/basenine/releases/download/v0.6.6/basenine_linux_${GOARCH} ./basenine_linux_${GOARCH}
|
||||
ADD https://github.com/up9inc/basenine/releases/download/v0.6.6/basenine_linux_${GOARCH}.sha256 ./basenine_linux_${GOARCH}.sha256
|
||||
RUN shasum -a 256 -c basenine_linux_${GOARCH}.sha256
|
||||
RUN chmod +x ./basenine_linux_${GOARCH}
|
||||
RUN mv ./basenine_linux_${GOARCH} ./basenine
|
||||
|
||||
@@ -20,7 +20,7 @@ require (
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/up9inc/basenine/client/go v0.0.0-20220317230530-8472d80307f6
|
||||
github.com/up9inc/basenine/client/go v0.0.0-20220326121918-785f3061c8ce
|
||||
github.com/up9inc/mizu/shared v0.0.0
|
||||
github.com/up9inc/mizu/tap v0.0.0
|
||||
github.com/up9inc/mizu/tap/api v0.0.0
|
||||
|
||||
@@ -681,8 +681,8 @@ github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
||||
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
||||
github.com/up9inc/basenine/client/go v0.0.0-20220317230530-8472d80307f6 h1:c0aVbLKYeFDAg246+NDgie2y484bsc20NaKLo8ODV3E=
|
||||
github.com/up9inc/basenine/client/go v0.0.0-20220317230530-8472d80307f6/go.mod h1:SvJGPoa/6erhUQV7kvHBwM/0x5LyO6XaG2lUaCaKiUI=
|
||||
github.com/up9inc/basenine/client/go v0.0.0-20220326121918-785f3061c8ce h1:vMTCpKItc9OyTLJXocNaq2NcBU5EnurJgTVOYb8W8dw=
|
||||
github.com/up9inc/basenine/client/go v0.0.0-20220326121918-785f3061c8ce/go.mod h1:SvJGPoa/6erhUQV7kvHBwM/0x5LyO6XaG2lUaCaKiUI=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/wI2L/jsondiff v0.1.1 h1:r2TkoEet7E4JMO5+s1RCY2R0LrNPNHY6hbDeow2hRHw=
|
||||
|
||||
@@ -40,7 +40,7 @@ type ConfigStruct struct {
|
||||
HeadlessMode bool `yaml:"headless" default:"false"`
|
||||
LogLevelStr string `yaml:"log-level,omitempty" default:"INFO" readonly:""`
|
||||
ServiceMap bool `yaml:"service-map" default:"true"`
|
||||
OAS bool `yaml:"oas,omitempty" default:"false" readonly:""`
|
||||
OAS bool `yaml:"oas" default:"true"`
|
||||
Elastic shared.ElasticConfig `yaml:"elastic"`
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ require (
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||
github.com/spf13/cobra v1.3.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/up9inc/basenine/server/lib v0.0.0-20220317230530-8472d80307f6
|
||||
github.com/up9inc/basenine/server/lib v0.0.0-20220326121918-785f3061c8ce
|
||||
github.com/up9inc/mizu/shared v0.0.0
|
||||
github.com/up9inc/mizu/tap/api v0.0.0
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
|
||||
@@ -600,8 +600,8 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/up9inc/basenine/server/lib v0.0.0-20220317230530-8472d80307f6 h1:+RZTD+HdfIW2SMbc65yWkruTY+g5/1Av074m62A74ls=
|
||||
github.com/up9inc/basenine/server/lib v0.0.0-20220317230530-8472d80307f6/go.mod h1:ZIkxWiJm65jYQIso9k+OZKhR7gQ1we2jNyE2kQX9IQI=
|
||||
github.com/up9inc/basenine/server/lib v0.0.0-20220326121918-785f3061c8ce h1:PypqybjmuxftGkX4NmP4JAUyEykZj2r6W4r9lnRZ/kE=
|
||||
github.com/up9inc/basenine/server/lib v0.0.0-20220326121918-785f3061c8ce/go.mod h1:ZIkxWiJm65jYQIso9k+OZKhR7gQ1we2jNyE2kQX9IQI=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||
github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
|
||||
|
||||
@@ -66,6 +66,7 @@ var filteringOptions *api.TrafficFilteringOptions // global
|
||||
var tapTargets []v1.Pod // global
|
||||
var packetSourceManager *source.PacketSourceManager // global
|
||||
var mainPacketInputChan chan source.TcpPacketInfo // global
|
||||
var tlsTapperInstance *tlstapper.TlsTapper // global
|
||||
|
||||
func inArrayInt(arr []int, valueToCheck int) bool {
|
||||
for _, value := range arr {
|
||||
@@ -92,7 +93,7 @@ func StartPassiveTapper(opts *TapOpts, outputItems chan *api.OutputChannelItem,
|
||||
if *tls {
|
||||
for _, e := range extensions {
|
||||
if e.Protocol.Name == "http" {
|
||||
startTlsTapper(e, outputItems, options)
|
||||
tlsTapperInstance = startTlsTapper(e, outputItems, options)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -106,20 +107,34 @@ func StartPassiveTapper(opts *TapOpts, outputItems chan *api.OutputChannelItem,
|
||||
}
|
||||
|
||||
func UpdateTapTargets(newTapTargets []v1.Pod) {
|
||||
success := true
|
||||
|
||||
tapTargets = newTapTargets
|
||||
if err := initializePacketSources(); err != nil {
|
||||
logger.Log.Fatal(err)
|
||||
|
||||
packetSourceManager.UpdatePods(tapTargets)
|
||||
|
||||
if tlsTapperInstance != nil {
|
||||
if err := tlstapper.UpdateTapTargets(tlsTapperInstance, &tapTargets, *procfs); err != nil {
|
||||
tlstapper.LogError(err)
|
||||
success = false
|
||||
}
|
||||
}
|
||||
printNewTapTargets()
|
||||
|
||||
printNewTapTargets(success)
|
||||
}
|
||||
|
||||
func printNewTapTargets() {
|
||||
func printNewTapTargets(success bool) {
|
||||
printStr := ""
|
||||
for _, tapTarget := range tapTargets {
|
||||
printStr += fmt.Sprintf("%s (%s), ", tapTarget.Status.PodIP, tapTarget.Name)
|
||||
}
|
||||
printStr = strings.TrimRight(printStr, ", ")
|
||||
logger.Log.Infof("Now tapping: %s", printStr)
|
||||
|
||||
if success {
|
||||
logger.Log.Infof("Now tapping: %s", printStr)
|
||||
} else {
|
||||
logger.Log.Errorf("Failed to start tapping: %s", printStr)
|
||||
}
|
||||
}
|
||||
|
||||
func printPeriodicStats(cleaner *Cleaner) {
|
||||
@@ -236,13 +251,18 @@ func startPassiveTapper(opts *TapOpts, outputItems chan *api.OutputChannelItem)
|
||||
logger.Log.Infof("AppStats: %v", diagnose.AppStats)
|
||||
}
|
||||
|
||||
func startTlsTapper(extension *api.Extension, outputItems chan *api.OutputChannelItem, options *api.TrafficFilteringOptions) {
|
||||
func startTlsTapper(extension *api.Extension, outputItems chan *api.OutputChannelItem, options *api.TrafficFilteringOptions) *tlstapper.TlsTapper {
|
||||
tls := tlstapper.TlsTapper{}
|
||||
tlsPerfBufferSize := os.Getpagesize() * 100
|
||||
|
||||
if err := tls.Init(tlsPerfBufferSize, *procfs, extension); err != nil {
|
||||
tlstapper.LogError(err)
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := tlstapper.UpdateTapTargets(&tls, &tapTargets, *procfs); err != nil {
|
||||
tlstapper.LogError(err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// A quick way to instrument libssl.so without PID filtering - used for debuging and troubleshooting
|
||||
@@ -250,19 +270,16 @@ func startTlsTapper(extension *api.Extension, outputItems chan *api.OutputChanne
|
||||
if os.Getenv("MIZU_GLOBAL_SSL_LIBRARY") != "" {
|
||||
if err := tls.GlobalTap(os.Getenv("MIZU_GLOBAL_SSL_LIBRARY")); err != nil {
|
||||
tlstapper.LogError(err)
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if err := tlstapper.UpdateTapTargets(&tls, &tapTargets, *procfs); err != nil {
|
||||
tlstapper.LogError(err)
|
||||
return
|
||||
}
|
||||
|
||||
var emitter api.Emitter = &api.Emitting{
|
||||
AppStats: &diagnose.AppStats,
|
||||
OutputChannel: outputItems,
|
||||
}
|
||||
|
||||
go tls.Poll(emitter, options)
|
||||
|
||||
return &tls
|
||||
}
|
||||
|
||||
@@ -11,8 +11,16 @@ import (
|
||||
const bpfFilterMaxPods = 150
|
||||
const hostSourcePid = "0"
|
||||
|
||||
type PacketSourceManagerConfig struct {
|
||||
mtls bool
|
||||
procfs string
|
||||
interfaceName string
|
||||
behaviour TcpPacketSourceBehaviour
|
||||
}
|
||||
|
||||
type PacketSourceManager struct {
|
||||
sources map[string]*tcpPacketSource
|
||||
config PacketSourceManagerConfig
|
||||
}
|
||||
|
||||
func NewPacketSourceManager(procfs string, filename string, interfaceName string,
|
||||
@@ -28,7 +36,14 @@ func NewPacketSourceManager(procfs string, filename string, interfaceName string
|
||||
},
|
||||
}
|
||||
|
||||
sourceManager.UpdatePods(mtls, procfs, pods, interfaceName, behaviour)
|
||||
sourceManager.config = PacketSourceManagerConfig{
|
||||
mtls: mtls,
|
||||
procfs: procfs,
|
||||
interfaceName: interfaceName,
|
||||
behaviour: behaviour,
|
||||
}
|
||||
|
||||
sourceManager.UpdatePods(pods)
|
||||
return sourceManager, nil
|
||||
}
|
||||
|
||||
@@ -49,10 +64,9 @@ func newHostPacketSource(filename string, interfaceName string,
|
||||
return source, nil
|
||||
}
|
||||
|
||||
func (m *PacketSourceManager) UpdatePods(mtls bool, procfs string, pods []v1.Pod,
|
||||
interfaceName string, behaviour TcpPacketSourceBehaviour) {
|
||||
if mtls {
|
||||
m.updateMtlsPods(procfs, pods, interfaceName, behaviour)
|
||||
func (m *PacketSourceManager) UpdatePods(pods []v1.Pod) {
|
||||
if m.config.mtls {
|
||||
m.updateMtlsPods(m.config.procfs, pods, m.config.interfaceName, m.config.behaviour)
|
||||
}
|
||||
|
||||
m.setBPFFilter(pods)
|
||||
|
||||
@@ -24,6 +24,8 @@ func UpdateTapTargets(tls *TlsTapper, pods *[]v1.Pod, procfs string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tls.ClearPids()
|
||||
|
||||
for _, pid := range containerPids {
|
||||
if err := tls.AddPid(procfs, pid); err != nil {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/up9inc/mizu/shared/logger"
|
||||
"github.com/up9inc/mizu/tap/api"
|
||||
"sync"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go tlsTapper bpf/tls_tapper.c -- -O2 -g -D__TARGET_ARCH_x86
|
||||
@@ -14,6 +15,7 @@ type TlsTapper struct {
|
||||
syscallHooks syscallHooks
|
||||
sslHooksStructs []sslHooks
|
||||
poller *tlsPoller
|
||||
registeredPids sync.Map
|
||||
}
|
||||
|
||||
func (t *TlsTapper) Init(bufferSize int, procfs string, extension *api.Extension) error {
|
||||
@@ -70,6 +72,16 @@ func (t *TlsTapper) RemovePid(pid uint32) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TlsTapper) ClearPids() {
|
||||
t.registeredPids.Range(func(key, v interface{}) bool {
|
||||
if err := t.RemovePid(key.(uint32)); err != nil {
|
||||
LogError(err)
|
||||
}
|
||||
t.registeredPids.Delete(key)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (t *TlsTapper) Close() []error {
|
||||
errors := make([]error, 0)
|
||||
|
||||
@@ -116,6 +128,8 @@ func (t *TlsTapper) tapPid(pid uint32, sslLibrary string) error {
|
||||
if err := pids.Put(pid, uint32(1)); err != nil {
|
||||
return errors.Wrap(err, 0)
|
||||
}
|
||||
|
||||
t.registeredPids.Store(pid, true)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
4
ui-common/package-lock.json
generated
4
ui-common/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@up9/mizu-common",
|
||||
"version": "1.0.10",
|
||||
"version": "1.0.135",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@up9/mizu-common",
|
||||
"version": "1.0.10",
|
||||
"version": "1.0.135",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@craco/craco": "^6.4.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@up9/mizu-common",
|
||||
"version": "1.0.135",
|
||||
"version": "1.0.137",
|
||||
"description": "Made with create-react-library",
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -11,6 +11,7 @@ import trafficViewerApi from "../../recoil/TrafficViewerApi";
|
||||
import TrafficViewerApi from "./TrafficViewerApi";
|
||||
import TrafficViewerApiAtom from "../../recoil/TrafficViewerApi/atom";
|
||||
import queryAtom from "../../recoil/query/atom";
|
||||
import useWindowDimensions, { useRequestTextByWidth } from "../../hooks/WindowDimensionsHook";
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
entryTitle: {
|
||||
@@ -35,15 +36,18 @@ const useStyles = makeStyles(() => ({
|
||||
}));
|
||||
|
||||
export const formatSize = (n: number) => n > 1000 ? `${Math.round(n / 1000)}KB` : `${n} B`;
|
||||
|
||||
const minSizeDisplayRequestSize = 880;
|
||||
const EntryTitle: React.FC<any> = ({protocol, data, elapsedTime}) => {
|
||||
const classes = useStyles();
|
||||
const request = data.request;
|
||||
const response = data.response;
|
||||
|
||||
const { width } = useWindowDimensions();
|
||||
const {requestText, responseText, elapsedTimeText} = useRequestTextByWidth(width)
|
||||
|
||||
return <div className={classes.entryTitle}>
|
||||
<Protocol protocol={protocol} horizontal={true}/>
|
||||
<div style={{right: "30px", position: "absolute", display: "flex"}}>
|
||||
{(width > minSizeDisplayRequestSize) && <div style={{right: "30px", position: "absolute", display: "flex"}}>
|
||||
{request && <Queryable
|
||||
query={`requestSize == ${data.requestSize}`}
|
||||
style={{margin: "0 18px"}}
|
||||
@@ -53,7 +57,7 @@ const EntryTitle: React.FC<any> = ({protocol, data, elapsedTime}) => {
|
||||
style={{opacity: 0.5}}
|
||||
id="entryDetailedTitleRequestSize"
|
||||
>
|
||||
{`Request: ${formatSize(data.requestSize)}`}
|
||||
{`${requestText}${formatSize(data.requestSize)}`}
|
||||
</div>
|
||||
</Queryable>}
|
||||
{response && <Queryable
|
||||
@@ -65,22 +69,22 @@ const EntryTitle: React.FC<any> = ({protocol, data, elapsedTime}) => {
|
||||
style={{opacity: 0.5}}
|
||||
id="entryDetailedTitleResponseSize"
|
||||
>
|
||||
{`Response: ${formatSize(data.responseSize)}`}
|
||||
{`${responseText}${formatSize(data.responseSize)}`}
|
||||
</div>
|
||||
</Queryable>}
|
||||
{response && <Queryable
|
||||
query={`elapsedTime >= ${elapsedTime}`}
|
||||
style={{marginRight: 18}}
|
||||
style={{margin: "0 0 0 18px"}}
|
||||
displayIconOnMouseOver={true}
|
||||
>
|
||||
<div
|
||||
style={{opacity: 0.5}}
|
||||
id="entryDetailedTitleElapsedTime"
|
||||
>
|
||||
{`Elapsed Time: ${Math.round(elapsedTime)}ms`}
|
||||
{`${elapsedTimeText}${Math.round(elapsedTime)}ms`}
|
||||
</div>
|
||||
</Queryable>}
|
||||
</div>
|
||||
</div>}
|
||||
</div>;
|
||||
};
|
||||
|
||||
|
||||
@@ -48,12 +48,13 @@ interface TrafficViewerProps {
|
||||
actionButtons?: JSX.Element,
|
||||
isShowStatusBar?: boolean,
|
||||
webSocketUrl : string,
|
||||
isCloseWebSocket : boolean
|
||||
isCloseWebSocket : boolean,
|
||||
isDemoBannerView : boolean
|
||||
}
|
||||
|
||||
export const TrafficViewer : React.FC<TrafficViewerProps> = ({setAnalyzeStatus, trafficViewerApiProp,
|
||||
actionButtons,isShowStatusBar,webSocketUrl,
|
||||
isCloseWebSocket}) => {
|
||||
isCloseWebSocket, isDemoBannerView}) => {
|
||||
|
||||
const classes = useLayoutStyles();
|
||||
|
||||
@@ -293,7 +294,7 @@ export const TrafficViewer : React.FC<TrafficViewerProps> = ({setAnalyzeStatus,
|
||||
|
||||
return (
|
||||
<div className={TrafficViewerStyles.TrafficPage}>
|
||||
{tappingStatus && isShowStatusBar && <StatusBar />}
|
||||
{tappingStatus && isShowStatusBar && <StatusBar isDemoBannerView={isDemoBannerView} />}
|
||||
<div className={TrafficViewerStyles.TrafficPageHeader}>
|
||||
<div className={TrafficViewerStyles.TrafficPageStreamStatus}>
|
||||
<img className={TrafficViewerStyles.playPauseIcon} style={{ visibility: ws?.current?.readyState === WebSocket.OPEN ? "visible" : "hidden" }} alt="pause"
|
||||
@@ -356,11 +357,11 @@ export const TrafficViewer : React.FC<TrafficViewerProps> = ({setAnalyzeStatus,
|
||||
const MemoiedTrafficViewer = React.memo(TrafficViewer)
|
||||
const TrafficViewerContainer: React.FC<TrafficViewerProps> = ({ setAnalyzeStatus, trafficViewerApiProp,
|
||||
actionButtons, isShowStatusBar = true ,
|
||||
webSocketUrl, isCloseWebSocket}) => {
|
||||
webSocketUrl, isCloseWebSocket, isDemoBannerView}) => {
|
||||
return <RecoilRoot>
|
||||
<MemoiedTrafficViewer actionButtons={actionButtons} isShowStatusBar={isShowStatusBar} webSocketUrl={webSocketUrl}
|
||||
isCloseWebSocket={isCloseWebSocket} trafficViewerApiProp={trafficViewerApiProp}
|
||||
setAnalyzeStatus={setAnalyzeStatus} />
|
||||
setAnalyzeStatus={setAnalyzeStatus} isDemoBannerView={isDemoBannerView} />
|
||||
</RecoilRoot>
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@ export interface InformationIconProps{
|
||||
|
||||
export const InformationIcon: React.FC<InformationIconProps> = ({link,style}) => {
|
||||
return <React.Fragment>
|
||||
|
||||
<a href={DEFUALT_LINK ? DEFUALT_LINK : link} style={style} className={styles.flex}>
|
||||
<a href={DEFUALT_LINK ? DEFUALT_LINK : link} style={style} className={styles.flex} title="documentation">
|
||||
<img className="headerIcon" src={infoImg} alt="Info icon"/>
|
||||
</a>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -10,12 +10,16 @@ const pluralize = (noun: string, amount: number) => {
|
||||
return `${noun}${amount !== 1 ? 's' : ''}`
|
||||
}
|
||||
|
||||
export const StatusBar = () => {
|
||||
interface StatusBarProps {
|
||||
isDemoBannerView: boolean;
|
||||
}
|
||||
|
||||
export const StatusBar = ({isDemoBannerView}) => {
|
||||
const tappingStatus = useRecoilValue(tappingStatusAtom);
|
||||
const [expandedBar, setExpandedBar] = useState(false);
|
||||
const {uniqueNamespaces, amountOfPods, amountOfTappedPods, amountOfUntappedPods} = useRecoilValue(tappingStatusDetails);
|
||||
|
||||
return <div className={`${style.statusBar} ${(expandedBar ? `${style.expandedStatusBar}` : "")}`} onMouseOver={() => setExpandedBar(true)} onMouseLeave={() => setExpandedBar(false)} data-cy="expandedStatusBar">
|
||||
return <div className={`${isDemoBannerView ? `${style.banner}` : ''} ${style.statusBar} ${(expandedBar ? `${style.expandedStatusBar}` : "")}`} onMouseOver={() => setExpandedBar(true)} onMouseLeave={() => setExpandedBar(false)} data-cy="expandedStatusBar">
|
||||
<div className={style.podsCount}>
|
||||
{tappingStatus.some(pod => !pod.isTapped) && <img src={warningIcon} alt="warning"/>}
|
||||
<span className={style.podsCountText} data-cy="podsCountText">
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4ZM2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12Z" fill="#627EF7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 10.1C12.5522 10.1 13 10.5477 13 11.1V14.6H13.8C14.3522 14.6 14.8 15.0477 14.8 15.6C14.8 16.1523 14.3522 16.6 13.8 16.6H10.2C9.64767 16.6 9.19995 16.1523 9.19995 15.6C9.19995 15.0477 9.64767 14.6 10.2 14.6H11V11.1C11 10.5477 11.4477 10.1 12 10.1Z" fill="#627EF7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 11C13 11.5523 12.5523 12 12 12L10 12C9.44772 12 9 11.5523 9 11C9 10.4477 9.44772 10 10 10L12 10C12.5523 10 13 10.4477 13 11Z" fill="#627EF7"/>
|
||||
<circle cx="12" cy="8" r="1" fill="#627EF7"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="#627EF7" d="M12 4.707c-2.938-1.83-7.416-2.567-12-2.707v17.714c3.937.12 7.795.681 10.667 1.995.846.388 1.817.388 2.667 0 2.872-1.314 6.729-1.875 10.666-1.995v-17.714c-4.584.14-9.062.877-12 2.707zm-10 13.104v-13.704c5.157.389 7.527 1.463 9 2.334v13.168c-1.525-.546-4.716-1.505-9-1.798zm20 0c-4.283.293-7.475 1.252-9 1.799v-13.171c1.453-.861 3.83-1.942 9-2.332v13.704z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 954 B After Width: | Height: | Size: 471 B |
@@ -9,4 +9,4 @@ import { InformationIcon } from "./InformationIcon";
|
||||
|
||||
|
||||
export {LoadingOverlay,Select,Tabs,Tooltip,Checkbox,CustomModal,InformationIcon}
|
||||
export {StatusBar}
|
||||
export {StatusBar}
|
||||
@@ -19,6 +19,9 @@
|
||||
overflow: hidden
|
||||
max-width: clamp(150px,50%,600px)
|
||||
|
||||
&.banner
|
||||
top: 53px
|
||||
|
||||
.podsCount
|
||||
display: flex
|
||||
justify-content: center
|
||||
|
||||
43
ui-common/src/hooks/WindowDimensionsHook.tsx
Normal file
43
ui-common/src/hooks/WindowDimensionsHook.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
function getWindowDimensions() {
|
||||
const { innerWidth: width, innerHeight: height } = window;
|
||||
return {
|
||||
width,
|
||||
height
|
||||
};
|
||||
}
|
||||
|
||||
export function useRequestTextByWidth(windowWidth){
|
||||
|
||||
let requestText = "Request: "
|
||||
let responseText = "Response: "
|
||||
let elapsedTimeText = "Elapsed Time: "
|
||||
|
||||
if (windowWidth < 1078) {
|
||||
requestText = ""
|
||||
responseText = ""
|
||||
elapsedTimeText = ""
|
||||
} else if (windowWidth < 1356) {
|
||||
requestText = "Req: "
|
||||
responseText = "Res: "
|
||||
elapsedTimeText = "ET: "
|
||||
}
|
||||
|
||||
return {requestText, responseText, elapsedTimeText}
|
||||
}
|
||||
|
||||
export default function useWindowDimensions() {
|
||||
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
|
||||
|
||||
useEffect(() => {
|
||||
function handleResize() {
|
||||
setWindowDimensions(getWindowDimensions());
|
||||
}
|
||||
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
|
||||
return windowDimensions;
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
"@types/jest": "^26.0.22",
|
||||
"@types/node": "^12.20.10",
|
||||
"@uiw/react-textarea-code-editor": "^1.4.12",
|
||||
"@up9/mizu-common": "1.0.135",
|
||||
"@up9/mizu-common": "1.0.137",
|
||||
"axios": "^0.25.0",
|
||||
"core-js": "^3.20.2",
|
||||
"craco-babel-loader": "^1.0.3",
|
||||
|
||||
@@ -40,10 +40,9 @@ const trafficViewerApi = {...api}
|
||||
{window["isOasEnabled"] && <Button
|
||||
startIcon={<img className="custom" src={services} alt="services"></img>}
|
||||
size="large"
|
||||
type="submit"
|
||||
variant="contained"
|
||||
className={commonClasses.outlinedButton + " " + commonClasses.imagedButton}
|
||||
style={{ marginRight: 25 }}
|
||||
style={{ marginRight: 25, textTransform: 'unset' }}
|
||||
onClick={handleOpenOasModal}>
|
||||
OpenApi Specs
|
||||
</Button>}
|
||||
@@ -52,7 +51,8 @@ const trafficViewerApi = {...api}
|
||||
size="large"
|
||||
variant="contained"
|
||||
className={commonClasses.outlinedButton + " " + commonClasses.imagedButton}
|
||||
onClick={openServiceMapModalDebounce}>
|
||||
onClick={openServiceMapModalDebounce}
|
||||
style={{textTransform: 'unset'}}>
|
||||
Service Map
|
||||
</Button>}
|
||||
</div>
|
||||
@@ -66,7 +66,7 @@ const trafficViewerApi = {...api}
|
||||
return (
|
||||
<>
|
||||
<TrafficViewer setAnalyzeStatus={setAnalyzeStatus} webSocketUrl={getWebsocketUrl()} isCloseWebSocket={!openWebSocket}
|
||||
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!openOasModal}/>
|
||||
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!openOasModal} isDemoBannerView={false}/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user