diff --git a/plugins/kiali-backend/__fixtures__/data/canaries_status.json b/plugins/kiali-backend/__fixtures__/data/canaries_status.json deleted file mode 100644 index cb4493b035..0000000000 --- a/plugins/kiali-backend/__fixtures__/data/canaries_status.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "currentVersion": "", - "upgradeVersion": "", - "migratedNamespaces": [], - "pendingNamespaces": [] -} diff --git a/plugins/kiali-backend/__fixtures__/data/config/auth_info.json b/plugins/kiali-backend/__fixtures__/data/config/auth_info.json new file mode 100644 index 0000000000..7bf224fba5 --- /dev/null +++ b/plugins/kiali-backend/__fixtures__/data/config/auth_info.json @@ -0,0 +1 @@ +{ "strategy": "token", "sessionInfo": {} } diff --git a/plugins/kiali-backend/__fixtures__/data/istio_status.json b/plugins/kiali-backend/__fixtures__/data/istio_status.json deleted file mode 100644 index 03fae2f991..0000000000 --- a/plugins/kiali-backend/__fixtures__/data/istio_status.json +++ /dev/null @@ -1 +0,0 @@ -[{ "name": "istiod-7c64f49766-m2gf9", "status": "Healthy", "is_core": true }] diff --git a/plugins/kiali-backend/__fixtures__/data/namespaces/all.json b/plugins/kiali-backend/__fixtures__/data/namespaces/all.json deleted file mode 100644 index bd2d528ae0..0000000000 --- a/plugins/kiali-backend/__fixtures__/data/namespaces/all.json +++ /dev/null @@ -1,84 +0,0 @@ -[ - { - "name": "default", - "cluster": "Kubernetes", - "labels": { "kubernetes.io/metadata.name": "default" }, - "annotations": {} - }, - { - "name": "hostpath-provisioner", - "cluster": "Kubernetes", - "labels": { - "kubernetes.io/metadata.name": "hostpath-provisioner", - "pod-security.kubernetes.io/audit": "privileged", - "pod-security.kubernetes.io/audit-version": "v1.24", - "pod-security.kubernetes.io/warn": "privileged", - "pod-security.kubernetes.io/warn-version": "v1.24" - }, - "annotations": {} - }, - { - "name": "istio-system", - "cluster": "Kubernetes", - "labels": { - "kubernetes.io/metadata.name": "istio-system", - "pod-security.kubernetes.io/audit": "baseline", - "pod-security.kubernetes.io/audit-version": "v1.24", - "pod-security.kubernetes.io/warn": "baseline", - "pod-security.kubernetes.io/warn-version": "v1.24", - "topology.istio.io/network": "" - }, - "annotations": {} - }, - { - "name": "kiali", - "cluster": "Kubernetes", - "labels": { - "kubernetes.io/metadata.name": "kiali", - "pod-security.kubernetes.io/audit": "restricted", - "pod-security.kubernetes.io/audit-version": "v1.24", - "pod-security.kubernetes.io/warn": "restricted", - "pod-security.kubernetes.io/warn-version": "v1.24" - }, - "annotations": {} - }, - { - "name": "travel-agency", - "cluster": "Kubernetes", - "labels": { - "istio-injection": "enabled", - "kubernetes.io/metadata.name": "travel-agency", - "pod-security.kubernetes.io/audit": "privileged", - "pod-security.kubernetes.io/audit-version": "v1.24", - "pod-security.kubernetes.io/warn": "privileged", - "pod-security.kubernetes.io/warn-version": "v1.24" - }, - "annotations": {} - }, - { - "name": "travel-control", - "cluster": "Kubernetes", - "labels": { - "istio-injection": "enabled", - "kubernetes.io/metadata.name": "travel-control", - "pod-security.kubernetes.io/audit": "privileged", - "pod-security.kubernetes.io/audit-version": "v1.24", - "pod-security.kubernetes.io/warn": "privileged", - "pod-security.kubernetes.io/warn-version": "v1.24" - }, - "annotations": {} - }, - { - "name": "travel-portal", - "cluster": "Kubernetes", - "labels": { - "istio-injection": "enabled", - "kubernetes.io/metadata.name": "travel-portal", - "pod-security.kubernetes.io/audit": "privileged", - "pod-security.kubernetes.io/audit-version": "v1.24", - "pod-security.kubernetes.io/warn": "privileged", - "pod-security.kubernetes.io/warn-version": "v1.24" - }, - "annotations": {} - } -] diff --git a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-agency-metrics.json b/plugins/kiali-backend/__fixtures__/data/namespaces/travel-agency-metrics.json deleted file mode 100644 index acb553a7d4..0000000000 --- a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-agency-metrics.json +++ /dev/null @@ -1,546 +0,0 @@ -{ - "grpc_received": null, - "grpc_sent": null, - "request_count": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "3.0666725927242826"], - [1689676185, "3.0666429650697715"], - [1689676200, "3.0666133404434963"], - [1689676215, "3.066666666666667"], - [1689676230, "3.0444681502553315"], - [1689676245, "3.044488895737518"], - [1689676260, "3.044444444444444"], - [1689676275, "3.0666548153415403"], - [1689676290, "3.0666725927242826"], - [1689676305, "3.066666666666667"], - [1689676320, "3.0666785190452908"], - [1689676335, "3.066666666666667"], - [1689676350, "3.066666666666667"], - [1689676365, "3.066666666666667"], - [1689676380, "3.066660740872425"], - [1689676395, "3.066666666666667"], - [1689676410, "3.066666666666667"], - [1689676425, "3.0666725927242826"], - [1689676440, "3.066666666666667"], - [1689676455, "3.066666666666667"], - [1689676470, "3.066660740872425"], - [1689676485, "3"], - [1689676500, "2.9555555555555557"], - [1689676515, "2.888894814946505"], - [1689676530, "2.9555555555555557"], - [1689676545, "2.9555555555555557"], - [1689676560, "3.066666666666667"], - [1689676575, "3.066666666666667"], - [1689676590, "3.066666666666667"], - [1689676605, "3.066666666666667"], - [1689676620, "3.066666666666667"], - [1689676635, "3.066666666666667"], - [1689676650, "3.066666666666667"], - [1689676665, "3.066660740872425"], - [1689676680, "3.066637040328852"], - [1689676695, "3.066666666666667"], - [1689676710, "3.0666488911273873"], - [1689676725, "3.0666962995888434"], - [1689676740, "3.066666666666667"], - [1689676755, "3.0666903724775536"], - [1689676770, "3.066666666666667"] - ], - "name": "request_count" - } - ], - "request_duration_millis": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "4.46484779723388"], - [1689676185, "4.644595060239843"], - [1689676200, "4.405137955019646"], - [1689676215, "4.680797101449263"], - [1689676230, "4.723522907495173"], - [1689676245, "4.94957320133482"], - [1689676260, "4.880797101449319"], - [1689676275, "4.952189009399399"], - [1689676290, "4.610861999776447"], - [1689676305, "4.572463768115895"], - [1689676320, "4.5452769903061725"], - [1689676335, "5.530434782608651"], - [1689676350, "5.552536231884058"], - [1689676365, "5.670652173912998"], - [1689676380, "4.861963573685952"], - [1689676395, "4.9985507246377185"], - [1689676410, "4.561956521739131"], - [1689676425, "4.421007978583803"], - [1689676440, "4.089130434782626"], - [1689676455, "4.4007246376812565"], - [1689676470, "4.39710811020587"], - [1689676485, "4.486956521739092"], - [1689676500, "4.42463768115934"], - [1689676515, "4.871731906315636"], - [1689676530, "5.045652173912979"], - [1689676545, "5.155797101449249"], - [1689676560, "4.983333333333249"], - [1689676575, "4.725000000000014"], - [1689676590, "4.637681159420319"], - [1689676605, "4.659782608695672"], - [1689676620, "4.739130434782638"], - [1689676635, "4.701449275362287"], - [1689676650, "4.689855072463793"], - [1689676665, "4.792037061727915"], - [1689676680, "4.7859057374212775"], - [1689676695, "4.723913043478268"], - [1689676710, "4.634442781402011"], - [1689676725, "4.630035333697192"], - [1689676740, "4.407971014492705"], - [1689676755, "4.498524711184274"], - [1689676770, "4.4829710144927315"] - ], - "stat": "avg", - "name": "request_duration_millis" - } - ], - "request_error_count": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "0"], - [1689676185, "0"], - [1689676200, "0"], - [1689676215, "0"], - [1689676230, "0"], - [1689676245, "0"], - [1689676260, "0"], - [1689676275, "0"], - [1689676290, "0"], - [1689676305, "0"], - [1689676320, "0"], - [1689676335, "0"], - [1689676350, "0"], - [1689676365, "0"], - [1689676380, "0"], - [1689676395, "0"], - [1689676410, "0"], - [1689676425, "0"], - [1689676440, "0"], - [1689676455, "0"], - [1689676470, "0"], - [1689676485, "0"], - [1689676500, "0"], - [1689676515, "0"], - [1689676530, "0"], - [1689676545, "0"], - [1689676560, "0"], - [1689676575, "0"], - [1689676590, "0"], - [1689676605, "0"], - [1689676620, "0"], - [1689676635, "0"], - [1689676650, "0"], - [1689676665, "0"], - [1689676680, "0"], - [1689676695, "0"], - [1689676710, "0"], - [1689676725, "0"], - [1689676740, "0"], - [1689676755, "0"], - [1689676770, "0"] - ], - "name": "request_error_count" - } - ], - "request_size": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "412.898583771587"], - [1689676185, "412.8984185502497"], - [1689676200, "412.9707473529639"], - [1689676215, "412.97101449275357"], - [1689676230, "413.2609989603021"], - [1689676245, "413.2610993809971"], - [1689676260, "413.40579710144925"], - [1689676275, "413.11589610212275"], - [1689676290, "413.04351102775996"], - [1689676305, "413.0434782608695"], - [1689676320, "413.0435244715244"], - [1689676335, "412.97101449275357"], - [1689676350, "412.7536231884058"], - [1689676365, "412.8260869565217"], - [1689676380, "412.9709815871691"], - [1689676395, "413.1159420289855"], - [1689676410, "413.1159420289855"], - [1689676425, "413.11597465584646"], - [1689676440, "413.1159420289855"], - [1689676455, "413.1159420289855"], - [1689676470, "413.1159094034485"], - [1689676485, "413.18840579710144"], - [1689676500, "413.26086956521743"], - [1689676515, "413.26090191201945"], - [1689676530, "413.2608695652173"], - [1689676545, "413.04347826086956"], - [1689676560, "412.89855072463763"], - [1689676575, "413.04347826086956"], - [1689676590, "413.1159420289855"], - [1689676605, "413.18840579710144"], - [1689676620, "412.97101449275357"], - [1689676635, "412.89855072463763"], - [1689676650, "413.1159420289855"], - [1689676665, "413.1159094034485"], - [1689676680, "413.2607561551727"], - [1689676695, "413.26086956521743"], - [1689676710, "413.18834699442306"], - [1689676725, "413.04359379453956"], - [1689676740, "412.97101449275357"], - [1689676755, "413.1160338938941"], - [1689676770, "413.3333333333333"] - ], - "stat": "avg", - "name": "request_size" - } - ], - "request_throughput": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "1266.224770426997"], - [1689676185, "1266.2120305355572"], - [1689676200, "1266.4216030455198"], - [1689676215, "1266.4444444444443"], - [1689676230, "1267.3435268320147"], - [1689676245, "1267.353632732586"], - [1689676260, "1267.7777777777778"], - [1689676275, "1266.8838520757101"], - [1689676290, "1266.6692148714415"], - [1689676305, "1266.6666666666665"], - [1689676320, "1266.6717039275818"], - [1689676335, "1266.4444444444443"], - [1689676350, "1265.7777777777778"], - [1689676365, "1266"], - [1689676380, "1266.4418963529206"], - [1689676395, "1266.888888888889"], - [1689676410, "1266.888888888889"], - [1689676425, "1266.8914370936636"], - [1689676440, "1266.888888888889"], - [1689676455, "1266.888888888889"], - [1689676470, "1266.886340797365"], - [1689676485, "1267.111111111111"], - [1689676500, "1267.3333333333335"], - [1689676515, "1267.3358815381082"], - [1689676530, "1267.3333333333333"], - [1689676545, "1266.6666666666667"], - [1689676560, "1266.2222222222222"], - [1689676575, "1266.6666666666667"], - [1689676590, "1266.888888888889"], - [1689676605, "1267.111111111111"], - [1689676620, "1266.4444444444443"], - [1689676635, "1266.2222222222222"], - [1689676650, "1266.888888888889"], - [1689676665, "1266.886340797365"], - [1689676680, "1267.3207421397622"], - [1689676695, "1267.3333333333335"], - [1689676710, "1267.1035861372056"], - [1689676725, "1266.6792606585918"], - [1689676740, "1266.4444444444443"], - [1689676755, "1266.8989638585158"], - [1689676770, "1267.5555555555557"] - ], - "name": "request_throughput" - } - ], - "response_size": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "512.8979267534253"], - [1689676185, "513.0459750126561"], - [1689676200, "512.7592356441766"], - [1689676215, "512.6811594202899"], - [1689676230, "512.6786650639601"], - [1689676245, "512.7486330751949"], - [1689676260, "513.0434782608695"], - [1689676275, "513.0447266874194"], - [1689676290, "512.9703903815117"], - [1689676305, "512.9710144927536"], - [1689676320, "512.9697662449425"], - [1689676335, "513.1159420289855"], - [1689676350, "512.9710144927536"], - [1689676365, "512.9710144927536"], - [1689676380, "512.8267107623903"], - [1689676395, "512.8260869565217"], - [1689676410, "512.7536231884058"], - [1689676425, "512.9703903815118"], - [1689676440, "512.8985507246376"], - [1689676455, "512.8260869565217"], - [1689676470, "512.8267107623903"], - [1689676485, "512.7536231884058"], - [1689676500, "512.9710144927536"], - [1689676515, "513.2602448938577"], - [1689676530, "513.695652173913"], - [1689676545, "513.623188405797"], - [1689676560, "513.0434782608695"], - [1689676575, "513.0434782608695"], - [1689676590, "513.0434782608695"], - [1689676605, "513.1159420289855"], - [1689676620, "512.8260869565216"], - [1689676635, "512.6086956521739"], - [1689676650, "513.3333333333334"], - [1689676665, "513.406422027508"], - [1689676680, "513.5538504145313"], - [1689676695, "513.4782608695652"], - [1689676710, "513.6975284450428"], - [1689676725, "513.9099135661105"], - [1689676740, "513.5507246376811"], - [1689676755, "513.6206867674929"], - [1689676770, "513.3333333333333"] - ], - "stat": "avg", - "name": "response_size" - } - ], - "response_throughput": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "1572.8900148398359"], - [1689676185, "1573.3288300299234"], - [1689676200, "1572.4343124620423"], - [1689676215, "1572.2222222222224"], - [1689676230, "1572.2267263262909"], - [1689676245, "1572.4534532281634"], - [1689676260, "1573.3333333333333"], - [1689676275, "1573.3310815815591"], - [1689676290, "1573.112237062058"], - [1689676305, "1573.111111111111"], - [1689676320, "1573.1133630630495"], - [1689676335, "1573.5555555555557"], - [1689676350, "1573.111111111111"], - [1689676365, "1573.111111111111"], - [1689676380, "1572.6655407657606"], - [1689676395, "1572.6666666666667"], - [1689676410, "1572.4444444444446"], - [1689676425, "1573.1122370620583"], - [1689676440, "1572.888888888889"], - [1689676455, "1572.6666666666667"], - [1689676470, "1572.6655407657609"], - [1689676485, "1572.4444444444446"], - [1689676500, "1573.111111111111"], - [1689676515, "1574.001125950947"], - [1689676530, "1575.3333333333333"], - [1689676545, "1575.111111111111"], - [1689676560, "1573.3333333333333"], - [1689676575, "1573.3333333333333"], - [1689676590, "1573.3333333333333"], - [1689676605, "1573.5555555555557"], - [1689676620, "1572.6666666666665"], - [1689676635, "1572"], - [1689676650, "1574.2222222222224"], - [1689676665, "1574.4433185435387"], - [1689676680, "1574.883259884704"], - [1689676695, "1574.6666666666667"], - [1689676710, "1575.3299559808702"], - [1689676725, "1576.0056302552134"], - [1689676740, "1574.888888888889"], - [1689676755, "1575.1156152151796"], - [1689676770, "1574.2222222222222"] - ], - "name": "response_throughput" - } - ], - "tcp_closed": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "1.7333392593909496"], - [1689676185, "1.7333096317364385"], - [1689676200, "1.7332266808869927"], - [1689676215, "1.7333333333333334"], - [1689676230, "1.711134816921998"], - [1689676245, "1.688983717269278"], - [1689676260, "1.6888888888888887"], - [1689676275, "1.7110992597859846"], - [1689676290, "1.7333392593909496"], - [1689676305, "1.7333333333333334"], - [1689676320, "1.7333451857119577"], - [1689676335, "1.7333333333333334"], - [1689676350, "1.7333333333333334"], - [1689676365, "1.7333333333333334"], - [1689676380, "1.7333274075390919"], - [1689676395, "1.7333333333333334"], - [1689676410, "1.7333333333333334"], - [1689676425, "1.7333392593909496"], - [1689676440, "1.7333333333333334"], - [1689676455, "1.7333333333333334"], - [1689676470, "1.7333274075390919"], - [1689676485, "1.7333333333333334"], - [1689676500, "1.7333333333333334"], - [1689676515, "1.7333392593909496"], - [1689676530, "1.7333333333333334"], - [1689676545, "1.7333333333333334"], - [1689676560, "1.7333333333333334"], - [1689676575, "1.7333333333333334"], - [1689676590, "1.7333333333333334"], - [1689676605, "1.7333333333333334"], - [1689676620, "1.7333333333333334"], - [1689676635, "1.7333333333333334"], - [1689676650, "1.7333333333333334"], - [1689676665, "1.7333274075390919"], - [1689676680, "1.7333037069955188"], - [1689676695, "1.7333333333333334"], - [1689676710, "1.7333155577940542"], - [1689676725, "1.73336296625551"], - [1689676740, "1.7333333333333334"], - [1689676755, "1.7333570391442201"], - [1689676770, "1.7333333333333334"] - ], - "name": "tcp_closed" - } - ], - "tcp_opened": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "1.7333392593909496"], - [1689676185, "1.7333096317364385"], - [1689676200, "1.7332266808869927"], - [1689676215, "1.7333333333333334"], - [1689676230, "1.711134816921998"], - [1689676245, "1.688983717269278"], - [1689676260, "1.6888888888888887"], - [1689676275, "1.7110992597859846"], - [1689676290, "1.7333392593909496"], - [1689676305, "1.7333333333333334"], - [1689676320, "1.7333451857119577"], - [1689676335, "1.7333333333333334"], - [1689676350, "1.7333333333333334"], - [1689676365, "1.7333333333333334"], - [1689676380, "1.7333274075390919"], - [1689676395, "1.7333333333333334"], - [1689676410, "1.7333333333333334"], - [1689676425, "1.7333392593909496"], - [1689676440, "1.7333333333333334"], - [1689676455, "1.7333333333333334"], - [1689676470, "1.7333274075390919"], - [1689676485, "1.7333333333333334"], - [1689676500, "1.7333333333333334"], - [1689676515, "1.7333392593909496"], - [1689676530, "1.7333333333333334"], - [1689676545, "1.7333333333333334"], - [1689676560, "1.7333333333333334"], - [1689676575, "1.7333333333333334"], - [1689676590, "1.7333333333333334"], - [1689676605, "1.7333333333333334"], - [1689676620, "1.7333333333333334"], - [1689676635, "1.7333333333333334"], - [1689676650, "1.7333333333333334"], - [1689676665, "1.7333274075390919"], - [1689676680, "1.7333037069955188"], - [1689676695, "1.7333333333333334"], - [1689676710, "1.7333155577940542"], - [1689676725, "1.73336296625551"], - [1689676740, "1.7333333333333334"], - [1689676755, "1.7333570391442201"], - [1689676770, "1.7333333333333334"] - ], - "name": "tcp_opened" - } - ], - "tcp_received": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "325.17898965656025"], - [1689676185, "324.9284922821675"], - [1689676200, "325.0711016308936"], - [1689676215, "325.66666666666663"], - [1689676230, "321.6270996928122"], - [1689676245, "318.7267400510643"], - [1689676260, "318.2"], - [1689676275, "322.06426677332854"], - [1689676290, "325.0678790392873"], - [1689676305, "325.35555555555555"], - [1689676320, "325.5135171439718"], - [1689676335, "325.0222222222222"], - [1689676350, "324.55555555555554"], - [1689676365, "324.7111111111111"], - [1689676380, "324.88767706396646"], - [1689676395, "324.97777777777776"], - [1689676410, "325.1555555555555"], - [1689676425, "325.4901022491858"], - [1689676440, "325.8666666666667"], - [1689676455, "326.06666666666666"], - [1689676470, "326.1543397801036"], - [1689676485, "326.4222222222222"], - [1689676500, "326.4222222222222"], - [1689676515, "326.4678859530212"], - [1689676530, "326.0222222222222"], - [1689676545, "325.08888888888885"], - [1689676560, "324.8666666666667"], - [1689676575, "325.1555555555555"], - [1689676590, "325.7777777777777"], - [1689676605, "325.68888888888887"], - [1689676620, "325.2444444444444"], - [1689676635, "325.6222222222222"], - [1689676650, "325.64444444444445"], - [1689676665, "325.576564965223"], - [1689676680, "325.4828796800355"], - [1689676695, "325.5777777777777"], - [1689676710, "325.55195847935903"], - [1689676725, "325.16155869170643"], - [1689676740, "325.1111111111111"], - [1689676755, "325.6492626505072"], - [1689676770, "326"] - ], - "name": "tcp_received" - } - ], - "tcp_sent": [ - { - "labels": {}, - "datapoints": [ - [1689676170, "957.8461096666346"], - [1689676185, "957.6600065179392"], - [1689676200, "957.4833399991112"], - [1689676215, "957.7111111111111"], - [1689676230, "952.2066613328592"], - [1689676245, "918.998749721949"], - [1689676260, "918.7777777777777"], - [1689676275, "924.2859260576074"], - [1689676290, "957.4905541110791"], - [1689676305, "957.7777777777777"], - [1689676320, "957.8918519835449"], - [1689676335, "957.9111111111112"], - [1689676350, "957.3333333333334"], - [1689676365, "957.4888888888889"], - [1689676380, "957.4872237407069"], - [1689676395, "957.6888888888889"], - [1689676410, "957.5777777777778"], - [1689676425, "957.7572207777456"], - [1689676440, "958"], - [1689676455, "958.1111111111111"], - [1689676470, "958.1983348518181"], - [1689676485, "958.2222222222223"], - [1689676500, "958.4666666666667"], - [1689676515, "958.4238874444123"], - [1689676530, "958.4000000000001"], - [1689676545, "957.8222222222222"], - [1689676560, "957.3555555555555"], - [1689676575, "957.4222222222222"], - [1689676590, "957.8444444444444"], - [1689676605, "957.9555555555555"], - [1689676620, "957.8222222222222"], - [1689676635, "957.5111111111111"], - [1689676650, "958.0222222222222"], - [1689676665, "957.8205570740403"], - [1689676680, "957.9481489711019"], - [1689676695, "957.9111111111112"], - [1689676710, "957.9735176007441"], - [1689676725, "957.8740748972108"], - [1689676740, "957.6"], - [1689676755, "957.7392597860551"], - [1689676770, "958.0444444444445"] - ], - "name": "tcp_sent" - } - ] -} diff --git a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-control-metrics.json b/plugins/kiali-backend/__fixtures__/data/namespaces/travel-control-metrics.json deleted file mode 100644 index 951e5063ef..0000000000 --- a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-control-metrics.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "grpc_received": null, - "grpc_sent": null, - "request_count": null, - "request_duration_millis": null, - "request_error_count": null, - "request_size": null, - "request_throughput": null, - "response_size": null, - "response_throughput": null, - "tcp_closed": null, - "tcp_opened": null, - "tcp_received": null, - "tcp_sent": null -} diff --git a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-portal-metrics.json b/plugins/kiali-backend/__fixtures__/data/namespaces/travel-portal-metrics.json deleted file mode 100644 index a546d9d1c1..0000000000 --- a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-portal-metrics.json +++ /dev/null @@ -1,786 +0,0 @@ -{ - "grpc_received": null, - "grpc_sent": null, - "request_count": [ - { - "labels": {}, - "datapoints": [ - [1689675150, "0.8"], - [1689675165, "0.8001363659944711"], - [1689675180, "0.7999466773312003"], - [1689675195, "0.8"], - [1689675210, "0.8"], - [1689675225, "0.8000533440021338"], - [1689675240, "0.8"], - [1689675255, "0.8"], - [1689675270, "0.8"], - [1689675285, "0.8"], - [1689675300, "0.7999585249701897"], - [1689675315, "0.8"], - [1689675330, "0.8"], - [1689675345, "0.8000414879351603"], - [1689675360, "0.8"], - [1689675375, "0.8"], - [1689675390, "0.8"], - [1689675405, "0.8"], - [1689675420, "0.8"], - [1689675435, "0.8"], - [1689675450, "0.8"], - [1689675465, "0.8"], - [1689675480, "0.8"], - [1689675495, "0.8"], - [1689675510, "0.8"], - [1689675525, "0.8"], - [1689675540, "0.7999111407308674"], - [1689675555, "0.8"], - [1689675570, "0.8"], - [1689675585, "0.777866696306176"], - [1689675600, "0.7555377789628839"], - [1689675615, "0.7555555555555555"], - [1689675630, "0.7777777777777777"], - [1689675645, "0.800005926057616"], - [1689675660, "0.7999822234073284"], - [1689675675, "0.8"], - [1689675690, "0.8000118523786242"], - [1689675705, "0.800017778963042"], - [1689675720, "0.7999170628397092"], - [1689675735, "0.8"], - [1689675750, "0.8"], - [1689675765, "0.8000829887816951"], - [1689675780, "0.8"], - [1689675795, "0.8"], - [1689675810, "0.8"], - [1689675825, "0.8"], - [1689675840, "0.8"], - [1689675855, "0.8"], - [1689675870, "0.8"], - [1689675885, "0.8"], - [1689675900, "0.8"], - [1689675915, "0.7555555555555555"], - [1689675930, "0.7555555555555555"], - [1689675945, "0.7555555555555555"], - [1689675960, "0.8"], - [1689675975, "0.8"], - [1689675990, "0.8"], - [1689676005, "0.8"], - [1689676020, "0.7999466773312003"], - [1689676035, "0.8"], - [1689676050, "0.8"], - [1689676065, "0.8000533440021338"], - [1689676080, "0.8"], - [1689676095, "0.8"], - [1689676110, "0.8"], - [1689676125, "0.8"], - [1689676140, "0.8"], - [1689676155, "0.8"], - [1689676170, "0.7999881486748737"], - [1689676185, "0.8"], - [1689676200, "0.8"], - [1689676215, "0.7999348307450771"], - [1689676230, "0.8"], - [1689676245, "0.8"], - [1689676260, "0.8000770592986122"], - [1689676275, "0.8"], - [1689676290, "0.8"], - [1689676305, "0.8"], - [1689676320, "0.7999881486748737"], - [1689676335, "0.8"], - [1689676350, "0.8"], - [1689676365, "0.8000000010534979"], - [1689676380, "0.8"], - [1689676395, "0.8"], - [1689676410, "0.7999763015631773"], - [1689676425, "0.8"], - [1689676440, "0.8"], - [1689676455, "0.8000355602969285"], - [1689676470, "0.8"], - [1689676485, "0.8"], - [1689676500, "0.7999822234073284"], - [1689676515, "0.8"], - [1689676530, "0.8"], - [1689676545, "0.800017778963042"], - [1689676560, "0.7998696933351102"], - [1689676575, "0.8"], - [1689676590, "0.8"], - [1689676605, "0.777908211915949"], - [1689676620, "0.7555555555555555"], - [1689676635, "0.7555555555555555"], - [1689676650, "0.7777777777777778"], - [1689676665, "0.8"], - [1689676680, "0.8"], - [1689676695, "0.8"], - [1689676710, "0.8"], - [1689676725, "0.8"], - [1689676740, "0.8"], - [1689676755, "0.8"], - [1689676770, "0.8"], - [1689676785, "0.8"], - [1689676800, "0.7995916850857555"], - [1689676815, "0.8"], - [1689676830, "0.7998815341329779"], - [1689676845, "0.800409464546342"], - [1689676860, "0.7999822234073284"], - [1689676875, "0.800118571216837"], - [1689676890, "0.8"], - [1689676905, "0.800017778963042"], - [1689676920, "0.7999822234073284"], - [1689676935, "0.8"], - [1689676950, "0.8"] - ], - "name": "request_count" - } - ], - "request_duration_millis": [ - { - "labels": {}, - "datapoints": [ - [1689675150, "9.320833333333413"], - [1689675165, "8.669435449609951"], - [1689675180, "9.194463793716393"], - [1689675195, "8.629166666666604"], - [1689675210, "13.779166666666542"], - [1689675225, "13.834451537982922"], - [1689675240, "14.20833333333333"], - [1689675255, "8.684722222222463"], - [1689675270, "8.199999999999918"], - [1689675285, "8.447222222222383"], - [1689675300, "8.740275545498825"], - [1689675315, "8.947222222222283"], - [1689675330, "9.005555555555475"], - [1689675345, "8.452812205216324"], - [1689675360, "8.866666666666786"], - [1689675375, "8.437499999999899"], - [1689675390, "8.409722222222323"], - [1689675405, "7.6097222222220395"], - [1689675420, "8.011111111111152"], - [1689675435, "8.437499999999998"], - [1689675450, "8.493055555555555"], - [1689675465, "11.919444444444402"], - [1689675480, "11.752777777777839"], - [1689675495, "11.709722222222302"], - [1689675510, "7.770833333333534"], - [1689675525, "7.952777777777757"], - [1689675540, "7.884746908094457"], - [1689675555, "7.88472222222208"], - [1689675570, "7.347222222222221"], - [1689675585, "7.776316496258347"], - [1689675600, "8.813897808245539"], - [1689675615, "9.252777777777737"], - [1689675630, "8.98750000000008"], - [1689675645, "14.248569947949767"], - [1689675660, "19.13037198346732"], - [1689675675, "19.65833333333325"], - [1689675690, "14.341764385611507"], - [1689675705, "9.722279786509029"], - [1689675720, "11.983216129781866"], - [1689675735, "17.348529411764662"], - [1689675750, "17.070588235294164"], - [1689675765, "14.342929919640607"], - [1689675780, "9.055555555555554"], - [1689675795, "8.740277777777816"], - [1689675810, "9.129166666666706"], - [1689675825, "8.147222222222403"], - [1689675840, "9.737499999999878"], - [1689675855, "9.391666666666524"], - [1689675870, "10.598611111110886"], - [1689675885, "10.37638888888907"], - [1689675900, "10.722222222222321"], - [1689675915, "11.593055555555715"], - [1689675930, "10.76249999999992"], - [1689675945, "10.12638888888897"], - [1689675960, "7.995833333333393"], - [1689675975, "8.134722222222281"], - [1689675990, "8.05138888888895"], - [1689676005, "12.030555555555413"], - [1689676020, "11.282941996622592"], - [1689676035, "11.780555555555514"], - [1689676050, "8.03611111111109"], - [1689676065, "8.298585366937914"], - [1689676080, "9.230555555555535"], - [1689676095, "9.588888888888807"], - [1689676110, "9.712499999999839"], - [1689676125, "8.474999999999856"], - [1689676140, "8.243055555555555"], - [1689676155, "8.369444444444424"], - [1689676170, "8.06666086436949"], - [1689676185, "7.980555555555535"], - [1689676200, "7.952777777777857"], - [1689676215, "8.866670400626091"], - [1689676230, "9.033333333333452"], - [1689676245, "9.376388888888968"], - [1689676260, "8.684775462928702"], - [1689676275, "9.098611111110987"], - [1689676290, "8.712499999999736"], - [1689676305, "9.027777777777878"], - [1689676320, "9.388879465299995"], - [1689676335, "9.997222222222463"], - [1689676350, "10.024999999999837"], - [1689676365, "9.305587963117535"], - [1689676380, "8.57361111111115"], - [1689676395, "8.480555555555535"], - [1689676410, "7.968030042773679"], - [1689676425, "7.816666666666707"], - [1689676440, "7.702777777777758"], - [1689676455, "8.03611469167648"], - [1689676470, "8.255555555555373"], - [1689676485, "8.573611111111253"], - [1689676500, "8.187477500999957"], - [1689676515, "9.141666666666827"], - [1689676530, "9.543055555555434"], - [1689676545, "10.052791142569136"], - [1689676560, "8.962420581440064"], - [1689676575, "8.1875000000001"], - [1689676590, "8.063888888888867"], - [1689676605, "8.106893049092605"], - [1689676620, "8.190277777777736"], - [1689676635, "8.755555555555574"], - [1689676650, "8.904166666666544"], - [1689676665, "9.330555555555694"], - [1689676680, "8.626388888888968"], - [1689676695, "9.151388888888807"], - [1689676710, "8.243055555555454"], - [1689676725, "8.727777777777797"], - [1689676740, "7.983333333333473"], - [1689676755, "8.631944444444342"], - [1689676770, "8.264285714285714"], - [1689676785, "8.038235294117625"], - [1689676800, "7.861692213768087"], - [1689676815, "9.64571428571435"], - [1689676830, "10.48187080371254"], - [1689676845, "9.916995605460045"], - [1689676860, "7.909721327200171"], - [1689676875, "7.344491577751271"], - [1689676890, "8.93472222222226"], - [1689676905, "9.694420492762742"], - [1689676920, "10.497259473653065"], - [1689676935, "9.555555555555554"], - [1689676950, "9.530555555555413"] - ], - "stat": "avg", - "name": "request_duration_millis" - } - ], - "request_error_count": null, - "request_size": [ - { - "labels": {}, - "datapoints": [ - [1689675150, "179.7222222222222"], - [1689675165, "179.7215594449467"], - [1689675180, "178.88914811358484"], - [1689675195, "178.61111111111106"], - [1689675210, "179.16666666666663"], - [1689675225, "179.16644441481088"], - [1689675240, "179.16666666666663"], - [1689675255, "178.88888888888886"], - [1689675270, "179.44444444444443"], - [1689675285, "179.16666666666663"], - [1689675300, "179.1668826936466"], - [1689675315, "178.88888888888886"], - [1689675330, "179.16666666666663"], - [1689675345, "178.88868722188468"], - [1689675360, "179.44444444444443"], - [1689675375, "179.44444444444443"], - [1689675390, "180.27777777777777"], - [1689675405, "180"], - [1689675420, "179.7222222222222"], - [1689675435, "179.16666666666663"], - [1689675450, "179.44444444444443"], - [1689675465, "179.44444444444443"], - [1689675480, "179.44444444444443"], - [1689675495, "178.88888888888886"], - [1689675510, "179.44444444444443"], - [1689675525, "179.16666666666663"], - [1689675540, "178.8893208916537"], - [1689675555, "178.6111111111111"], - [1689675570, "178.6111111111111"], - [1689675585, "178.88845669408016"], - [1689675600, "179.1667592551442"], - [1689675615, "179.16666666666663"], - [1689675630, "179.16666666666663"], - [1689675645, "179.16663580201188"], - [1689675660, "179.722179014266"], - [1689675675, "179.7222222222222"], - [1689675690, "179.4443785988721"], - [1689675705, "179.16670370534985"], - [1689675720, "179.5718272200858"], - [1689675735, "179.70588235294116"], - [1689675750, "179.41176470588235"], - [1689675765, "178.71397834985947"], - [1689675780, "178.88888888888889"], - [1689675795, "179.16666666666663"], - [1689675810, "179.16666666666663"], - [1689675825, "178.88888888888886"], - [1689675840, "179.7222222222222"], - [1689675855, "179.7222222222222"], - [1689675870, "179.44444444444443"], - [1689675885, "178.33333333333331"], - [1689675900, "178.6111111111111"], - [1689675915, "178.6111111111111"], - [1689675930, "179.16666666666663"], - [1689675945, "179.44444444444443"], - [1689675960, "180"], - [1689675975, "180"], - [1689675990, "179.7222222222222"], - [1689676005, "179.16666666666663"], - [1689676020, "178.61135181975737"], - [1689676035, "178.33333333333331"], - [1689676050, "178.88888888888886"], - [1689676065, "179.16638885184688"], - [1689676080, "179.16666666666663"], - [1689676095, "178.6111111111111"], - [1689676110, "178.88888888888886"], - [1689676125, "179.16666666666663"], - [1689676140, "179.44444444444443"], - [1689676155, "178.88888888888886"], - [1689676170, "178.61116460746842"], - [1689676185, "178.33333333333331"], - [1689676200, "178.61111111111106"], - [1689676215, "179.1669382273506"], - [1689676230, "179.7222222222222"], - [1689676245, "179.7222222222222"], - [1689676260, "179.72184766448845"], - [1689676275, "179.16666666666663"], - [1689676290, "179.16666666666663"], - [1689676305, "179.16666666666663"], - [1689676320, "179.44449794080177"], - [1689676335, "179.16666666666663"], - [1689676350, "178.88888888888889"], - [1689676365, "178.88880246785544"], - [1689676380, "179.44444444444443"], - [1689676395, "179.7222222222222"], - [1689676410, "179.72238681932737"], - [1689676425, "179.16666666666663"], - [1689676440, "179.16666666666663"], - [1689676455, "179.16648146501907"], - [1689676470, "179.16666666666663"], - [1689676485, "179.44444444444443"], - [1689676500, "179.44454320548715"], - [1689676515, "179.7222222222222"], - [1689676530, "179.44444444444443"], - [1689676545, "179.16659258930022"], - [1689676560, "179.16720969955472"], - [1689676575, "179.16666666666663"], - [1689676590, "179.44444444444443"], - [1689676605, "179.44385577521564"], - [1689676620, "178.88888888888886"], - [1689676635, "179.16666666666663"], - [1689676650, "178.88888888888886"], - [1689676665, "178.88888888888886"], - [1689676680, "178.88888888888886"], - [1689676695, "179.16666666666663"], - [1689676710, "179.7222222222222"], - [1689676725, "179.16666666666663"], - [1689676740, "179.16666666666663"], - [1689676755, "179.44444444444443"], - [1689676770, "179.85714285714283"], - [1689676785, "180"], - [1689676800, "179.11930521401027"], - [1689676815, "179.00000000000003"], - [1689676830, "179.44497926540285"], - [1689676845, "180.27567073097228"], - [1689676860, "180.00009258847757"], - [1689676875, "179.1660491997629"], - [1689676890, "178.33333333333331"], - [1689676905, "178.3332592559669"], - [1689676920, "178.6111913544583"], - [1689676935, "179.44444444444443"], - [1689676950, "179.44444444444443"] - ], - "stat": "avg", - "name": "request_size" - } - ], - "request_throughput": [ - { - "labels": {}, - "datapoints": [ - [1689675150, "143.77777777777777"], - [1689675165, "143.80175546513897"], - [1689675180, "143.10177964407114"], - [1689675195, "142.88888888888886"], - [1689675210, "143.33333333333331"], - [1689675225, "143.34271298704186"], - [1689675240, "143.33333333333331"], - [1689675255, "143.1111111111111"], - [1689675270, "143.55555555555554"], - [1689675285, "143.33333333333331"], - [1689675300, "143.32607520311655"], - [1689675315, "143.1111111111111"], - [1689675330, "143.33333333333331"], - [1689675345, "143.11837149976412"], - [1689675360, "143.55555555555554"], - [1689675375, "143.55555555555554"], - [1689675390, "144.22222222222223"], - [1689675405, "144"], - [1689675420, "143.77777777777777"], - [1689675435, "143.33333333333331"], - [1689675450, "143.55555555555554"], - [1689675465, "143.55555555555554"], - [1689675480, "143.55555555555554"], - [1689675495, "143.1111111111111"], - [1689675510, "143.55555555555554"], - [1689675525, "143.33333333333331"], - [1689675540, "143.0955607390129"], - [1689675555, "142.88888888888889"], - [1689675570, "142.88888888888889"], - [1689675585, "143.12667185358083"], - [1689675600, "143.3302224296158"], - [1689675615, "143.33333333333331"], - [1689675630, "143.33333333333331"], - [1689675645, "143.33437039341612"], - [1689675660, "143.77454836344242"], - [1689675675, "143.77777777777777"], - [1689675690, "143.5576297218148"], - [1689675705, "143.33654836248343"], - [1689675720, "139.65208354931553"], - [1689675735, "135.77777777777777"], - [1689675750, "135.55555555555554"], - [1689675765, "139.01459219411473"], - [1689675780, "143.11111111111111"], - [1689675795, "143.33333333333331"], - [1689675810, "143.33333333333331"], - [1689675825, "143.1111111111111"], - [1689675840, "143.77777777777777"], - [1689675855, "143.77777777777777"], - [1689675870, "143.55555555555554"], - [1689675885, "142.66666666666666"], - [1689675900, "142.88888888888889"], - [1689675915, "142.88888888888889"], - [1689675930, "143.33333333333331"], - [1689675945, "143.55555555555554"], - [1689675960, "144"], - [1689675975, "144"], - [1689675990, "143.77777777777777"], - [1689676005, "143.33333333333331"], - [1689676020, "142.87955742184894"], - [1689676035, "142.66666666666666"], - [1689676050, "143.1111111111111"], - [1689676065, "143.34266853370673"], - [1689676080, "143.33333333333331"], - [1689676095, "142.88888888888889"], - [1689676110, "143.1111111111111"], - [1689676125, "143.33333333333331"], - [1689676140, "143.55555555555554"], - [1689676155, "143.1111111111111"], - [1689676170, "142.8868149069918"], - [1689676185, "142.66666666666666"], - [1689676200, "142.88888888888886"], - [1689676215, "143.32187440600939"], - [1689676230, "143.77777777777777"], - [1689676245, "143.77777777777777"], - [1689676260, "143.79132737111706"], - [1689676275, "143.33333333333331"], - [1689676290, "143.33333333333331"], - [1689676305, "143.33333333333331"], - [1689676320, "143.5534716975542"], - [1689676335, "143.33333333333331"], - [1689676350, "143.11111111111111"], - [1689676365, "143.11104216274333"], - [1689676380, "143.55555555555554"], - [1689676395, "143.77777777777777"], - [1689676410, "143.77365031583224"], - [1689676425, "143.33333333333331"], - [1689676440, "143.33333333333331"], - [1689676455, "143.3395563852958"], - [1689676470, "143.33333333333331"], - [1689676485, "143.55555555555554"], - [1689676500, "143.55244465183802"], - [1689676515, "143.77777777777777"], - [1689676530, "143.55555555555554"], - [1689676545, "143.3364594676682"], - [1689676560, "143.3104210780902"], - [1689676575, "143.33333333333331"], - [1689676590, "143.55555555555554"], - [1689676605, "143.57849022485067"], - [1689676620, "143.1111111111111"], - [1689676635, "143.33333333333331"], - [1689676650, "143.1111111111111"], - [1689676665, "143.1111111111111"], - [1689676680, "143.1111111111111"], - [1689676695, "143.33333333333331"], - [1689676710, "143.77777777777777"], - [1689676725, "143.33333333333331"], - [1689676740, "143.33333333333331"], - [1689676755, "143.55555555555554"], - [1689676770, "139.88888888888886"], - [1689676785, "136"], - [1689676800, "135.26144907794867"], - [1689676815, "139.22222222222223"], - [1689676830, "143.53472530727083"], - [1689676845, "144.29435308051018"], - [1689676860, "143.99687428245525"], - [1689676875, "143.35408329627984"], - [1689676890, "142.66666666666666"], - [1689676905, "142.669777985199"], - [1689676920, "142.88577798517133"], - [1689676935, "143.55555555555554"], - [1689676950, "143.55555555555554"] - ], - "name": "request_throughput" - } - ], - "response_size": [ - { - "labels": {}, - "datapoints": [ - [1689675150, "1535.2777777777776"], - [1689675165, "1534.1668086903687"], - [1689675180, "1532.7777407456786"], - [1689675195, "1532.2222222222222"], - [1689675210, "1534.1666666666665"], - [1689675225, "1534.444648175312"], - [1689675240, "1536.9444444444446"], - [1689675255, "1541.111111111111"], - [1689675270, "1542.222222222222"], - [1689675285, "1540"], - [1689675300, "1536.111082307514"], - [1689675315, "1534.4444444444441"], - [1689675330, "1535.2777777777776"], - [1689675345, "1533.3333765476914"], - [1689675360, "1533.8888888888885"], - [1689675375, "1533.0555555555554"], - [1689675390, "1534.4444444444446"], - [1689675405, "1534.7222222222222"], - [1689675420, "1535"], - [1689675435, "1534.1666666666665"], - [1689675450, "1534.1666666666665"], - [1689675465, "1533.333333333333"], - [1689675480, "1534.1666666666665"], - [1689675495, "1533.611111111111"], - [1689675510, "1533.8888888888887"], - [1689675525, "1532.5"], - [1689675540, "1532.5"], - [1689675555, "1533.6111111111109"], - [1689675570, "1533.611111111111"], - [1689675585, "1535.5555864266132"], - [1689675600, "1535.277820985734"], - [1689675615, "1535.5555555555554"], - [1689675630, "1535.2777777777776"], - [1689675645, "1535.5555390944062"], - [1689675660, "1536.9444135816184"], - [1689675675, "1535.2777777777776"], - [1689675690, "1535.5555226327695"], - [1689675705, "1534.1666666666663"], - [1689675720, "1562.7173301712282"], - [1689675735, "1534.8529411764705"], - [1689675750, "1533.0882352941176"], - [1689675765, "1508.0027027747894"], - [1689675780, "1533.3333333333333"], - [1689675795, "1532.7777777777776"], - [1689675810, "1533.8888888888887"], - [1689675825, "1534.1666666666665"], - [1689675840, "1535.833333333333"], - [1689675855, "1535.5555555555554"], - [1689675870, "1535"], - [1689675885, "1532.5"], - [1689675900, "1532.2222222222222"], - [1689675915, "1531.6666666666665"], - [1689675930, "1533.0555555555554"], - [1689675945, "1531.9444444444446"], - [1689675960, "1533.611111111111"], - [1689675975, "1534.1666666666665"], - [1689675990, "1535.5555555555554"], - [1689676005, "1545.5555555555554"], - [1689676020, "1545.2777407456783"], - [1689676035, "1544.4444444444441"], - [1689676050, "1533.3333333333333"], - [1689676065, "1532.2221296172825"], - [1689676080, "1532.7777777777776"], - [1689676095, "1533.8888888888887"], - [1689676110, "1535"], - [1689676125, "1535.2777777777776"], - [1689676140, "1535"], - [1689676155, "1534.4444444444446"], - [1689676170, "1533.6111275715289"], - [1689676185, "1532.5"], - [1689676200, "1533.333333333333"], - [1689676215, "1533.3333333333333"], - [1689676230, "1534.4444444444441"], - [1689676245, "1533.8888888888887"], - [1689676260, "1534.9999197376285"], - [1689676275, "1533.8888888888887"], - [1689676290, "1533.8888888888887"], - [1689676305, "1533.333333333333"], - [1689676320, "1534.1666543213537"], - [1689676335, "1533.8888888888887"], - [1689676350, "1533.0555555555554"], - [1689676365, "1532.5"], - [1689676380, "1532.2222222222222"], - [1689676395, "1532.5"], - [1689676410, "1533.055448567108"], - [1689676425, "1533.8888888888887"], - [1689676440, "1533.8888888888887"], - [1689676455, "1534.72212344801"], - [1689676470, "1534.4444444444446"], - [1689676485, "1535"], - [1689676500, "1534.1667037020575"], - [1689676515, "1534.7222222222222"], - [1689676530, "1535.2777777777776"], - [1689676545, "1534.7222469146777"], - [1689676560, "1533.6111563638517"], - [1689676575, "1532.7777777777776"], - [1689676590, "1533.3333333333333"], - [1689676605, "1533.0554649910587"], - [1689676620, "1531.9444444444441"], - [1689676635, "1533.333333333333"], - [1689676650, "1534.1666666666665"], - [1689676665, "1535.5555555555554"], - [1689676680, "1534.7222222222222"], - [1689676695, "1535.833333333333"], - [1689676710, "1535.833333333333"], - [1689676725, "1534.4444444444441"], - [1689676740, "1533.333333333333"], - [1689676755, "1533.611111111111"], - [1689676770, "1562.4285714285716"], - [1689676785, "1534.8529411764707"], - [1689676800, "1531.6154460678363"], - [1689676815, "1508.2857142857144"], - [1689676830, "1534.4441153238547"], - [1689676845, "1535.2776726958782"], - [1689676860, "1534.1667037020575"], - [1689676875, "1534.1662961865245"], - [1689676890, "1533.0555555555554"], - [1689676905, "1532.7777716046637"], - [1689676920, "1534.1666481489713"], - [1689676935, "1534.7222222222222"], - [1689676950, "1535.2777777777776"] - ], - "stat": "avg", - "name": "response_size" - } - ], - "response_throughput": [ - { - "labels": {}, - "datapoints": [ - [1689675150, "1228.2222222222222"], - [1689675165, "1227.5426551348467"], - [1689675180, "1226.1404607967295"], - [1689675195, "1225.7777777777778"], - [1689675210, "1227.3333333333333"], - [1689675225, "1227.6375719588361"], - [1689675240, "1229.5555555555557"], - [1689675255, "1232.888888888889"], - [1689675270, "1233.7777777777776"], - [1689675285, "1232"], - [1689675300, "1228.8251555930806"], - [1689675315, "1227.5555555555554"], - [1689675330, "1228.2222222222222"], - [1689675345, "1226.7303160738584"], - [1689675360, "1227.1111111111109"], - [1689675375, "1226.4444444444443"], - [1689675390, "1227.5555555555557"], - [1689675405, "1227.7777777777778"], - [1689675420, "1228"], - [1689675435, "1227.3333333333333"], - [1689675450, "1227.3333333333333"], - [1689675465, "1226.6666666666665"], - [1689675480, "1227.3333333333333"], - [1689675495, "1226.888888888889"], - [1689675510, "1227.111111111111"], - [1689675525, "1226"], - [1689675540, "1225.8638231700543"], - [1689675555, "1226.8888888888887"], - [1689675570, "1226.888888888889"], - [1689675585, "1228.5810084843095"], - [1689675600, "1228.1949647801257"], - [1689675615, "1228.4444444444443"], - [1689675630, "1228.2222222222222"], - [1689675645, "1228.4535310661222"], - [1689675660, "1229.5282092304956"], - [1689675675, "1228.2222222222222"], - [1689675690, "1228.4626180916682"], - [1689675705, "1227.3606092258"], - [1689675720, "1215.3172050176981"], - [1689675735, "1159.6666666666665"], - [1689675750, "1158.3333333333333"], - [1689675765, "1173.0161383541547"], - [1689675780, "1226.6666666666667"], - [1689675795, "1226.2222222222222"], - [1689675810, "1227.111111111111"], - [1689675825, "1227.3333333333333"], - [1689675840, "1228.6666666666665"], - [1689675855, "1228.4444444444443"], - [1689675870, "1228"], - [1689675885, "1226"], - [1689675900, "1225.7777777777778"], - [1689675915, "1225.3333333333333"], - [1689675930, "1226.4444444444443"], - [1689675945, "1225.5555555555557"], - [1689675960, "1226.888888888889"], - [1689675975, "1227.3333333333333"], - [1689675990, "1228.4444444444443"], - [1689676005, "1236.4444444444443"], - [1689676020, "1236.1397942633694"], - [1689676035, "1235.5555555555554"], - [1689676050, "1226.6666666666667"], - [1689676065, "1225.8594385543777"], - [1689676080, "1226.2222222222222"], - [1689676095, "1227.111111111111"], - [1689676110, "1228"], - [1689676125, "1228.2222222222222"], - [1689676140, "1228"], - [1689676155, "1227.5555555555557"], - [1689676170, "1226.8707267331329"], - [1689676185, "1226"], - [1689676200, "1226.6666666666665"], - [1689676215, "1226.5667404757849"], - [1689676230, "1227.5555555555554"], - [1689676245, "1227.111111111111"], - [1689676260, "1228.1182218072875"], - [1689676275, "1227.111111111111"], - [1689676290, "1227.111111111111"], - [1689676305, "1226.6666666666665"], - [1689676320, "1227.3151415492646"], - [1689676335, "1227.111111111111"], - [1689676350, "1226.4444444444443"], - [1689676365, "1226.0000016144854"], - [1689676380, "1225.7777777777778"], - [1689676395, "1226"], - [1689676410, "1226.408027835993"], - [1689676425, "1227.111111111111"], - [1689676440, "1227.111111111111"], - [1689676455, "1227.8322739328205"], - [1689676470, "1227.5555555555557"], - [1689676485, "1228"], - [1689676500, "1227.306090705064"], - [1689676515, "1227.7777777777778"], - [1689676530, "1228.2222222222222"], - [1689676545, "1227.80508330185"], - [1689676560, "1226.6890853360578"], - [1689676575, "1226.2222222222222"], - [1689676590, "1226.6666666666667"], - [1689676605, "1226.6443347611917"], - [1689676620, "1225.5555555555554"], - [1689676635, "1226.6666666666665"], - [1689676650, "1227.3333333333333"], - [1689676665, "1228.4444444444443"], - [1689676680, "1227.7777777777778"], - [1689676695, "1228.6666666666665"], - [1689676710, "1228.6666666666665"], - [1689676725, "1227.5555555555554"], - [1689676740, "1226.6666666666665"], - [1689676755, "1226.888888888889"], - [1689676770, "1215.2222222222222"], - [1689676785, "1159.6666666666667"], - [1689676800, "1156.5951778217375"], - [1689676815, "1173.111111111111"], - [1689676830, "1227.373513006565"], - [1689676845, "1228.850779932462"], - [1689676860, "1227.306090705064"], - [1689676875, "1227.514944913789"], - [1689676890, "1226.4444444444443"], - [1689676905, "1226.249468483084"], - [1689676920, "1227.3060462635824"], - [1689676935, "1227.7777777777778"], - [1689676950, "1228.2222222222222"] - ], - "name": "response_throughput" - } - ], - "tcp_closed": null, - "tcp_opened": null, - "tcp_received": null, - "tcp_sent": null -} diff --git a/plugins/kiali-backend/__fixtures__/data/namespaces/validations.json b/plugins/kiali-backend/__fixtures__/data/namespaces/validations.json deleted file mode 100644 index 6a2b4f7a43..0000000000 --- a/plugins/kiali-backend/__fixtures__/data/namespaces/validations.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "Kubernetes": { - "travel-agency": { "errors": 0, "objectCount": 0, "warnings": 0 }, - "travel-control": { "errors": 0, "objectCount": 0, "warnings": 0 }, - "travel-portal": { "errors": 0, "objectCount": 0, "warnings": 0 } - } -} diff --git a/plugins/kiali-backend/__fixtures__/handlers.ts b/plugins/kiali-backend/__fixtures__/handlers.ts index 289903fea5..9231283f72 100644 --- a/plugins/kiali-backend/__fixtures__/handlers.ts +++ b/plugins/kiali-backend/__fixtures__/handlers.ts @@ -3,157 +3,10 @@ import { rest } from 'msw'; const LOCAL_ADDR = 'https://localhost:4000'; export const handlers = [ - rest.get(`${LOCAL_ADDR}/api/config`, (_, res, ctx) => { + rest.post(`${LOCAL_ADDR}/api/auth/info`, (_, res, ctx) => { return res( ctx.status(200), - ctx.json(require(`${__dirname}/data/config/anonymous_config.json`)), + ctx.json(require(`${__dirname}/data/config/auth_info.json`)), ); }), - rest.get(`${LOCAL_ADDR}/api/istio/certs`, (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json(require(`${__dirname}/data/config/istio_certs.json`)), - ); - }), - rest.get(`${LOCAL_ADDR}/api/status`, (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json(require(`${__dirname}/data/config/status.json`)), - ); - }), - rest.get(`${LOCAL_ADDR}/api/mesh/tls`, (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json(require(`${__dirname}/data/config/mesh_tls.json`)), - ); - }), - rest.get(`${LOCAL_ADDR}/api/namespaces`, (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json(require(`${__dirname}/data/namespaces/all.json`)), - ); - }), - rest.get(`${LOCAL_ADDR}/api/mesh/canaries/status`, (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json(require(`${__dirname}/data/canaries_status.json`)), - ); - }), - rest.get(`${LOCAL_ADDR}/api/istio/status`, (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json(require(`${__dirname}/data/istio_status.json`)), - ); - }), - rest.get( - `${LOCAL_ADDR}/api/mesh/outbound_traffic_policy/mode`, - (_, res, ctx) => { - return res(ctx.status(200), ctx.json({ mode: 'ALLOW_ANY' })); - }, - ), - rest.get(`${LOCAL_ADDR}/api/mesh/resources/thresholds`, (_, res, ctx) => { - return res(ctx.status(200), ctx.json({ memory: 0, cpu: 0 })); - }), - rest.get(`${LOCAL_ADDR}/api/istio/validations`, (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json(require(`${__dirname}/data/namespaces/validations.json`)), - ); - }), - rest.get(`${LOCAL_ADDR}/api/namespaces/travel-portal/tls`, (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - status: 'MTLS_NOT_ENABLED', - autoMTLSEnabled: true, - minTLS: '', - }), - ); - }), - rest.get(`${LOCAL_ADDR}/api/namespaces/travel-control/tls`, (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - status: 'MTLS_NOT_ENABLED', - autoMTLSEnabled: true, - minTLS: '', - }), - ); - }), - rest.get(`${LOCAL_ADDR}/api/namespaces/travel-agency/tls`, (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json({ - status: 'MTLS_NOT_ENABLED', - autoMTLSEnabled: true, - minTLS: '', - }), - ); - }), - rest.get( - `${LOCAL_ADDR}/api/namespaces/travel-agency/metrics`, - (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json( - require(`${__dirname}/data/namespaces/travel-agency-metrics.json`), - ), - ); - }, - ), - rest.get( - `${LOCAL_ADDR}/api/namespaces/travel-portal/metrics`, - (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json( - require(`${__dirname}/data/namespaces/travel-portal-metrics.json`), - ), - ); - }, - ), - rest.get( - `${LOCAL_ADDR}/api/namespaces/travel-control/metrics`, - (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json( - require(`${__dirname}/data/namespaces/travel-control-metrics.json`), - ), - ); - }, - ), - rest.get( - `${LOCAL_ADDR}/api/namespaces/travel-agency/health`, - (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json( - require(`${__dirname}/data/namespaces/travel-agency-health.json`), - ), - ); - }, - ), - rest.get( - `${LOCAL_ADDR}/api/namespaces/travel-portal/health`, - (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json( - require(`${__dirname}/data/namespaces/travel-portal-health.json`), - ), - ); - }, - ), - rest.get( - `${LOCAL_ADDR}/api/namespaces/travel-control/health`, - (_, res, ctx) => { - return res( - ctx.status(200), - ctx.json( - require(`${__dirname}/data/namespaces/travel-control-health.json`), - ), - ); - }, - ), ]; diff --git a/plugins/kiali-backend/config.d.ts b/plugins/kiali-backend/config.d.ts index 59872dc852..88f3fc1bff 100644 --- a/plugins/kiali-backend/config.d.ts +++ b/plugins/kiali-backend/config.d.ts @@ -6,15 +6,6 @@ export interface Config { * Url of the hub cluster API endpoint */ url: string; - /** - * Strategy used to auth with Kiali - * - anonymous - * - token - * - * More info in https://kiali.io/docs/configuration/authentication/ - * - */ - strategy: string; /** * Service Account Token which is used for querying data from Kiali * @visibility secret diff --git a/plugins/kiali-backend/dist-dynamic/package.json b/plugins/kiali-backend/dist-dynamic/package.json index 67fa1889dd..fba3ea1888 100644 --- a/plugins/kiali-backend/dist-dynamic/package.json +++ b/plugins/kiali-backend/dist-dynamic/package.json @@ -30,8 +30,7 @@ "express-promise-router": "^4.1.1", "moment": "^2.29.4", "winston": "^3.11.0", - "yn": "^4.0.0", - "deep-freeze": "^0.0.1" + "yn": "^4.0.0" }, "devDependencies": {}, "files": [ diff --git a/plugins/kiali-backend/src/clients/auth.ts b/plugins/kiali-backend/src/clients/Auth.ts similarity index 51% rename from plugins/kiali-backend/src/clients/auth.ts rename to plugins/kiali-backend/src/clients/Auth.ts index 9485a8181c..d6837fbe9d 100644 --- a/plugins/kiali-backend/src/clients/auth.ts +++ b/plugins/kiali-backend/src/clients/Auth.ts @@ -1,39 +1,65 @@ import moment from 'moment'; -import { config, KialiDetails } from '@janus-idp/backstage-plugin-kiali-common'; - -export type Session = { - expiresOn: string; - username: string; -}; +import { KialiDetails } from '../service/config'; export const MILLISECONDS = 1000; export const AUTH_KIALI_TOKEN = 'kiali-token-aes'; + +const timeOutforWarningUser = 60 * MILLISECONDS; + +export enum AuthStrategy { + anonymous = 'anonymous', + openshift = 'openshift', + token = 'token', + openid = 'openid', + header = 'header', +} + +export interface SessionInfo { + username?: string; + expiresOn?: string; +} + +export interface AuthConfig { + authorizationEndpoint?: string; + logoutEndpoint?: string; + logoutRedirect?: string; + strategy?: AuthStrategy; +} + +export type AuthInfo = { + sessionInfo: SessionInfo; +} & AuthConfig; + export class KialiAuthentication { - protected session: Session; protected cookie: string; - private KialiDetails: KialiDetails; + protected auth: AuthInfo; private readonly sessionSeconds: number; constructor(KD: KialiDetails) { - this.KialiDetails = KD; this.sessionSeconds = KD.sessionTime ? KD.sessionTime * MILLISECONDS - : config.session.timeOutforWarningUser; - this.session = { expiresOn: '', username: 'anonymous' }; + : timeOutforWarningUser; + this.auth = { + sessionInfo: { expiresOn: '', username: 'anonymous' }, + }; this.cookie = ''; } + setAuthInfo = (auth: AuthInfo) => { + this.auth = auth; + }; + getSession = () => { - return this.session; + return this.auth; }; getCookie = () => { return this.cookie; }; - setSession = (session: Session) => { - this.session = session; + setSession = (session: SessionInfo) => { + this.auth.sessionInfo = session; }; checkIfExtendSession = () => { @@ -52,7 +78,7 @@ export class KialiAuthentication { }; private timeLeft = (): number => { - const expiresOn = moment(this.session.expiresOn); + const expiresOn = moment(this.auth.sessionInfo.expiresOn); if (expiresOn <= moment()) { return -1; @@ -62,12 +88,12 @@ export class KialiAuthentication { }; shouldRelogin = (): boolean => { - if (this.KialiDetails.strategy === 'anonymous') { + if (this.auth.strategy === 'anonymous') { return false; } if (this.cookie === '') { return true; } - return moment(this.session.expiresOn).diff(moment()) <= 0; + return moment(this.auth.sessionInfo.expiresOn).diff(moment()) <= 0; }; } diff --git a/plugins/kiali-backend/src/clients/KialiAPIConnector.ts b/plugins/kiali-backend/src/clients/KialiAPIConnector.ts index daa925cb8e..bdc2836141 100644 --- a/plugins/kiali-backend/src/clients/KialiAPIConnector.ts +++ b/plugins/kiali-backend/src/clients/KialiAPIConnector.ts @@ -1,40 +1,6 @@ -import { Entity } from '@backstage/catalog-model'; - -import { AxiosResponse } from 'axios'; import { Logger } from 'winston'; -import { - AuthInfo, - AuthStrategy, - CanaryUpgradeStatus, - CertsInfo, - ComponentStatus, - ComputedServerConfig, - computePrometheusRateParams, - config, - defaultMetricsDuration, - defaultServerConfig, - Direction, - FetchResponseWrapper, - HealthNamespace, - INITIAL_STATUS_STATE, - IstiodResourceThresholds, - IstioMetricsOptions, - KialiConfigT, - KialiDetails, - KialiInfo, - Namespace, - NsMetrics, - nsWideMTLSStatus, - OutboundTrafficPolicy, - OverviewData, - StatusState, - TLSStatus, - ValidationStatus, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { filterNsByAnnotation } from '../filters/byAnnotation'; -import { OverviewQuery } from '../service/router'; +import { KialiDetails } from '../service/config'; import { KialiFetcher } from './fetch'; export type Options = { @@ -43,308 +9,46 @@ export type Options = { }; export interface KialiApi { - fetchConfig(): Promise; - fetchOverviewNamespaces( - entity: Entity, - query: OverviewQuery, - ): Promise; + proxy(endpoint: string): Promise; } - export class KialiApiImpl implements KialiApi { - private readonly logger: Logger; - private kialiDetails: KialiDetails; - private kialiconfig: KialiConfigT; private kialiFetcher: KialiFetcher; + private logger: Logger; constructor(options: Options) { - options.logger.debug(`creating kiali client with url=${options.kiali.url}`); this.logger = options.logger; - this.kialiDetails = options.kiali; + options.logger.debug(`creating kiali client with url=${options.kiali.url}`); this.kialiFetcher = new KialiFetcher(options.kiali, options.logger); - this.kialiconfig = { - server: defaultServerConfig, - kialiConsole: options.kiali.url, - meshTLSStatus: { status: '', autoMTLSEnabled: false, minTLS: '' }, - username: '', - }; - } - - private queryMetrics = (options: IstioMetricsOptions) => { - const filters = options.filters?.map(f => `filters[]=${f}`).join('&'); - return ( - `?${filters || ''}&duration=${options.duration}` + - `&step=${options.step}&rateInterval=${options.rateInterval}` + - `&direction=${options.direction}&reporter=${options.reporter}` - ); - }; - - private queryOptions = (query: OverviewQuery): IstioMetricsOptions => { - const direction = query.direction; - const duration = query.duration || defaultMetricsDuration; - const globalScrapeInterval = 15; - const rateParams = computePrometheusRateParams( - duration, - globalScrapeInterval, - 10, - ); - return { - filters: ['request_count', 'request_error_count'], - duration: duration, - step: rateParams.step, - rateInterval: rateParams.rateInterval, - direction: (direction as Direction) || 'inbound', - reporter: direction === 'inbound' ? 'destination' : 'source', - }; - }; - - async fetchInfo(): Promise { - const response: FetchResponseWrapper = { errors: [], warnings: [] }; - const info: KialiInfo = { - status: INITIAL_STATUS_STATE, - auth: { sessionInfo: {}, strategy: AuthStrategy.anonymous }, - }; - await Promise.all([ - this.kialiFetcher - .newRequest('api') - .then(resp => { - info.status = resp.data; - return info; - }) - .catch(err => - response.errors.push( - this.kialiFetcher.handleUnsuccessfulResponse(err), - ), - ), - this.kialiFetcher - .newRequest(config.api.urls.authInfo) - .then(resp => { - info.auth = resp.data; - // Check if strategy is the same - if (this.kialiDetails.strategy !== info.auth.strategy) { - response.errors.push({ - errorType: 'Bad configuration', - message: `Strategy in app-config is ${this.kialiDetails.strategy} and kiali server is configured for ${info.auth.strategy}`, - }); - } - return info; - }) - .catch(err => - response.errors.push( - this.kialiFetcher.handleUnsuccessfulResponse(err), - ), - ), - ]); - response.response = info; - return response; - } - - async fetchConfig(): Promise { - let response: FetchResponseWrapper = { errors: [], warnings: [] }; - await this.kialiFetcher.checkSession().then(resp => { - response = resp; - return response; - }); - if (response.errors.length === 0) { - this.logger.info( - `Authenticated user ${this.kialiFetcher.getSession().username}`, - ); - this.logger.debug(`Fetching configuration`); - await Promise.all([ - this.kialiFetcher - .newRequest(config.api.urls.serverConfig) - .then(resp => { - this.kialiconfig.server = resp.data; - return this.kialiconfig; - }) - .catch(err => - response.errors.push( - this.kialiFetcher.handleUnsuccessfulResponse(err), - ), - ), - this.kialiFetcher - .newRequest(config.api.urls.meshTls()) - .then(resp => { - this.kialiconfig.meshTLSStatus = resp.data; - return this.kialiconfig; - }) - .catch(err => - response.errors.push( - this.kialiFetcher.handleUnsuccessfulResponse(err), - ), - ), - this.kialiFetcher - .newRequest(config.api.urls.istioCertsInfo()) - .then(resp => { - this.kialiconfig.istioCerts = resp.data; - return this.kialiconfig; - }) - .catch(err => - response.errors.push( - this.kialiFetcher.handleUnsuccessfulResponse(err), - ), - ), - ]); - this.kialiconfig.username = this.kialiFetcher.getSession().username; - response.response = this.kialiconfig; - } - return response; } - async fetchNamespaces(entity: Entity): Promise { - const result: FetchResponseWrapper = { - errors: [], - warnings: [], - }; - - await this.kialiFetcher.checkSession().then(resp => { - result.errors = resp.errors; - result.warnings = resp.warnings; - return result; - }); - if (result.errors.length === 0) { - await this.handlePromise( - result, - config.api.urls.namespaces, - resp => (result.response = filterNsByAnnotation(resp.data, entity)), + async proxy(endpoint: string): Promise { + const authValid = await this.kialiFetcher.checkSession(); + if (authValid.verify) { + this.logger.debug( + `Authenticated user : ${ + this.kialiFetcher.getAuthData().sessionInfo.username + }`, ); + return this.kialiFetcher + .newRequest(endpoint) + .then(resp => resp.data); } - - return result; - } - - handlePromise( - result: FetchResponseWrapper, - endpoint: string, - handlerThen: (resp: AxiosResponse) => void, - handlerError?: (err: any) => void, - ): Promise { - return this.kialiFetcher - .newRequest(endpoint) - .then(resp => handlerThen(resp)) - .catch(err => - handlerError - ? handlerError(err) - : result.errors.push( - this.kialiFetcher.handleUnsuccessfulResponse(err, endpoint), - ), - ); + this.logger.debug( + `Authentication failed : ${ + authValid.missingAttributes && + `Missing attributes: [${authValid.missingAttributes?.join(',')}] .` + } ${authValid.message}`, + ); + return Promise.resolve(authValid); } - async fetchOverviewNamespaces( - entity: Entity, - query: OverviewQuery, - ): Promise { - this.logger.debug(`Fetching namespaces`); - const result: FetchResponseWrapper = { - errors: [], - warnings: [], - }; - - const response: OverviewData = { - namespaces: [], - }; - await this.kialiFetcher.checkSession().then(resp => { - result.errors = resp.errors; - result.warnings = resp.warnings; - return result; - }); - if (result.errors.length === 0) { - await this.handlePromise( - result, - config.api.urls.namespaces, - resp => (response.namespaces = filterNsByAnnotation(resp.data, entity)), - ); - - if (result.errors.length === 0) { - const meshStatus = 'MTLS_NOT_ENABLED'; - const duration = query.duration || defaultMetricsDuration; - const overviewType = query.overviewType; - const queryTime = undefined; - const options = this.queryOptions(query); - - await Promise.all([ - this.handlePromise( - result, - config.api.urls.canaryUpgradeStatus(), - resp => (response.canaryUpgrade = resp.data), - ), - this.handlePromise( - result, - config.api.urls.istioStatus(), - resp => (response.istioStatus = resp.data), - ), - this.handlePromise( - result, - config.api.urls.outboundTrafficPolicyMode(), - resp => (response.outboundTraffic = resp.data), - ), - this.handlePromise( - result, - config.api.urls.istiodResourceThresholds(), - resp => (response.istiodResourceThresholds = resp.data), - ), - this.handlePromise<{ - [key: string]: { [key: string]: ValidationStatus }; - }>( - result, - `${config.api.urls.configValidations()}?namespaces=${response.namespaces - .map(n => n.name) - .join(',')}`, - resp => - response.namespaces.forEach( - (n, index) => - (response.namespaces[index].validations = - resp.data[n.cluster][n.name]), - ), - ), - response.namespaces.map(ns => - this.handlePromise( - result, - config.api.urls.namespaceTls(ns.name), - resp => - (ns.tlsStatus = { - status: nsWideMTLSStatus(resp.data.status, meshStatus), - autoMTLSEnabled: resp.data.autoMTLSEnabled, - minTLS: resp.data.minTLS, - }), - ), - ), - response.namespaces.map(ns => - this.handlePromise( - result, - `${config.api.urls.namespaceMetrics(ns.name)}${this.queryMetrics( - options, - )}`, - resp => { - const metricsNs: NsMetrics = resp.data; - ns.metrics = metricsNs.request_count; - ns.errorMetrics = metricsNs.request_error_count; - if (ns.name === this.kialiconfig.server.istioNamespace) { - ns.controlPlaneMetrics = { - istiod_proxy_time: metricsNs.pilot_proxy_convergence_time, - istiod_cpu: metricsNs.process_cpu_seconds_total, - istiod_mem: metricsNs.process_virtual_memory_bytes, - }; - } - }, - ), - ), - response.namespaces.map(ns => - this.handlePromise( - result, - `${config.api.urls.namespaceHealth( - ns.name, - )}?type=${overviewType}&rateInterval=${duration}s${ - queryTime ? `&queryTime=${queryTime}` : '' - }`, - resp => (ns.nsHealth = resp.data), - ), - ), - ]); - } - result.response = response; + async status(): Promise { + const authValid = await this.kialiFetcher.checkSession(); + if (authValid.verify) { + return this.kialiFetcher + .newRequest('api/status') + .then(resp => resp.data); } - - return result; + return Promise.resolve(authValid); } } diff --git a/plugins/kiali-backend/src/clients/auth.test.ts b/plugins/kiali-backend/src/clients/auth.test.ts deleted file mode 100644 index 6e69f6e763..0000000000 --- a/plugins/kiali-backend/src/clients/auth.test.ts +++ /dev/null @@ -1,191 +0,0 @@ -import moment from 'moment'; - -import { config } from '@janus-idp/backstage-plugin-kiali-common'; - -import { - AUTH_KIALI_TOKEN, - KialiAuthentication, - MILLISECONDS, - Session, -} from './auth'; - -const kialiURL = 'https://localhost:4000'; -const tomorrow = moment().add(1, 'days'); -const yesterday = moment().subtract(1, 'days'); - -describe('createRouter', () => { - describe('KialiAuthentication constructor', () => { - it('returns values for KialiAuthentication', () => { - const kialiAuth = new KialiAuthentication({ - url: kialiURL, - strategy: 'anonymous', - skipTLSVerify: true, - }); - - expect(kialiAuth.getSession()).toEqual({ - expiresOn: '', - username: 'anonymous', - }); - expect(kialiAuth.getCookie()).toEqual(''); - // eslint-disable-next-line - expect(kialiAuth['sessionSeconds']).toEqual( - config.session.timeOutforWarningUser, - ); - }); - - it('with a specific sessionTime', () => { - const sessionSeconds = 500; - const kialiAuth = new KialiAuthentication({ - url: kialiURL, - strategy: 'anonymous', - skipTLSVerify: true, - sessionTime: sessionSeconds, - }); - // eslint-disable-next-line - expect(kialiAuth['sessionSeconds']).toEqual(500 * MILLISECONDS); - }); - }); - describe('KialiAuthentication set', () => { - it('session set', () => { - const kialiAuth = new KialiAuthentication({ - url: kialiURL, - strategy: 'anonymous', - skipTLSVerify: true, - }); - expect(kialiAuth.getSession()).toEqual({ - expiresOn: '', - username: 'anonymous', - }); - const session: Session = { - expiresOn: tomorrow.toISOString(), - username: 'kiali', - }; - kialiAuth.setSession(session); - expect(kialiAuth.getSession()).toEqual(session); - }); - - it('Cookie set', async () => { - const kialiAuth = new KialiAuthentication({ - url: kialiURL, - strategy: 'anonymous', - skipTLSVerify: true, - }); - expect(kialiAuth.getCookie()).toEqual(''); - - const cookieKiali = `${AUTH_KIALI_TOKEN}=kiali-cookie-token`; - const cookie = `d5b5278d6ecca213a6cda3f6cfaa8cef=d0f2b7c7d1dd95460bc1764814f35468; ${cookieKiali} ; date=today`; - kialiAuth.setKialiCookie(cookie); - expect(kialiAuth.getCookie()).toEqual(cookieKiali); - }); - - it('Cookie set to empty', async () => { - const kialiAuth = new KialiAuthentication({ - url: kialiURL, - strategy: 'anonymous', - skipTLSVerify: true, - }); - expect(kialiAuth.getCookie()).toEqual(''); - - const wrongCookieKiali = `${AUTH_KIALI_TOKEN}error=kiali-cookie-token`; - const cookie = `d5b5278d6ecca213a6cda3f6cfaa8cef=d0f2b7c7d1dd95460bc1764814f35468; ${wrongCookieKiali} ; date=today`; - kialiAuth.setKialiCookie(cookie); - expect(kialiAuth.getCookie()).toEqual(''); - }); - }); - - describe('Should relogin', () => { - it('should be false if strategy is anonymous', () => { - const kialiAuth = new KialiAuthentication({ - url: kialiURL, - strategy: 'anonymous', - skipTLSVerify: true, - }); - expect(kialiAuth.shouldRelogin()).toBeFalsy(); - }); - - it('should be true if strategy is not anonymous and cookie is empty', () => { - const kialiAuth = new KialiAuthentication({ - url: kialiURL, - strategy: 'token', - skipTLSVerify: true, - }); - expect(kialiAuth.shouldRelogin()).toBeTruthy(); - }); - - describe('Strategy is not anonymous', () => { - it('should check the expire time if cookie is set but expire date is out', () => { - const kialiAuth = new KialiAuthentication({ - url: kialiURL, - strategy: 'token', - skipTLSVerify: true, - }); - const cookieKiali = `${AUTH_KIALI_TOKEN}=kiali-cookie-token`; - const cookie = `d5b5278d6ecca213a6cda3f6cfaa8cef=d0f2b7c7d1dd95460bc1764814f35468; ${cookieKiali} ; date=today`; - kialiAuth.setKialiCookie(cookie); - const session: Session = { - expiresOn: yesterday.toISOString(), - username: 'kiali', - }; - kialiAuth.setSession(session); - expect(kialiAuth.shouldRelogin()).toBeTruthy(); - }); - - it('should check the expire time if cookie is set and expire date is fine', () => { - const kialiAuth = new KialiAuthentication({ - url: kialiURL, - strategy: 'token', - skipTLSVerify: true, - }); - const cookieKiali = `${AUTH_KIALI_TOKEN}=kiali-cookie-token`; - const cookie = `d5b5278d6ecca213a6cda3f6cfaa8cef=d0f2b7c7d1dd95460bc1764814f35468; ${cookieKiali} ; date=today`; - kialiAuth.setKialiCookie(cookie); - const session: Session = { - expiresOn: tomorrow.toISOString(), - username: 'kiali', - }; - kialiAuth.setSession(session); - expect(kialiAuth.getSession()).toBe(session); - expect(kialiAuth.shouldRelogin()).toBeFalsy(); - }); - - it('should check if we need extend session', () => { - const kialiAuth = new KialiAuthentication({ - url: kialiURL, - strategy: 'token', - skipTLSVerify: true, - sessionTime: 60 * 60, // 1 hour of session - }); - const cookieKiali = `${AUTH_KIALI_TOKEN}=kiali-cookie-token`; - const cookie = `d5b5278d6ecca213a6cda3f6cfaa8cef=d0f2b7c7d1dd95460bc1764814f35468; ${cookieKiali} ; date=today`; - kialiAuth.setKialiCookie(cookie); - let session: Session = { - expiresOn: tomorrow.toISOString(), - username: 'kiali', - }; - kialiAuth.setSession(session); - expect(kialiAuth.checkIfExtendSession()).toBeFalsy(); - session = { expiresOn: yesterday.toISOString(), username: 'kiali' }; - kialiAuth.setSession(session); - expect(kialiAuth.checkIfExtendSession()).toBeTruthy(); - - // Check with sessionTime less than option - const today_less_sessiontime = moment().add(50, 'minutes'); - session = { - expiresOn: today_less_sessiontime.toISOString(), - username: 'kiali', - }; - kialiAuth.setSession(session); - expect(kialiAuth.checkIfExtendSession()).toBeTruthy(); - - // Check with sessionTime less than option - const today_more_sessiontime = moment().add(70, 'minutes'); - session = { - expiresOn: today_more_sessiontime.toISOString(), - username: 'kiali', - }; - kialiAuth.setSession(session); - expect(kialiAuth.checkIfExtendSession()).toBeFalsy(); - }); - }); - }); -}); diff --git a/plugins/kiali-backend/src/clients/fetch.ts b/plugins/kiali-backend/src/clients/fetch.ts index 0e60208b0f..a750df62d3 100644 --- a/plugins/kiali-backend/src/clients/fetch.ts +++ b/plugins/kiali-backend/src/clients/fetch.ts @@ -1,20 +1,26 @@ import axios, { AxiosError, AxiosRequestConfig } from 'axios'; import { Logger } from 'winston'; -import { - config, - FetchResponseWrapper, - KialiDetails, - KialiFetchError, -} from '@janus-idp/backstage-plugin-kiali-common'; - import fs from 'fs'; import https from 'https'; -import { KialiAuthentication, Session } from './auth'; +import { KialiDetails } from '../service/config'; +import { + AuthInfo, + AuthStrategy, + KialiAuthentication, + SessionInfo, +} from './Auth'; + +export type AuthValid = { + verify: boolean; + missingAttributes?: string[]; + message?: string; + helper?: string; + authData?: AuthInfo; +}; const TIMEOUT_FETCH = 8000; - export class KialiFetcher { private readonly logger: Logger; private kialiAuth: KialiAuthentication; @@ -26,91 +32,86 @@ export class KialiFetcher { this.kialiAuth = new KialiAuthentication(KD); } - getSession = () => { - return this.kialiAuth.getSession(); - }; - newRequest = async

(endpoint: string, auth: boolean = false) => { + this.logger.info(`Query to ${endpoint}`); return axios.request

(this.getRequestInit(endpoint, auth)); }; - async checkSession(): Promise { - const response: FetchResponseWrapper = { - errors: [], - warnings: [], + private async getAuthInfo(): Promise { + return this.newRequest('api/auth/info').then(resp => resp.data); + } + + getAuthData(): AuthInfo { + return this.kialiAuth.getSession(); + } + + private validateConfiguration = (auth: AuthInfo): AuthValid => { + const result: AuthValid = { + verify: true, + authData: auth, }; + switch (auth.strategy) { + case AuthStrategy.anonymous: + break; + case AuthStrategy.token: { + if (this.KialiDetails.serviceAccountToken === '') { + result.verify = false; + result.message = `Attribute 'serviceAccountToken' is not in the backstage configuration`; + result.helper = `For more information follow the steps in https://janus-idp.io/plugins/kiali`; + result.missingAttributes = ['serviceAccountToken']; + } + break; + } + default: + result.verify = false; + result.message = `Strategy ${auth.strategy} is not supported in Kiali backstage plugin yet`; + break; + } + + return result; + }; + + async checkSession(): Promise { + let checkAuth: AuthValid = { verify: true }; /* * Check if the actual cookie/session is valid */ if (this.kialiAuth.shouldRelogin()) { + this.logger.info(`User must relogin`); + /* + * Get/Update AuthInformation from /api/auth/info + */ + const auth = await this.getAuthInfo(); + this.kialiAuth.setAuthInfo(auth); + this.logger.info(`AuthInfo: ${JSON.stringify(auth)}`); + /* + * Check Configuration + */ + checkAuth = this.validateConfiguration(auth); + if (!checkAuth.verify) { + return checkAuth; + } /* * Verify that SA token is in the config file */ - if (this.KialiDetails.serviceAccountToken) { - this.logger.debug( - `Query to ${ - new URL(config.api.urls.authenticate, this.KialiDetails.url).href - }`, - ); - const params = new URLSearchParams(); - params.append('token', this.KialiDetails.serviceAccountToken || ''); - await axios - .request( - this.getRequestInit(config.api.urls.authenticate, true), - ) + if (this.kialiAuth.checkIfExtendSession()) { + this.logger.info(`User need extend the session`); + await this.newRequest('api/authenticate', true) .then(resp => { - const session = resp.data; - /* - * Store the session and cookie - */ - this.logger.debug(`Logged username ${session.username}`); + const session = resp.data as SessionInfo; this.kialiAuth.setSession(session); this.kialiAuth.setKialiCookie( resp.headers['set-cookie']?.join(';') || '', ); + this.logger.info(`User ${session.username} logged in kiali plugin`); }) - .catch(err => - response.errors.push(this.handleUnsuccessfulResponse(err)), - ); - } else { - response.errors.push({ - errorType: 'NOT_FOUND', - message: 'No service account token for Kiali', - }); + .catch(err => { + checkAuth.verify = false; + checkAuth.message = this.handleUnsuccessfulResponse(err); + }); } - return response; } - /* - * Check if we need to extend the session - */ - if (this.kialiAuth.checkIfExtendSession()) { - this.logger.debug( - `Query to ${ - new URL(config.api.urls.authenticate, this.KialiDetails.url).href - } to extend session`, - ); - await axios - .request(this.getRequestInit(config.api.urls.authenticate)) - .then(resp => { - const session = resp.data; - /* - * Extend the session and store it - */ - this.logger.debug( - `Extended session for username ${session.username}`, - ); - this.kialiAuth.setSession(session); - return {}; - }) - .catch(err => - response.errors.push(this.handleUnsuccessfulResponse(err)), - ); - } - /* - * Login again is not needed - */ - this.logger.debug(`Not need relogin`); - return response; + return checkAuth; } private bufferFromFileOrString(file?: string, data?: string): Buffer | null { @@ -123,45 +124,26 @@ export class KialiFetcher { return null; } - handleUnsuccessfulResponse( - res: AxiosError, - endpoint?: string, - ): KialiFetchError { - const message = res.message; - const codeMessage = res.code ? `status (${res.code}) ` : ''; - const url = endpoint || res.config?.url || ''; - const urlMessage = url ? `when fetching "${url}" in "Kiali";` : ''; - this.logger.warn(`Error response axios: ${JSON.stringify(res)}`); - this.logger.warn( - `Received ${res.status} ${codeMessage} ${urlMessage} body=[${message}]`, - ); - - return { - errorType: res.code || 'UNKNOWN_ERROR', - message, - statusCode: res.status, - resourcePath: url, - }; - } - private getRequestInit = ( endpoint: string, auth: boolean = false, ): AxiosRequestConfig => { const requestInit: AxiosRequestConfig = { timeout: TIMEOUT_FETCH }; + const headers = { 'X-Auth-Type-Kiali-UI': '1' }; + if (auth) { const params = new URLSearchParams(); params.append('token', this.KialiDetails.serviceAccountToken || ''); - requestInit.headers = config.login.headers; + requestInit.headers = headers; requestInit.data = params; requestInit.method = 'post'; } else { requestInit.method = 'get'; requestInit.headers = { - ...config.login.headers, - cookie: this.kialiAuth.getCookie(), + ...headers, Accept: 'application/json', 'Content-Type': 'application/json', + cookie: this.kialiAuth.getCookie(), }; } @@ -179,4 +161,16 @@ export class KialiFetcher { } return requestInit; }; + + private handleUnsuccessfulResponse( + res: AxiosError, + endpoint?: string, + ): string { + const message = res.message; + const url = endpoint || res.config?.url || ''; + const urlMessage = url ? `when fetching "${url}" in "Kiali";` : ''; + return `[${ + res.code || 'UNKNOWN_ERROR' + }] Fetching ${urlMessage} body=[${message}]`; + } } diff --git a/plugins/kiali-backend/src/dynamic/index.ts b/plugins/kiali-backend/src/dynamic/index.ts index 3800583047..aab94ac418 100644 --- a/plugins/kiali-backend/src/dynamic/index.ts +++ b/plugins/kiali-backend/src/dynamic/index.ts @@ -1,5 +1,4 @@ import { BackendDynamicPluginInstaller } from '@backstage/backend-plugin-manager'; -import { CatalogClient } from '@backstage/catalog-client'; import { createRouter } from '../service/router'; @@ -8,10 +7,8 @@ export const dynamicPluginInstaller: BackendDynamicPluginInstaller = { router: { pluginID: 'kiali', createPlugin: async env => { - const catalogApi = new CatalogClient({ discoveryApi: env.discovery }); return await createRouter({ logger: env.logger, - catalogApi, config: env.config, }); }, diff --git a/plugins/kiali-backend/src/filters/byAnnotation.test.ts b/plugins/kiali-backend/src/filters/byAnnotation.test.ts deleted file mode 100644 index 78cbfd9a68..0000000000 --- a/plugins/kiali-backend/src/filters/byAnnotation.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Namespace } from '@janus-idp/backstage-plugin-kiali-common'; - -import { exportedForTesting } from './byAnnotation'; - -const namespaceMock: Namespace[] = [ - { - name: 'bookinfo', - cluster: 'kubernetes', - labels: { - app: 'bookinfo', - version: 'v1', - }, - }, - { - name: 'travel-agency', - cluster: 'kubernetes', - labels: { - 'backstage.io/kubernetes-id': 'travels', - app: 'travels', - }, - }, - { - name: 'travel-control', - cluster: 'kubernetes', - labels: { - app: 'travels', - }, - }, -]; - -describe('filterNsByAnnotation', () => { - describe('filterByNs', () => { - it('returns bookinfo', async () => { - const result = exportedForTesting.filterByNs( - namespaceMock, - 'bookinfo,istio-system', - ); - expect(result.length).toEqual(1); - expect(result[0].name).toEqual('bookinfo'); - }); - }); - - describe('filterById', () => { - it('returns travel-agency', async () => { - const result = exportedForTesting.filterById(namespaceMock, 'travels'); - expect(result.length).toEqual(1); - expect(result[0].name).toEqual('travel-agency'); - }); - }); - - describe('filterBySelector', () => { - it('returns travel-agency and travel-control', async () => { - const result = exportedForTesting.filterBySelector( - namespaceMock, - 'app=travels', - ); - expect(result.length).toEqual(2); - expect(result[0].name).toEqual('travel-agency'); - expect(result[1].name).toEqual('travel-control'); - }); - }); -}); diff --git a/plugins/kiali-backend/src/plugin.ts b/plugins/kiali-backend/src/plugin.ts index 9700d40795..42ef1f159f 100644 --- a/plugins/kiali-backend/src/plugin.ts +++ b/plugins/kiali-backend/src/plugin.ts @@ -1,12 +1,8 @@ -import { - HostDiscovery, - loggerToWinstonLogger, -} from '@backstage/backend-common'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; -import { CatalogClient } from '@backstage/catalog-client'; import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha'; import { createRouter } from './service/router'; @@ -27,13 +23,9 @@ export const kialiPlugin = createBackendPlugin({ }, async init({ http, logger, config }) { const winstonLogger = loggerToWinstonLogger(logger); - const catalogApi = new CatalogClient({ - discoveryApi: HostDiscovery.fromConfig(config), - }); const router = await createRouter({ logger: winstonLogger, config, - catalogApi, }); http.use(router); }, diff --git a/plugins/kiali-common/src/helpers/config.ts b/plugins/kiali-backend/src/service/config.ts similarity index 88% rename from plugins/kiali-common/src/helpers/config.ts rename to plugins/kiali-backend/src/service/config.ts index b116961d85..85e27299b4 100644 --- a/plugins/kiali-common/src/helpers/config.ts +++ b/plugins/kiali-backend/src/service/config.ts @@ -1,9 +1,16 @@ import { Config } from '@backstage/config'; -import { KialiDetails } from '../types'; - const KIALI_PREFIX = 'catalog.providers.kiali'; +export type KialiDetails = { + url: string; + skipTLSVerify?: boolean; + sessionTime?: number; + serviceAccountToken?: string; + caData?: string; + caFile?: string; +}; + const isValidUrl = (url: string): boolean => { try { // eslint-disable-next-line no-new @@ -26,6 +33,7 @@ export const getFromKialiConfig = (config: Config): Config => { }); return config; }; + export const getHubClusterFromConfig = (config: Config): KialiDetails => { const hub = getFromKialiConfig(config); @@ -36,12 +44,10 @@ export const getHubClusterFromConfig = (config: Config): KialiDetails => { return { url, - strategy: hub.getString('strategy'), serviceAccountToken: hub.getOptionalString('serviceAccountToken'), skipTLSVerify: hub.getOptionalBoolean('skipTLSVerify') || false, caData: hub.getOptionalString('caData'), caFile: hub.getOptionalString('caFile'), - sessionTime: hub.getOptionalNumber('sessionTime'), }; }; diff --git a/plugins/kiali-backend/src/service/router.test.ts b/plugins/kiali-backend/src/service/router.test.ts deleted file mode 100644 index 1e97c27310..0000000000 --- a/plugins/kiali-backend/src/service/router.test.ts +++ /dev/null @@ -1,270 +0,0 @@ -import { HostDiscovery } from '@backstage/backend-common'; -import { CatalogClient } from '@backstage/catalog-client'; -import { ConfigReader } from '@backstage/config'; - -import express from 'express'; -import { setupServer } from 'msw/node'; -import request from 'supertest'; -import { createLogger, transports } from 'winston'; - -import { readKialiConfigs } from '@janus-idp/backstage-plugin-kiali-common'; - -import { handlers } from '../../__fixtures__/handlers'; -import { KialiApiImpl } from '../clients/KialiAPIConnector'; -import { makeRouter } from './router'; - -const server = setupServer(...handlers); - -const kialiURL = 'https://localhost:4000'; -const MockConfig = { - backend: { - baseUrl: 'http://localhost:7007', - }, - catalog: { - providers: { - kiali: { - url: kialiURL, - strategy: 'anonymous', - skipTLSVerify: true, - }, - }, - }, -}; - -afterEach(() => server.restoreHandlers()); -afterAll(() => server.close()); - -beforeAll(() => - server.listen({ - /* - * This is required so that msw doesn't throw - * warnings when the express app is requesting an endpoint - */ - onUnhandledRequest: 'bypass', - }), -); - -describe('createRouter', () => { - let app: express.Express; - - beforeAll(async () => { - const mockConfig = new ConfigReader(MockConfig, 'kiali'); - const kiali = readKialiConfigs(mockConfig); - const mockCatalog = new CatalogClient({ - discoveryApi: HostDiscovery.fromConfig(mockConfig), - }); - const logger = createLogger({ - transports: [new transports.Console({ silent: true })], - }); - const kialiAPI = new KialiApiImpl({ logger, kiali }); - app = express(); - app.use(express.json()); - const router = makeRouter(logger, kialiAPI, mockCatalog); - app.use('/', router); - }); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe('POST /config', () => { - it('returns config', async () => { - const response = await request(app) - .post('/config') - .set('Content-Type', 'application/json'); - - expect(response.status).toEqual(200); - expect(response.body).toEqual({ - warnings: [], - errors: [], - response: { - server: { - accessibleNamespaces: ['**'], - authStrategy: 'anonymous', - clusterInfo: {}, - deployment: {}, - healthConfig: { - rate: [ - { - tolerance: [ - { - code: '5XX', - degraded: 0, - failure: 10, - protocol: 'http', - direction: '.*', - }, - { - code: '4XX', - degraded: 10, - failure: 20, - protocol: 'http', - direction: '.*', - }, - { - code: '^[1-9]$|^1[0-6]$', - degraded: 0, - failure: 10, - protocol: 'grpc', - direction: '.*', - }, - { - code: '^-$', - degraded: 0, - failure: 10, - protocol: 'http|grpc', - direction: '.*', - }, - ], - }, - { - tolerance: [ - { - code: '5XX', - degraded: 0, - failure: 10, - protocol: 'http', - direction: '.*', - }, - { - code: '4XX', - degraded: 10, - failure: 20, - protocol: 'http', - direction: '.*', - }, - { - code: '^[1-9]$|^1[0-6]$', - degraded: 0, - failure: 10, - protocol: 'grpc', - direction: '.*', - }, - { - code: '^-$', - degraded: 0, - failure: 10, - protocol: 'http|grpc', - direction: '.*', - }, - ], - }, - ], - }, - istioAnnotations: { - istioInjectionAnnotation: 'sidecar.istio.io/inject', - }, - istioCanaryRevision: {}, - istioStatusEnabled: true, - istioIdentityDomain: 'svc.cluster.local', - istioNamespace: 'istio-system', - istioLabels: { - appLabelName: 'app', - injectionLabelName: 'istio-injection', - injectionLabelRev: 'istio.io/rev', - versionLabelName: 'version', - }, - istioConfigMap: 'istio', - kialiFeatureFlags: { - certificatesInformationIndicators: { - enabled: true, - secrets: ['cacerts', 'istio-ca-secret'], - }, - clustering: { - enable_exec_provider: false, - }, - istioAnnotationAction: true, - istioInjectionAction: true, - istioUpgradeAction: false, - uiDefaults: { - graph: { - findOptions: [ - { - description: 'Find: slow edges (\u003e 1s)', - expression: 'rt \u003e 1000', - }, - { - description: 'Find: unhealthy nodes', - expression: '! healthy', - }, - { - description: 'Find: unknown nodes', - expression: 'name = unknown', - }, - { - description: 'Find: nodes with the 2 top rankings', - expression: 'rank \u003c= 2', - }, - ], - hideOptions: [ - { - description: 'Hide: healthy nodes', - expression: 'healthy', - }, - { - description: 'Hide: unknown nodes', - expression: 'name = unknown', - }, - { - description: - 'Hide: nodes ranked lower than the 2 top rankings', - expression: 'rank \u003e 2', - }, - ], - settings: { - fontLabel: 13, - minFontBadge: 7, - minFontLabel: 10, - }, - traffic: { - grpc: 'requests', - http: 'requests', - tcp: 'sent', - }, - }, - list: { - includeHealth: true, - includeIstioResources: true, - includeValidations: true, - showIncludeToggles: false, - }, - metricsPerRefresh: '1m', - metricsInbound: {}, - metricsOutbound: {}, - refreshInterval: '60s', - }, - validations: { - ignore: ['KIA1301'], - SkipWildcardGatewayHosts: false, - }, - }, - logLevel: 'trace', - prometheus: { - globalScrapeInterval: 15, - storageTsdbRetention: 1296000, - }, - }, - meshTLSStatus: { - status: 'MTLS_NOT_ENABLED', - autoMTLSEnabled: true, - minTLS: 'N/A', - }, - username: 'anonymous', - istioCerts: [ - { - secretName: 'istio-ca-secret', - secretNamespace: 'istio-system', - dnsNames: null, - issuer: 'O=cluster.local', - notBefore: '2023-07-10T10:43:24Z', - notAfter: '2033-07-07T10:43:24Z', - error: '', - accessible: true, - }, - ], - kialiConsole: kialiURL, - }, - }); - }); - }); -}); diff --git a/plugins/kiali-backend/src/service/router.ts b/plugins/kiali-backend/src/service/router.ts index bace4ce1d1..550040aeb1 100644 --- a/plugins/kiali-backend/src/service/router.ts +++ b/plugins/kiali-backend/src/service/router.ts @@ -1,106 +1,34 @@ import { errorHandler } from '@backstage/backend-common'; -import { CatalogApi } from '@backstage/catalog-client'; -import { - CompoundEntityRef, - parseEntityRef, - stringifyEntityRef, -} from '@backstage/catalog-model'; import { Config } from '@backstage/config'; -import { InputError } from '@backstage/errors'; -import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; -import express, { Request } from 'express'; +import express from 'express'; import { Logger } from 'winston'; -import { readKialiConfigs } from '@janus-idp/backstage-plugin-kiali-common'; - import { KialiApiImpl } from '../clients/KialiAPIConnector'; +import { readKialiConfigs } from './config'; export interface RouterOptions { logger: Logger; config: Config; - catalogApi: CatalogApi; } -export type OverviewQuery = { - ns?: string; - nss?: string[]; - overviewType?: string; - duration?: number; - direction?: string; -}; - export const makeRouter = ( logger: Logger, kialiAPI: KialiApiImpl, - catalogApi: CatalogApi, ): express.Router => { - const getEntityByReq = async (req: Request) => { - const rawEntityRef = req.body.entityRef; - if (rawEntityRef && typeof rawEntityRef !== 'string') { - throw new InputError(`entity query must be a string`); - } else if (!rawEntityRef) { - throw new InputError('entity is a required field'); - } - let entityRef: CompoundEntityRef | undefined = undefined; - - try { - entityRef = parseEntityRef(rawEntityRef); - } catch (error) { - throw new InputError(`Invalid entity ref, ${error}`); - } - - logger.info(`entityRef: ${JSON.stringify(entityRef)}`); - - const token = - getBearerTokenFromAuthorizationHeader(req.headers.authorization) || - (req.cookies?.token as string | undefined); - - logger.info(`Token: ${JSON.stringify(token)}`); - const entity = await catalogApi.getEntityByRef(entityRef, { - token: token, - }); - - if (!entity) { - throw new InputError( - `Entity ref missing, ${stringifyEntityRef(entityRef)}`, - ); - } - return entity; - }; - const router = express.Router(); router.use(express.json()); - router.post('/info', async (_, res) => { - logger.debug('Call to Kiali information'); - const response = await kialiAPI.fetchInfo(); - res.json(response); - }); - - router.post('/config', async (_, res) => { - logger.debug('Call to Configuration'); - const response = await kialiAPI.fetchConfig(); - res.json(response); - }); - - router.post('/namespaces', async (req, res) => { - const entity = await getEntityByReq(req); - logger.debug('Call to Namespaces'); - const response = await kialiAPI.fetchNamespaces(entity); - res.json(response); + // curl -H "Content-type: application/json" -H "Accept: application/json" -X GET localhost:7007/api/kiali/proxy --data '{"endpoint": "api/namespaces"}' + router.post('/proxy', async (req, res) => { + const endpoint = req.body.endpoint; + logger.info(`Call to Kiali ${endpoint}`); + res.json(await kialiAPI.proxy(endpoint)); }); - router.post('/overview', async (req, res) => { - const entity = await getEntityByReq(req); - const query: OverviewQuery = { - duration: Number(req.body.query.duration) || 600, - direction: (req.body.query.direction as string) || 'inbound', - overviewType: (req.body.query.overviewType as string) || 'app', - }; - logger.debug('Call to Overview'); - const response = await kialiAPI.fetchOverviewNamespaces(entity, query); - res.json(response); + router.post('/status', async (_, res) => { + logger.info(`Call to Kiali Status`); + res.json(await kialiAPI.status()); }); router.use(errorHandler()); @@ -113,7 +41,6 @@ export async function createRouter( ): Promise { const { logger } = options; const { config } = options; - const { catalogApi } = options; logger.info('Initializing Kiali backend'); @@ -121,5 +48,5 @@ export async function createRouter( const kialiAPI = new KialiApiImpl({ logger, kiali }); - return makeRouter(logger, kialiAPI, catalogApi); + return makeRouter(logger, kialiAPI); } diff --git a/plugins/kiali-backend/src/service/standaloneServer.ts b/plugins/kiali-backend/src/service/standaloneServer.ts index b877b68b4d..4ea2081eaf 100644 --- a/plugins/kiali-backend/src/service/standaloneServer.ts +++ b/plugins/kiali-backend/src/service/standaloneServer.ts @@ -1,5 +1,4 @@ -import { createServiceBuilder, HostDiscovery } from '@backstage/backend-common'; -import { CatalogClient } from '@backstage/catalog-client'; +import { createServiceBuilder } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { Logger } from 'winston'; @@ -19,14 +18,10 @@ export async function startStandaloneServer( ): Promise { const logger = options.logger.child({ service: 'kiali-backend' }); const config = new ConfigReader({}); - const catalogApi = new CatalogClient({ - discoveryApi: HostDiscovery.fromConfig(config), - }); logger.debug('Starting application server...'); const router = await createRouter({ logger, config, - catalogApi, }); let service = createServiceBuilder(module) diff --git a/plugins/kiali-common/.eslintrc.js b/plugins/kiali-common/.eslintrc.js deleted file mode 100644 index e2a53a6ad2..0000000000 --- a/plugins/kiali-common/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/kiali-common/CHANGELOG.md b/plugins/kiali-common/CHANGELOG.md deleted file mode 100644 index ecbcf83b07..0000000000 --- a/plugins/kiali-common/CHANGELOG.md +++ /dev/null @@ -1,59 +0,0 @@ -## @janus-idp/backstage-plugin-kiali-common 1.0.0 (2023-10-27) - - -### Features - -* **kiali:** add namespace selector ([#675](https://github.com/janus-idp/backstage-plugins/issues/675)) ([e3cfc26](https://github.com/janus-idp/backstage-plugins/commit/e3cfc26bdf550916da3ee801601196d8614471b5)) -* **kiali:** kiali plugin ([#371](https://github.com/janus-idp/backstage-plugins/issues/371)) ([08d5583](https://github.com/janus-idp/backstage-plugins/commit/08d5583f839a8233d7b08a7ec1eb043bf4978e91)) -* **kiali:** move from node-fetch to axios ([#573](https://github.com/janus-idp/backstage-plugins/issues/573)) ([c0ed797](https://github.com/janus-idp/backstage-plugins/commit/c0ed7972ef8fa143d51b590ca5f874900e5d8bef)) -* **kiali:** show kiali information in header ([#630](https://github.com/janus-idp/backstage-plugins/issues/630)) ([b9a83b3](https://github.com/janus-idp/backstage-plugins/commit/b9a83b332ec518e60a9780961fdce070eda02d02)) -* **ts:** transpile each plugin separately ([#634](https://github.com/janus-idp/backstage-plugins/issues/634)) ([b94c4dc](https://github.com/janus-idp/backstage-plugins/commit/b94c4dc50ada328e5ce1bed5fb7c76f64607e1ee)) - - -### Bug Fixes - -* **kiali:** fix code smells ([#607](https://github.com/janus-idp/backstage-plugins/issues/607)) ([ef2eecf](https://github.com/janus-idp/backstage-plugins/commit/ef2eecfa71e2a60b4442ce3105a526b3332eaa1b)) - -## @janus-idp/backstage-plugin-kiali-common [1.4.1](https://github.com/janus-idp/backstage-plugins/compare/@janus-idp/backstage-plugin-kiali-common@1.4.0...@janus-idp/backstage-plugin-kiali-common@1.4.1) (2023-10-19) - -## @janus-idp/backstage-plugin-kiali-common [1.4.0](https://github.com/janus-idp/backstage-plugins/compare/@janus-idp/backstage-plugin-kiali-common@1.3.0...@janus-idp/backstage-plugin-kiali-common@1.4.0) (2023-08-30) - - -### Features - -* **kiali:** add namespace selector ([#675](https://github.com/janus-idp/backstage-plugins/issues/675)) ([e3cfc26](https://github.com/janus-idp/backstage-plugins/commit/e3cfc26bdf550916da3ee801601196d8614471b5)) - -## @janus-idp/backstage-plugin-kiali-common [1.3.0](https://github.com/janus-idp/backstage-plugins/compare/@janus-idp/backstage-plugin-kiali-common@1.2.1...@janus-idp/backstage-plugin-kiali-common@1.3.0) (2023-08-28) - - -### Features - -* **kiali:** show kiali information in header ([#630](https://github.com/janus-idp/backstage-plugins/issues/630)) ([b9a83b3](https://github.com/janus-idp/backstage-plugins/commit/b9a83b332ec518e60a9780961fdce070eda02d02)) - -## @janus-idp/backstage-plugin-kiali-common [1.2.1](https://github.com/janus-idp/backstage-plugins/compare/@janus-idp/backstage-plugin-kiali-common@1.2.0...@janus-idp/backstage-plugin-kiali-common@1.2.1) (2023-08-22) - - -### Bug Fixes - -* **kiali:** fix code smells ([#607](https://github.com/janus-idp/backstage-plugins/issues/607)) ([ef2eecf](https://github.com/janus-idp/backstage-plugins/commit/ef2eecfa71e2a60b4442ce3105a526b3332eaa1b)) - -## @janus-idp/backstage-plugin-kiali-common [1.2.0](https://github.com/janus-idp/backstage-plugins/compare/@janus-idp/backstage-plugin-kiali-common@1.1.0...@janus-idp/backstage-plugin-kiali-common@1.2.0) (2023-08-14) - - -### Features - -* **ts:** transpile each plugin separately ([#634](https://github.com/janus-idp/backstage-plugins/issues/634)) ([b94c4dc](https://github.com/janus-idp/backstage-plugins/commit/b94c4dc50ada328e5ce1bed5fb7c76f64607e1ee)) - -## @janus-idp/backstage-plugin-kiali-common [1.1.0](https://github.com/janus-idp/backstage-plugins/compare/@janus-idp/backstage-plugin-kiali-common@1.0.0...@janus-idp/backstage-plugin-kiali-common@1.1.0) (2023-07-27) - - -### Features - -* **kiali:** move from node-fetch to axios ([#573](https://github.com/janus-idp/backstage-plugins/issues/573)) ([c0ed797](https://github.com/janus-idp/backstage-plugins/commit/c0ed7972ef8fa143d51b590ca5f874900e5d8bef)) - -## @janus-idp/backstage-plugin-kiali-common 1.0.0 (2023-07-25) - - -### Features - -* **kiali:** kiali plugin ([#371](https://github.com/janus-idp/backstage-plugins/issues/371)) ([08d5583](https://github.com/janus-idp/backstage-plugins/commit/08d5583f839a8233d7b08a7ec1eb043bf4978e91)) diff --git a/plugins/kiali-common/README.md b/plugins/kiali-common/README.md deleted file mode 100644 index 0cfb61b886..0000000000 --- a/plugins/kiali-common/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Kiali Common plugin for Kiali Plugin - -Welcome to the common package for the kiali plugin! - -For more information about Kiali plugin, see the [Kiali Plugin documentation](https://github.com/janus-idp/backstage-plugins/tree/main/plugins/kiali) on GitHub. diff --git a/plugins/kiali-common/package.json b/plugins/kiali-common/package.json deleted file mode 100644 index 56dab11dec..0000000000 --- a/plugins/kiali-common/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@janus-idp/backstage-plugin-kiali-common", - "description": "Common functionalities for the kiali plugin", - "version": "1.0.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "module": "dist/index.esm.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "common-library" - }, - "scripts": { - "build": "backstage-cli package build", - "tsc": "tsc", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test --passWithNoTests --coverage", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "devDependencies": { - "@backstage/cli": "0.23.0", - "supertest": "6.3.3" - }, - "files": [ - "dist" - ], - "dependencies": { - "@backstage/config": "^1.1.1", - "deep-freeze": "^0.0.1" - } -} diff --git a/plugins/kiali-common/src/config/index.ts b/plugins/kiali-common/src/config/index.ts deleted file mode 100644 index bd37f302df..0000000000 --- a/plugins/kiali-common/src/config/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Config'; diff --git a/plugins/kiali-common/src/helpers/index.ts b/plugins/kiali-common/src/helpers/index.ts deleted file mode 100644 index f03c2281a9..0000000000 --- a/plugins/kiali-common/src/helpers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './config'; diff --git a/plugins/kiali-common/src/index.ts b/plugins/kiali-common/src/index.ts deleted file mode 100644 index 12cee53565..0000000000 --- a/plugins/kiali-common/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './config'; -export * from './helpers'; -export * from './types'; -export * from './query'; -export * from './responses'; -export * from './utils'; diff --git a/plugins/kiali-common/src/query/index.ts b/plugins/kiali-common/src/query/index.ts deleted file mode 100644 index 5448ad2d1d..0000000000 --- a/plugins/kiali-common/src/query/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const KUBERNETES_ANNOTATION = 'backstage.io/kubernetes-id'; -export const KUBERNETES_LABEL_SELECTOR = - 'backstage.io/kubernetes-label-selector'; -export const KUBERNETES_NAMESPACE = 'backstage.io/kubernetes-namespace'; diff --git a/plugins/kiali-common/src/responses/index.ts b/plugins/kiali-common/src/responses/index.ts deleted file mode 100644 index 6368110b36..0000000000 --- a/plugins/kiali-common/src/responses/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { - CanaryUpgradeStatus, - ComponentStatus, - IstiodResourceThresholds, - NamespaceInfo, - OutboundTrafficPolicy, -} from '../types'; - -export type OverviewData = { - namespaces: NamespaceInfo[]; - canaryUpgrade?: CanaryUpgradeStatus; - istioStatus?: ComponentStatus[]; - outboundTraffic?: OutboundTrafficPolicy; - istiodResourceThresholds?: IstiodResourceThresholds; -}; diff --git a/plugins/kiali-common/src/setupTests.ts b/plugins/kiali-common/src/setupTests.ts deleted file mode 100644 index cb0ff5c3b5..0000000000 --- a/plugins/kiali-common/src/setupTests.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/plugins/kiali-common/src/types/Common.ts b/plugins/kiali-common/src/types/Common.ts deleted file mode 100644 index da24f43bc5..0000000000 --- a/plugins/kiali-common/src/types/Common.ts +++ /dev/null @@ -1,98 +0,0 @@ -export const defaultMetricsDuration: number = 600; - -// cluster name to denote the cluster where Kiali is deployed -export const HomeClusterName = ''; - -export enum HTTP_VERBS { - DELETE = 'DELETE', - GET = 'get', - PATCH = 'patch', - POST = 'post', - PUT = 'put', -} - -export type TargetKind = 'app' | 'service' | 'workload'; - -export const MILLISECONDS = 1000; - -export const UNIT_TIME = { - SECOND: 1, - MINUTE: 60, - HOUR: 3600, - DAY: 24 * 3600, -}; - -export type BoundsInMilliseconds = { - from?: number; - to?: number; -}; - -// Redux doesn't work well with type composition -export type TimeRange = { - from?: number; - to?: number; - rangeDuration?: number; -}; - -// Type-guarding TimeRange: executes first callback when range is a duration, or second callback when it's a bounded range, mapping to a value -export function guardTimeRange( - range: TimeRange, - ifDuration: (d: number) => T, - ifBounded: (b: BoundsInMilliseconds) => T, -): T { - if (range.from) { - const b: BoundsInMilliseconds = { - from: range.from, - }; - if (range.to) { - b.to = range.to; - } - return ifBounded(b); - } - - if (range.rangeDuration) { - return ifDuration(range.rangeDuration); - } - - // It shouldn't reach here a TimeRange should have DurationInSeconds or BoundsInMilliseconds - return ifDuration(defaultMetricsDuration); -} - -export const durationToBounds = (duration: number): BoundsInMilliseconds => { - return { - from: new Date().getTime() - duration * 1000, - }; -}; - -export const evalTimeRange = (range: TimeRange): [Date, Date] => { - const bounds = guardTimeRange(range, durationToBounds, b => b); - return [ - bounds.from ? new Date(bounds.from) : new Date(), - bounds.to ? new Date(bounds.to) : new Date(), - ]; -}; - -export const boundsToDuration = (bounds: BoundsInMilliseconds): number => { - return Math.floor( - ((bounds.to || new Date().getTime()) - - (bounds.from || new Date().getTime())) / - 1000, - ); -}; - -export const isEqualTimeRange = (t1: TimeRange, t2: TimeRange): boolean => { - if (t1.from && t2.from && t1.from !== t2.from) { - return false; - } - if (t1.to && t2.to && t1.to !== t2.to) { - return false; - } - if ( - t1.rangeDuration && - t2.rangeDuration && - t1.rangeDuration !== t2.rangeDuration - ) { - return false; - } - return true; -}; diff --git a/plugins/kiali-common/src/types/Config.ts b/plugins/kiali-common/src/types/Config.ts deleted file mode 100644 index cf8f3f169e..0000000000 --- a/plugins/kiali-common/src/types/Config.ts +++ /dev/null @@ -1,278 +0,0 @@ -import { parseHealthConfig } from './HealthConfig'; - -export type KialiDetails = { - url: string; - strategy: string; - skipTLSVerify?: boolean; - serviceAccountToken?: string; - caData?: string; - caFile?: string; - sessionTime?: number; -}; - -export interface MeshCluster { - apiEndpoint: string; - isKialiHome: boolean; - kialiInstances: KialiInstance[]; - name: string; - network: string; - secretName: string; -} - -export interface KialiInstance { - serviceName: string; - namespace: string; - operatorResource: string; - url: string; - version: string; -} - -export type IstioLabelKey = - | 'appLabelName' - | 'versionLabelName' - | 'injectionLabelName' - | 'injectionLabelRev'; - -interface ClusterInfo { - name: string; - network: string; -} - -interface DeploymentConfig { - viewOnlyMode: boolean; -} - -interface IstioAnnotations { - // this could also be the name of the pod label, both label and annotation are supported - istioInjectionAnnotation: string; -} - -interface GraphFindOption { - description: string; - expression: string; -} - -interface GraphTraffic { - grpc: string; - http: string; - tcp: string; -} - -interface GraphSettings { - fontLabel: number; - minFontBadge: number; - minFontLabel: number; -} - -interface GraphUIDefaults { - findOptions: GraphFindOption[]; - hideOptions: GraphFindOption[]; - settings: GraphSettings; - traffic: GraphTraffic; -} - -interface UIDefaults { - graph: GraphUIDefaults; - metricsPerRefresh?: string; - namespaces?: string[]; - refreshInterval?: string; -} - -interface CertificatesInformationIndicators { - enabled: boolean; -} - -interface KialiFeatureFlags { - certificatesInformationIndicators: CertificatesInformationIndicators; - disabledFeatures: string[]; - istioInjectionAction: boolean; - istioAnnotationAction: boolean; - istioUpgradeAction: boolean; - uiDefaults: UIDefaults; -} - -// Not based exactly on Kiali configuration but rather whether things like prometheus config -// allow for certain Kiali features. True means the feature is crippled, false means supported. -export interface KialiCrippledFeatures { - requestSize: boolean; - requestSizeAverage: boolean; - requestSizePercentiles: boolean; - responseSize: boolean; - responseSizeAverage: boolean; - responseSizePercentiles: boolean; - responseTime: boolean; - responseTimeAverage: boolean; - responseTimePercentiles: boolean; -} - -interface IstioCanaryRevision { - current: string; - upgrade: string; -} - -/* - Health Config -*/ -export type RegexConfig = string | RegExp; - -export interface HealthConfig { - rate: RateHealthConfig[]; -} - -// rateHealthConfig -export interface RateHealthConfig { - namespace?: RegexConfig; - kind?: RegexConfig; - name?: RegexConfig; - tolerance: ToleranceConfig[]; -} -// toleranceConfig -export interface ToleranceConfig { - code: RegexConfig; - degraded: number; - failure: number; - protocol?: RegexConfig; - direction?: RegexConfig; -} - -/* - End Health Config -*/ - -export interface ServerConfig { - accessibleNamespaces: Array; - authStrategy: string; - clusterInfo?: ClusterInfo; - clusters: { [key: string]: MeshCluster }; - deployment: DeploymentConfig; - gatewayAPIEnabled: boolean; - healthConfig: HealthConfig; - installationTag?: string; - istioAnnotations: IstioAnnotations; - istioCanaryRevision: IstioCanaryRevision; - istioIdentityDomain: string; - istioNamespace: string; - istioLabels: { [key in IstioLabelKey]: string }; - kialiFeatureFlags: KialiFeatureFlags; - logLevel: string; - prometheus: { - globalScrapeInterval?: number; - storageTsdbRetention?: number; - }; -} - -export type Durations = { [key: number]: string }; - -export type ComputedServerConfig = ServerConfig & { - durations: Durations; -}; - -export const defaultServerConfig: ComputedServerConfig = { - accessibleNamespaces: [], - authStrategy: '', - clusters: {}, - durations: {}, - gatewayAPIEnabled: false, - logLevel: '', - healthConfig: { - rate: [], - }, - deployment: { - viewOnlyMode: false, - }, - installationTag: 'Kiali Console', - istioAnnotations: { - istioInjectionAnnotation: 'sidecar.istio.io/inject', - }, - istioCanaryRevision: { - current: '', - upgrade: '', - }, - istioIdentityDomain: 'svc.cluster.local', - istioNamespace: 'istio-system', - istioLabels: { - appLabelName: 'app', - injectionLabelName: 'istio-injection', - injectionLabelRev: 'istio.io/rev', - versionLabelName: 'version', - }, - kialiFeatureFlags: { - certificatesInformationIndicators: { - enabled: true, - }, - disabledFeatures: [], - istioInjectionAction: true, - istioAnnotationAction: true, - istioUpgradeAction: false, - uiDefaults: { - graph: { - findOptions: [], - hideOptions: [], - settings: { - fontLabel: 13, - minFontBadge: 7, - minFontLabel: 10, - }, - traffic: { - grpc: 'requests', - http: 'requests', - tcp: 'sent', - }, - }, - }, - }, - prometheus: { - globalScrapeInterval: 15, - storageTsdbRetention: 21600, - }, -}; - -const toDurations = (tupleArray: [number, string][]): Durations => { - const obj: { [key: number]: string } = {}; - tupleArray.forEach(tuple => { - obj[tuple[0]] = tuple[1]; - }); - return obj; -}; - -const durationsTuples: [number, string][] = [ - [60, '1m'], - [120, '2m'], - [300, '5m'], - [600, '10m'], - [1800, '30m'], - [3600, '1h'], - [10800, '3h'], - [21600, '6h'], - [43200, '12h'], - [86400, '1d'], - [604800, '7d'], - [2592000, '30d'], -]; -export const computeValidDurations = (cfg: ComputedServerConfig) => { - const tsdbRetention = cfg.prometheus.storageTsdbRetention; - const scrapeInterval = cfg.prometheus.globalScrapeInterval; - let filtered = durationsTuples.filter( - d => - (!tsdbRetention || d[0] <= tsdbRetention) && - (!scrapeInterval || d[0] >= scrapeInterval * 2), - ); - // Make sure we keep at least one item, even if it's silly - if (filtered.length === 0) { - filtered = [durationsTuples[0]]; - } - cfg.durations = toDurations(filtered); -}; - -export const setServerConfig = ( - serverConfig: ComputedServerConfig, - cfg: ServerConfig, -) => { - const config = { ...defaultServerConfig, ...cfg }; - config.healthConfig = cfg.healthConfig - ? parseHealthConfig(cfg.healthConfig) - : serverConfig.healthConfig; - computeValidDurations(config); - - return config; -}; diff --git a/plugins/kiali-common/src/types/Fetch.ts b/plugins/kiali-common/src/types/Fetch.ts deleted file mode 100644 index 26b84c1fc4..0000000000 --- a/plugins/kiali-common/src/types/Fetch.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - AuthInfo, - ControlPlaneMetricsMap, - KialiConfigT, - Metric, - Namespace, - NamespaceHealth, - NamespaceInfo, - OverviewData, - StatusState, - TLSStatus, -} from '../'; - -export type NsMetrics = { [key: string]: Metric[] }; -export type HealthNamespace = { [key: string]: NamespaceHealth }; - -export interface KialiInfo { - status: StatusState; - auth: AuthInfo; -} -export type FetchResponse = - | KialiConfigT - | KialiInfo - | OverviewData - | NamespaceInfo - | TLSStatus - | NsMetrics - | ControlPlaneMetricsMap - | HealthNamespace - | Namespace[]; - -export interface StatusError { - errorType: string; - message?: string; - resourcePath?: string; - statusCode?: number; -} - -export type KialiFetchError = StatusError; - -export interface FetchResponseWrapper { - errors: KialiFetchError[]; - warnings: KialiFetchError[]; - response?: FetchResponse; -} - -export type FetchResult = FetchResponse | KialiFetchError | number; diff --git a/plugins/kiali-common/src/types/Health.ts b/plugins/kiali-common/src/types/Health.ts deleted file mode 100644 index 119afe8373..0000000000 --- a/plugins/kiali-common/src/types/Health.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { RequestHealth } from './'; - -export type NamespaceHealth = { - workloadStatuses?: WorkloadStatus[]; - WorkloadStatus?: WorkloadStatus; - requests: RequestHealth; -}; - -export interface WorkloadStatus { - name: string; - desiredReplicas: number; - currentReplicas: number; - availableReplicas: number; - syncedProxies: number; -} - -export type HealthAnnotationType = { [key: string]: string }; diff --git a/plugins/kiali-common/src/types/HealthStatus.ts b/plugins/kiali-common/src/types/HealthStatus.ts deleted file mode 100644 index 71a6bf8355..0000000000 --- a/plugins/kiali-common/src/types/HealthStatus.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { HealthAnnotationType, ToleranceConfig } from './'; - -/* -RequestType interface -- where the structure is type {: {:value ...} ...} - -Example: { "http": {"200": 2, "404": 1 ...} ... } -*/ -export interface RequestType { - [key: string]: { [key: string]: number }; -} -export interface RequestHealth { - inbound: RequestType; - outbound: RequestType; - healthAnnotations: HealthAnnotationType; -} - -export interface Status { - name: string; - color?: string; - htmlColor?: string; - priority: number; -} - -export interface ProxyStatus { - CDS: string; - EDS: string; - LDS: string; - RDS: string; -} - -export const FAILURE: Status = { - name: 'Failure', - color: 'error', - htmlColor: '#c9190b', - priority: 4, -}; -export const DEGRADED: Status = { - name: 'Degraded', - htmlColor: '#f0ab00', - priority: 3, -}; -export const NOT_READY: Status = { - name: 'Not Ready', - htmlColor: '#6a6e73', - priority: 2, -}; -export const HEALTHY: Status = { - name: 'Healthy', - htmlColor: '#3e8635', - priority: 1, -}; -export const NA: Status = { - name: 'No health information', - htmlColor: '#6a6e73', - priority: 0, -}; - -export interface Thresholds { - degraded: number; - failure: number; - unit: string; -} - -export interface ThresholdStatus { - value: number; - status: Status; - violation?: string; -} - -export const POD_STATUS = 'Pod Status'; - -// Use -1 rather than NaN to allow straigthforward comparison -export const RATIO_NA = -1; - -export const ascendingThresholdCheck = ( - value: number, - thresholds: Thresholds, -): ThresholdStatus => { - if (value > 0) { - if (value >= thresholds.failure) { - return { - value: value, - status: FAILURE, - violation: `${value.toFixed(2)}${thresholds.unit}>=${ - thresholds.failure - }${thresholds.unit}`, - }; - } else if (value >= thresholds.degraded) { - return { - value: value, - status: DEGRADED, - violation: `${value.toFixed(2)}${thresholds.unit}>=${ - thresholds.degraded - }${thresholds.unit}`, - }; - } - } - - return { value: value, status: HEALTHY }; -}; - -export const getRequestErrorsStatus = ( - ratio: number, - tolerance?: ToleranceConfig, -): ThresholdStatus => { - if (tolerance && ratio >= 0) { - const thresholds = { - degraded: tolerance.degraded, - failure: tolerance.failure, - unit: '%', - }; - return ascendingThresholdCheck(100 * ratio, thresholds); - } - - return { - value: RATIO_NA, - status: NA, - }; -}; diff --git a/plugins/kiali-common/src/types/IstioConfigList.test.ts b/plugins/kiali-common/src/types/IstioConfigList.test.ts deleted file mode 100644 index 3e5a2715b1..0000000000 --- a/plugins/kiali-common/src/types/IstioConfigList.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { filterConfigValidations, IstioConfigItem } from './IstioConfigList'; - -const items: IstioConfigItem[] = [ - { - namespace: 'bookinfo', - type: 'service', - name: 'productpage', - validation: { - name: 'Check', - objectType: 'validation', - valid: true, - checks: [], - }, - }, - { - namespace: 'bookinfo', - type: 'service', - name: 'details', - validation: { - name: 'Check', - objectType: 'validation', - valid: false, - checks: [], - }, - }, - { - namespace: 'bookinfo', - type: 'service', - name: 'reviews', - }, -]; -describe('IstioConfigList', () => { - describe('filterConfigValidations', () => { - it('returns filtered correctly the istiovalidations', () => { - const filterByValid = true; - const filterByWarning = false; - const filterByNotValidated = true; - const result = filterConfigValidations(items, { - filterByValid, - filterByWarning, - filterByNotValidated, - }); - expect(result.length).toBe(2); - expect(result[0].name).toBe('productpage'); - expect(result[1].name).toBe('reviews'); - }); - }); -}); diff --git a/plugins/kiali-common/src/types/Namespace.ts b/plugins/kiali-common/src/types/Namespace.ts deleted file mode 100644 index 7eebb309c3..0000000000 --- a/plugins/kiali-common/src/types/Namespace.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { - ControlPlaneMetricsMap, - IstioConfigList, - Metric, - NamespaceHealth, - TLSStatus, - ValidationStatus, -} from './'; - -export interface Namespace { - name: string; - cluster: string; - labels?: { [key: string]: string }; -} -export type NamespaceInfo = { - name: string; - cluster: string; - outboundPolicyMode?: string; - status?: NamespaceStatus; - tlsStatus?: TLSStatus; - istioConfig?: IstioConfigList; - validations?: ValidationStatus; - metrics?: Metric[]; - errorMetrics?: Metric[]; - labels?: { [key: string]: string }; - controlPlaneMetrics?: ControlPlaneMetricsMap; - nsHealth?: { [key: string]: NamespaceHealth }; -}; - -export type NamespaceStatus = { - inNotReady: string[]; - inError: string[]; - inWarning: string[]; - inSuccess: string[]; - notAvailable: string[]; -}; - -export const namespaceFromString = (namespace: string) => ({ name: namespace }); - -export const namespacesFromString = (namespaces: string) => { - return namespaces.split(',').map(name => namespaceFromString(name)); -}; - -export const namespacesToString = (namespaces: Namespace[]) => - namespaces.map(namespace => namespace.name).join(','); diff --git a/plugins/kiali-common/src/types/Permissions.ts b/plugins/kiali-common/src/types/Permissions.ts deleted file mode 100644 index a52792bade..0000000000 --- a/plugins/kiali-common/src/types/Permissions.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ComputedServerConfig } from './'; - -export interface ResourcePermissions { - create: boolean; - update: boolean; - delete: boolean; -} - -export function canCreate( - serverConfig: ComputedServerConfig, - privs?: ResourcePermissions, -) { - return privs?.create && !serverConfig.deployment.viewOnlyMode; -} - -export function canUpdate( - serverConfig: ComputedServerConfig, - privs?: ResourcePermissions, -) { - return privs?.update && !serverConfig.deployment.viewOnlyMode; -} - -export function canDelete( - serverConfig: ComputedServerConfig, - privs?: ResourcePermissions, -) { - return privs?.delete && !serverConfig.deployment.viewOnlyMode; -} diff --git a/plugins/kiali-common/src/types/index.ts b/plugins/kiali-common/src/types/index.ts deleted file mode 100644 index 5e437c31ea..0000000000 --- a/plugins/kiali-common/src/types/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -export * from './Auth'; -export * from './CertsInfo'; -export * from './Common'; -export * from './Config'; -export * from './Dashboards'; -export * from './Fetch'; -export * from './Graph'; -export * from './Health'; -export * from './HealthAnnotation'; -export * from './HealthConfig'; -export * from './HealthStatus'; -export * from './MetricsOptions'; -export * from './Namespace'; -export * from './Overlay'; -export * from './IstioConfigList'; -export * from './IstioObjects'; -export * from './IstioStatus'; -export * from './IstioWizards'; -export * from './Permissions'; -export * from './StatusState'; -export * from './TLSStatus'; -export * from './Metrics'; -export * from './VictoryChartInfo'; diff --git a/plugins/kiali-common/src/utils/RateIntervals.ts b/plugins/kiali-common/src/utils/RateIntervals.ts deleted file mode 100644 index 9cf48c9030..0000000000 --- a/plugins/kiali-common/src/utils/RateIntervals.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ComputedServerConfig } from '../types'; - -export const getName = ( - serverConfig: ComputedServerConfig, - durationSeconds: number, -): string => { - const name = serverConfig.durations[durationSeconds]; - if (name) { - return name; - } - return `${durationSeconds} seconds`; -}; diff --git a/plugins/kiali-common/src/utils/index.ts b/plugins/kiali-common/src/utils/index.ts deleted file mode 100644 index 4ea14cd8f6..0000000000 --- a/plugins/kiali-common/src/utils/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './CancelablePromises'; -export * from './Prometheus'; -export * from './RateIntervals'; -export * from './TimeSeriesUtils'; -export * from './VictoryChartsUtils'; -export * from './VictoryEvents'; diff --git a/plugins/kiali-common/tsconfig.json b/plugins/kiali-common/tsconfig.json deleted file mode 100644 index 4bd72a66db..0000000000 --- a/plugins/kiali-common/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@backstage/cli/config/tsconfig.json", - "include": ["src", "dev", "migrations"], - "exclude": ["node_modules"], - "compilerOptions": { - "outDir": "../../dist-types/plugins/kiali-common", - "rootDir": "." - } -} diff --git a/plugins/kiali-common/turbo.json b/plugins/kiali-common/turbo.json deleted file mode 100644 index 1f3d52c6ec..0000000000 --- a/plugins/kiali-common/turbo.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": ["//"], - "pipeline": { - "tsc": { - "outputs": ["../../dist-types/plugins/kiali-common/**"], - "dependsOn": ["^tsc"] - } - } -} diff --git a/plugins/kiali/CONTRIBUTING.md b/plugins/kiali/CONTRIBUTING.md new file mode 100644 index 0000000000..0e82e6f828 --- /dev/null +++ b/plugins/kiali/CONTRIBUTING.md @@ -0,0 +1,9 @@ +# Setting up the development environment for Quay plugin + +In [Backstage plugin terminology](https://backstage.io/docs/local-dev/cli-build-system#package-roles), the Kiali plugin is a front-end plugin. + +You can run the following commands concurrently from the root repository to start a live development session: + +```console +yarn workspace @janus-idp/backstage-plugin-kiali run start +``` diff --git a/plugins/kiali/DEVELOPMENT.md b/plugins/kiali/DEVELOPMENT.md index 43d93d594e..7b8bd57bf5 100644 --- a/plugins/kiali/DEVELOPMENT.md +++ b/plugins/kiali/DEVELOPMENT.md @@ -18,51 +18,13 @@ "@janus-idp/backstage-plugin-kiali": "link:../../plugins/kiali", ``` - or launch - - ```bash - yarn workspace add @janus-idp/backstage-plugin-kiali@* - ``` - - Add to packages/backend/package.json ```yaml title="packages/backend/package.json" '@janus-idp/backstage-plugin-kiali-backend': 'link:../../plugins/kiali-backend' ``` - or launch - - ```bash - yarn workspace backend @janus-idp/backstage-plugin-kiali-backend@* - ``` - -2. If you are going to modify `kiali-common` then you need to link this too. - - - Replace in plugin/kiali/package.json - - ```yaml title="plugin/kiali/package.json" - "@janus-idp/backstage-plugin-kiali-common": "link:../kiali-common", - ``` - - or launch - - ```bash - yarn upgrade @janus-idp/backstage-plugin-kiali-common@link:../kiali-common - ``` - - - Replace in plugin/kiali-backend/package.json - - ```yaml title="plugin/kiali-backend/package.json" - "@janus-idp/backstage-plugin-kiali-common": "link:../kiali-common", - ``` - - or launch - - ```bash - yarn upgrade @janus-idp/backstage-plugin-kiali-common@link:../kiali-common - ``` - -3. Enable the **Kiali** tab on the entity view page using the `packages/app/src/components/catalog/EntityPage.tsx` file: +2. Enable the **Kiali** tab on the entity view page using the `packages/app/src/components/catalog/EntityPage.tsx` file: ```tsx title="packages/app/src/components/catalog/EntityPage.tsx" /* highlight-add-next-line */ @@ -80,12 +42,10 @@ ); ``` -4. Create a file called `kiali.ts` inside `packages/backend/src/plugins/` and add the following: +3. Create a file called `kiali.ts` inside `packages/backend/src/plugins/` and add the following: ```ts /* highlight-add-start */ -import { CatalogClient } from '@backstage/catalog-client'; - import { Router } from 'express'; import { createRouter } from '@janus-idp/backstage-plugin-kiali-backend'; @@ -95,10 +55,8 @@ import { PluginEnvironment } from '../types'; export default async function createPlugin( env: PluginEnvironment, ): Promise { - const catalogApi = new CatalogClient({ discoveryApi: env.discovery }); return await createRouter({ logger: env.logger, - catalogApi, config: env.config, }); } @@ -130,8 +88,6 @@ catalog: kiali: # Required. Kiali endpoint url: ${KIALI_ENDPOINT} - # Required. Kiali authentication. Supported anonymous and token - strategy: ${KIALI_AUTH_STRATEGY} # Optional. Required by token authentication serviceAccountToken: ${KIALI_SERVICE_ACCOUNT_TOKEN} # Optional. defaults false @@ -145,6 +101,17 @@ catalog: # highlight-add-end ``` +7. Add catalog + +Add to locations in `app-config.yaml` + +```yaml +locations: + # Local example data for Kiali plugin + - type: file + target: ../../plugins/kiali/catalog-demo.yaml +``` + ## Configure auth ### Token authentication @@ -158,8 +125,6 @@ catalog: kiali: # Required. Kiali endpoint url: ${KIALI_ENDPOINT} - # Required. Kiali authentication. Supported anonymous and token - strategy: token # Optional. Required by token authentication serviceAccountToken: ${KIALI_SERVICE_ACCOUNT_TOKEN} # Optional. defaults false @@ -172,3 +137,9 @@ catalog: ```bash kubectl create token $KIALI_SERVICE_ACCOUNT ``` + +or if you installed kiali with the operator then execute + +```bash +export KIALI_SERVICE_ACCOUNT_TOKEN=$(kubectl describe secret $(kubectl get secret -n istio-system | grep kiali-service-account-token | cut -d" " -f1) -n istio-system | grep token: | cut -d ":" -f2 | sed 's/^ *//') +``` diff --git a/plugins/kiali/README.md b/plugins/kiali/README.md index c9c6bb095f..b1148c5795 100644 --- a/plugins/kiali/README.md +++ b/plugins/kiali/README.md @@ -78,7 +78,6 @@ The Kiali plugin has the following capabilities: ```console yarn workspace app add @janus-idp/backstage-plugin-kiali - yarn workspace app add @janus-idp/backstage-plugin-kiali-backend ``` 2. Enable the **Kiali** tab on the entity view page using the `packages/app/src/components/catalog/EntityPage.tsx` file: @@ -99,48 +98,7 @@ The Kiali plugin has the following capabilities: ); ``` -3. Create a file called `kiali.ts` inside `packages/backend/src/plugins/` and add the following: - -```ts -/* highlight-add-start */ -import { CatalogClient } from '@backstage/catalog-client'; - -import { Router } from 'express'; - -import { createRouter } from '@janus-idp/backstage-plugin-kiali-backend'; - -import { PluginEnvironment } from '../types'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - const catalogApi = new CatalogClient({ discoveryApi: env.discovery }); - return await createRouter({ - logger: env.logger, - catalogApi, - config: env.config, - }); -} -/* highlight-add-end */ -``` - -4. import the plugin to `packages/backend/src/index.ts`. There are three lines of code you'll need to add, and they should be added near similar code in your existing Backstage backend. - -```typescript title="packages/backend/src/index.ts" -// .. -/* highlight-add-next-line */ -import kiali from './plugins/kiali'; - -async function main() { - // ... - /* highlight-add-next-line */ - const kialiEnv = useHotMemoize(module, () => createEnv('kiali')); - // ... - /* highlight-add-next-line */ - apiRouter.use('/kiali', await kiali(kialiEnv)); -``` - -5. Configure you `app-config.yaml` with kiali configuration +3. Configure you `app-config.yaml` with kiali configuration ```yaml catalog: @@ -149,8 +107,6 @@ catalog: kiali: # Required. Kiali endpoint url: ${KIALI_ENDPOINT} - # Required. Kiali authentication. Supported anonymous and token - strategy: ${KIALI_AUTH_STRATEGY} # Optional. Required by token authentication serviceAccountToken: ${KIALI_SERVICE_ACCOUNT_TOKEN} # Optional. defaults false @@ -172,9 +128,8 @@ Authentication methods: The following table describes the parameters that you can configure to enable the plugin under `catalog.providers.keycloakOrg.` object in the `app-config.yaml` file: | Name | Description | Default Value | Required | -| --------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------- | --------------------------------------- | -| `url` | Location of the kIALI server, such as `https://localhost:4000` | "" | Yes | -| `strategy` | Authentication strategy. [Methods](https://kiali.io/docs/configuration/authentication/) | `anonymous` | Yes | +| --------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------- | --------------------------------------- | --- | +| `url` | Location of the kIALI server, such as `https://localhost:4000` | "" | Yes | | | `serviceAccountToken` | Service Account Token which is used for querying data from Kiali | "" | Yes if using token based authentication | | `skipTLSVerify` | Skip TLS certificate verification presented by the API server | false | No | | `caData` | Base64-encoded certificate authority bundle in PEM format | "" | No | diff --git a/plugins/kiali/catalog-demo.yaml b/plugins/kiali/catalog-demo.yaml new file mode 100644 index 0000000000..cc5ab01117 --- /dev/null +++ b/plugins/kiali/catalog-demo.yaml @@ -0,0 +1,16 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: istio + description: An example of a Kiali demo istio-system. + tags: + - istio + - kiali + - core + - servicemesh + annotations: + 'backstage.io/kubernetes-namespace': istio-system,bookinfo +spec: + type: service + lifecycle: production + owner: user:guest diff --git a/plugins/kiali/config.d.ts b/plugins/kiali/config.d.ts new file mode 100644 index 0000000000..24bd3590c7 --- /dev/null +++ b/plugins/kiali/config.d.ts @@ -0,0 +1,10 @@ +export interface Config { + /** Configurations for the Kiali plugin */ + kiali?: { + /** + * The token secret for the Kiali instance. + * @visibility frontend + */ + token?: string; + }; +} diff --git a/plugins/kiali/dev/__fixtures__/1-overview.json b/plugins/kiali/dev/__fixtures__/1-overview.json deleted file mode 100644 index c84e5c5862..0000000000 --- a/plugins/kiali/dev/__fixtures__/1-overview.json +++ /dev/null @@ -1,333 +0,0 @@ -{ - "namespaces": [ - { - "name": "bookinfo", - "cluster": "Kubernetes", - "isAmbient": false, - "labels": { - "istio-injection": "enabled", - "kubernetes.io/metadata.name": "bookinfo", - "pod-security.kubernetes.io/audit": "privileged", - "pod-security.kubernetes.io/audit-version": "v1.24", - "pod-security.kubernetes.io/warn": "privileged", - "pod-security.kubernetes.io/warn-version": "v1.24" - }, - "annotations": { - "openshift.io/description": "", - "openshift.io/display-name": "", - "openshift.io/requester": "kubeadmin", - "openshift.io/sa.scc.mcs": "s0:c26,c10", - "openshift.io/sa.scc.supplemental-groups": "1000670000/10000", - "openshift.io/sa.scc.uid-range": "1000670000/10000" - }, - "tlsStatus": { - "status": "MTLS_NOT_ENABLED", - "autoMTLSEnabled": true, - "minTLS": "" - }, - "validations": { "errors": 0, "objectCount": 2, "warnings": 0 }, - "metrics": [ - { - "labels": {}, - "datapoints": [ - [1693301460, "3.644444444444444"], - [1693301520, "3.866711113086507"], - [1693301580, "3.822222222222222"], - [1693301640, "3.666666666666666"], - [1693301700, "3.555347210480139"], - [1693301760, "3.733333333333333"], - [1693301820, "3.7110933341234214"], - [1693301880, "3.488888888888888"], - [1693301940, "3.6889170389137043"], - [1693302000, "3.6888888888888887"], - [1693302060, "3.688644504182928"] - ], - "name": "request_count" - } - ], - "errorMetrics": [ - { - "labels": {}, - "datapoints": [ - [1693301460, "0"], - [1693301520, "0"], - [1693301580, "0"], - [1693301640, "0"], - [1693301700, "0"], - [1693301760, "0"], - [1693301820, "0"], - [1693301880, "0"], - [1693301940, "0.02222222222222222"], - [1693302000, "0"], - [1693302060, "0"] - ], - "name": "request_error_count" - } - ], - "nsHealth": { - "details": { - "workloadStatuses": [ - { - "name": "details-v1", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": 1 - } - ], - "requests": { - "inbound": { "http": { "200": 0.9999999999999999 } }, - "outbound": {}, - "healthAnnotations": {} - } - }, - "kiali-traffic-generator": { - "workloadStatuses": [ - { - "name": "kiali-traffic-generator", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": 1 - } - ], - "requests": { "inbound": {}, "outbound": {}, "healthAnnotations": {} } - }, - "productpage": { - "workloadStatuses": [ - { - "name": "productpage-v1", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": 1 - } - ], - "requests": { - "inbound": { "http": { "200": 0.9999999999999999 } }, - "outbound": { "http": { "200": 2 } }, - "healthAnnotations": {} - } - }, - "ratings": { - "workloadStatuses": [ - { - "name": "ratings-v1", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": 1 - } - ], - "requests": { - "inbound": { - "http": { - "200": 0.6615384615384614, - "503": 0.0017094017094017092 - } - }, - "outbound": {}, - "healthAnnotations": {} - } - }, - "reviews": { - "workloadStatuses": [ - { - "name": "reviews-v1", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": 1 - }, - { - "name": "reviews-v2", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": 1 - }, - { - "name": "reviews-v3", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": 1 - } - ], - "requests": { - "inbound": { "http": { "200": 1.0017094017094017 } }, - "outbound": { "http": { "200": 0.6615384615384614 } }, - "healthAnnotations": {} - } - } - } - }, - { - "name": "istio-system", - "cluster": "Kubernetes", - "isAmbient": false, - "labels": { - "kubernetes.io/metadata.name": "istio-system", - "pod-security.kubernetes.io/audit": "baseline", - "pod-security.kubernetes.io/audit-version": "v1.24", - "pod-security.kubernetes.io/warn": "baseline", - "pod-security.kubernetes.io/warn-version": "v1.24", - "topology.istio.io/network": "" - }, - "annotations": { - "openshift.io/description": "", - "openshift.io/display-name": "", - "openshift.io/requester": "kubeadmin", - "openshift.io/sa.scc.mcs": "s0:c26,c0", - "openshift.io/sa.scc.supplemental-groups": "1000650000/10000", - "openshift.io/sa.scc.uid-range": "1000650000/10000" - }, - "tlsStatus": { - "status": "MTLS_NOT_ENABLED", - "autoMTLSEnabled": true, - "minTLS": "" - }, - "validations": { "errors": 0, "objectCount": 0, "warnings": 0 }, - "nsHealth": { - "grafana": { - "workloadStatuses": [ - { - "name": "grafana", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": -1 - } - ], - "requests": { "inbound": {}, "outbound": {}, "healthAnnotations": {} } - }, - "istio-egressgateway": { - "workloadStatuses": [ - { - "name": "istio-egressgateway", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": -1 - } - ], - "requests": { "inbound": {}, "outbound": {}, "healthAnnotations": {} } - }, - "istio-ingressgateway": { - "workloadStatuses": [ - { - "name": "istio-ingressgateway", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": -1 - } - ], - "requests": { "inbound": {}, "outbound": {}, "healthAnnotations": {} } - }, - "istiod": { - "workloadStatuses": [ - { - "name": "istiod", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": -1 - } - ], - "requests": { "inbound": {}, "outbound": {}, "healthAnnotations": {} } - }, - "jaeger": { - "workloadStatuses": [ - { - "name": "jaeger", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": -1 - } - ], - "requests": { "inbound": {}, "outbound": {}, "healthAnnotations": {} } - }, - "kiali": { - "workloadStatuses": [ - { - "name": "kiali", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": -1 - } - ], - "requests": { "inbound": {}, "outbound": {}, "healthAnnotations": {} } - }, - "prometheus": { - "workloadStatuses": [ - { - "name": "prometheus", - "desiredReplicas": 1, - "currentReplicas": 1, - "availableReplicas": 1, - "syncedProxies": -1 - } - ], - "requests": { "inbound": {}, "outbound": {}, "healthAnnotations": {} } - } - }, - "metrics": null, - "errorMetrics": null, - "controlPlaneMetrics": { - "istiod_proxy_time": [ - { - "labels": {}, - "datapoints": [ - [1693301460, "NaN"], - [1693301520, "NaN"], - [1693301580, "NaN"], - [1693301640, "NaN"], - [1693301700, "NaN"], - [1693301760, "NaN"], - [1693301820, "NaN"], - [1693301880, "NaN"], - [1693301940, "NaN"], - [1693302000, "NaN"], - [1693302060, "NaN"] - ], - "stat": "avg", - "name": "pilot_proxy_convergence_time" - } - ], - "istiod_cpu": [ - { - "labels": {}, - "datapoints": [ - [1693301460, "0.0011111111111110873"], - [1693301520, "0.0013333333333333047"], - [1693301580, "0.0011111111111111267"], - [1693301640, "0.0013333333333333441"], - [1693301700, "0.004444444444444428"], - [1693301760, "0.0013333333333333047"], - [1693301820, "0.0013333333333333047"], - [1693301880, "0.0013333333333333047"], - [1693301940, "0.0008888888888888698"], - [1693302000, "0.0015555555555555618"], - [1693302060, "0.0011107902161597918"] - ], - "name": "process_cpu_seconds_total" - } - ] - } - } - ], - "istiodResourceThresholds": { "memory": 0, "cpu": 0 }, - "outboundTraffic": { "mode": "ALLOW_ANY" }, - "canaryUpgrade": { - "currentVersion": "", - "upgradeVersion": "", - "migratedNamespaces": [], - "pendingNamespaces": [] - }, - "istioStatus": [ - { "name": "istiod-69744664c5-wtv8x", "status": "Healthy", "is_core": true } - ] -} diff --git a/plugins/kiali/dev/__fixtures__/config.json b/plugins/kiali/dev/__fixtures__/config.json deleted file mode 100644 index 48abef325b..0000000000 --- a/plugins/kiali/dev/__fixtures__/config.json +++ /dev/null @@ -1,195 +0,0 @@ -{ - "server": { - "accessibleNamespaces": ["**"], - "authStrategy": "anonymous", - "clusters": { - "Kubernetes": { - "apiEndpoint": "https://10.217.4.1:443", - "isKialiHome": true, - "kialiInstances": [ - { - "namespace": "istio-system", - "operatorResource": "kiali-operator/kiali", - "serviceName": "kiali", - "url": "https://kiali-istio-system.apps-crc.testing", - "version": "dev" - } - ], - "name": "Kubernetes", - "network": "", - "secretName": "" - } - }, - "deployment": {}, - "healthConfig": { - "rate": [ - { - "tolerance": [ - { - "code": "5XX", - "degraded": 0, - "failure": 10, - "protocol": "http", - "direction": ".*" - }, - { - "code": "4XX", - "degraded": 10, - "failure": 20, - "protocol": "http", - "direction": ".*" - }, - { - "code": "^[1-9]$|^1[0-6]$", - "degraded": 0, - "failure": 10, - "protocol": "grpc", - "direction": ".*" - }, - { - "code": "^-$", - "degraded": 0, - "failure": 10, - "protocol": "http|grpc", - "direction": ".*" - } - ] - }, - { - "tolerance": [ - { - "code": "5XX", - "degraded": 0, - "failure": 10, - "protocol": "http", - "direction": ".*" - }, - { - "code": "4XX", - "degraded": 10, - "failure": 20, - "protocol": "http", - "direction": ".*" - }, - { - "code": "^[1-9]$|^1[0-6]$", - "degraded": 0, - "failure": 10, - "protocol": "grpc", - "direction": ".*" - }, - { - "code": "^-$", - "degraded": 0, - "failure": 10, - "protocol": "http|grpc", - "direction": ".*" - } - ] - } - ] - }, - "istioAnnotations": { - "istioInjectionAnnotation": "sidecar.istio.io/inject" - }, - "istioCanaryRevision": {}, - "istioConfigMap": "istio", - "istioIdentityDomain": "svc.cluster.local", - "istioLabels": { - "appLabelName": "app", - "injectionLabelName": "istio-injection", - "injectionLabelRev": "istio.io/rev", - "versionLabelName": "version" - }, - "istioNamespace": "istio-system", - "istioStatusEnabled": true, - "kialiFeatureFlags": { - "certificatesInformationIndicators": { - "enabled": true, - "secrets": ["cacerts", "istio-ca-secret"] - }, - "clustering": { "enable_exec_provider": false }, - "istioAnnotationAction": true, - "istioInjectionAction": true, - "istioUpgradeAction": false, - "uiDefaults": { - "graph": { - "findOptions": [ - { - "description": "Find: slow edges (> 1s)", - "expression": "rt > 1000" - }, - { - "description": "Find: unhealthy nodes", - "expression": "! healthy" - }, - { - "description": "Find: unknown nodes", - "expression": "name = unknown" - }, - { - "description": "Find: nodes with the 2 top rankings", - "expression": "rank <= 2" - } - ], - "hideOptions": [ - { "description": "Hide: healthy nodes", "expression": "healthy" }, - { - "description": "Hide: unknown nodes", - "expression": "name = unknown" - }, - { - "description": "Hide: nodes ranked lower than the 2 top rankings", - "expression": "rank > 2" - } - ], - "impl": "cy", - "settings": { - "fontLabel": 13, - "minFontBadge": 7, - "minFontLabel": 10 - }, - "traffic": { "grpc": "requests", "http": "requests", "tcp": "sent" } - }, - "list": { - "includeHealth": true, - "includeIstioResources": true, - "includeValidations": true, - "showIncludeToggles": false - }, - "metricsPerRefresh": "1m", - "metricsInbound": {}, - "metricsOutbound": {}, - "refreshInterval": "60s" - }, - "validations": { - "ignore": ["KIA1301"], - "SkipWildcardGatewayHosts": false - } - }, - "logLevel": "trace", - "prometheus": { - "globalScrapeInterval": 15, - "storageTsdbRetention": 1296000 - } - }, - "kialiConsole": "https://kiali-istio-system.apps-crc.testing/", - "meshTLSStatus": { - "status": "MTLS_NOT_ENABLED", - "autoMTLSEnabled": true, - "minTLS": "N/A" - }, - "username": "anonymous", - "istioCerts": [ - { - "secretName": "istio-ca-secret", - "secretNamespace": "istio-system", - "dnsNames": null, - "issuer": "O=cluster.local", - "notBefore": "2023-08-28T06:39:18Z", - "notAfter": "2033-08-25T06:39:18Z", - "error": "", - "accessible": true - } - ] -} diff --git a/plugins/kiali/dev/__fixtures__/general/auth_info_anonymous.json b/plugins/kiali/dev/__fixtures__/general/auth_info_anonymous.json new file mode 100644 index 0000000000..b66d1554cf --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/general/auth_info_anonymous.json @@ -0,0 +1 @@ +{ "strategy": "anonymous", "sessionInfo": {} } diff --git a/plugins/kiali-backend/__fixtures__/data/config/anonymous_config.json b/plugins/kiali/dev/__fixtures__/general/config.json similarity index 86% rename from plugins/kiali-backend/__fixtures__/data/config/anonymous_config.json rename to plugins/kiali/dev/__fixtures__/general/config.json index ad45c6964d..48d358f71d 100644 --- a/plugins/kiali-backend/__fixtures__/data/config/anonymous_config.json +++ b/plugins/kiali/dev/__fixtures__/general/config.json @@ -1,8 +1,32 @@ { "accessibleNamespaces": ["**"], "authStrategy": "anonymous", - "clusterInfo": {}, + "ambientEnabled": true, + "clusters": { + "Kubernetes": { + "apiEndpoint": "https://10.217.4.1:443", + "isKialiHome": true, + "kialiInstances": [ + { + "namespace": "istio-system", + "operatorResource": "kiali-operator/kiali", + "serviceName": "kiali", + "url": "https://kiali-istio-system.apps-crc.testing", + "version": "dev" + } + ], + "name": "Kubernetes", + "network": "", + "secretName": "" + } + }, "deployment": {}, + "gatewayAPIClasses": [ + { + "name": "Istio", + "className": "istio" + } + ], "healthConfig": { "rate": [ { @@ -75,16 +99,16 @@ "istioInjectionAnnotation": "sidecar.istio.io/inject" }, "istioCanaryRevision": {}, - "istioStatusEnabled": true, + "istioConfigMap": "istio", "istioIdentityDomain": "svc.cluster.local", - "istioNamespace": "istio-system", "istioLabels": { "appLabelName": "app", "injectionLabelName": "istio-injection", "injectionLabelRev": "istio.io/rev", "versionLabelName": "version" }, - "istioConfigMap": "istio", + "istioNamespace": "istio-system", + "istioStatusEnabled": true, "kialiFeatureFlags": { "certificatesInformationIndicators": { "enabled": true, @@ -130,6 +154,7 @@ "expression": "rank \u003e 2" } ], + "impl": "cy", "settings": { "fontLabel": 13, "minFontBadge": 7, @@ -153,7 +178,7 @@ "refreshInterval": "60s" }, "validations": { - "ignore": ["KIA1301"], + "ignore": ["KIA1201"], "SkipWildcardGatewayHosts": false } }, diff --git a/plugins/kiali-backend/__fixtures__/data/config/istio_certs.json b/plugins/kiali/dev/__fixtures__/general/istioCertsInfo.json similarity index 69% rename from plugins/kiali-backend/__fixtures__/data/config/istio_certs.json rename to plugins/kiali/dev/__fixtures__/general/istioCertsInfo.json index 55fc76c280..eeda6f935b 100644 --- a/plugins/kiali-backend/__fixtures__/data/config/istio_certs.json +++ b/plugins/kiali/dev/__fixtures__/general/istioCertsInfo.json @@ -4,8 +4,8 @@ "secretNamespace": "istio-system", "dnsNames": null, "issuer": "O=cluster.local", - "notBefore": "2023-07-10T10:43:24Z", - "notAfter": "2033-07-07T10:43:24Z", + "notBefore": "2023-10-09T07:01:47Z", + "notAfter": "2033-10-06T07:01:47Z", "error": "", "accessible": true } diff --git a/plugins/kiali/dev/__fixtures__/general/istioConfig.json b/plugins/kiali/dev/__fixtures__/general/istioConfig.json new file mode 100644 index 0000000000..bdc9f0bd98 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/general/istioConfig.json @@ -0,0 +1,375 @@ +{ + "bookinfo": { + "namespace": { + "name": "bookinfo", + "cluster": "", + "isAmbient": false, + "labels": null, + "annotations": null + }, + "destinationRules": [], + "envoyFilters": [], + "gateways": [ + { + "kind": "Gateway", + "apiVersion": "networking.istio.io/v1alpha3", + "metadata": { + "name": "bookinfo-gateway", + "namespace": "bookinfo", + "resourceVersion": "30111", + "creationTimestamp": "2023-10-09T07:02:07Z", + "annotations": { + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"networking.istio.io/v1alpha3\",\"kind\":\"Gateway\",\"metadata\":{\"annotations\":{},\"name\":\"bookinfo-gateway\",\"namespace\":\"bookinfo\"},\"spec\":{\"selector\":{\"istio\":\"ingressgateway\"},\"servers\":[{\"hosts\":[\"*\"],\"port\":{\"name\":\"http\",\"number\":80,\"protocol\":\"HTTP\"}}]}}\n" + } + }, + "spec": { + "servers": [ + { + "port": { + "number": 80, + "protocol": "HTTP", + "name": "http" + }, + "hosts": ["*"] + } + ], + "selector": { + "istio": "ingressgateway" + } + }, + "status": {} + } + ], + "serviceEntries": [], + "sidecars": [], + "virtualServices": [ + { + "kind": "VirtualService", + "apiVersion": "networking.istio.io/v1alpha3", + "metadata": { + "name": "bookinfo", + "namespace": "bookinfo", + "resourceVersion": "30205", + "creationTimestamp": "2023-10-09T07:02:07Z", + "annotations": { + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"networking.istio.io/v1alpha3\",\"kind\":\"VirtualService\",\"metadata\":{\"annotations\":{},\"name\":\"bookinfo\",\"namespace\":\"bookinfo\"},\"spec\":{\"gateways\":[\"bookinfo-gateway\"],\"hosts\":[\"*\"],\"http\":[{\"match\":[{\"uri\":{\"exact\":\"/productpage\"}},{\"uri\":{\"prefix\":\"/static\"}},{\"uri\":{\"exact\":\"/login\"}},{\"uri\":{\"exact\":\"/logout\"}},{\"uri\":{\"prefix\":\"/api/v1/products\"}}],\"route\":[{\"destination\":{\"host\":\"productpage\",\"port\":{\"number\":9080}}}]}]}}\n" + } + }, + "spec": { + "hosts": ["istio-ingressgateway-istio-system.apps-crc.testing"], + "gateways": ["bookinfo-gateway"], + "http": [ + { + "match": [ + { + "uri": { + "exact": "/productpage" + } + }, + { + "uri": { + "prefix": "/static" + } + }, + { + "uri": { + "exact": "/login" + } + }, + { + "uri": { + "exact": "/logout" + } + }, + { + "uri": { + "prefix": "/api/v1/products" + } + } + ], + "route": [ + { + "destination": { + "host": "productpage", + "port": { + "number": 9080 + } + } + } + ] + } + ] + }, + "status": {} + } + ], + "workloadEntries": [], + "workloadGroups": [], + "wasmPlugins": [], + "telemetries": [], + "k8sGateways": [], + "k8sHTTPRoutes": [], + "authorizationPolicies": [], + "peerAuthentications": [], + "requestAuthentications": [], + "validations": {} + }, + "default": { + "namespace": { + "name": "default", + "cluster": "", + "isAmbient": false, + "labels": null, + "annotations": null + }, + "destinationRules": [], + "envoyFilters": [], + "gateways": [], + "serviceEntries": [], + "sidecars": [], + "virtualServices": [], + "workloadEntries": [], + "workloadGroups": [], + "wasmPlugins": [], + "telemetries": [], + "k8sGateways": [], + "k8sHTTPRoutes": [], + "authorizationPolicies": [], + "peerAuthentications": [], + "requestAuthentications": [], + "validations": {} + }, + "hostpath-provisioner": { + "namespace": { + "name": "hostpath-provisioner", + "cluster": "", + "isAmbient": false, + "labels": null, + "annotations": null + }, + "destinationRules": [], + "envoyFilters": [], + "gateways": [], + "serviceEntries": [], + "sidecars": [], + "virtualServices": [], + "workloadEntries": [], + "workloadGroups": [], + "wasmPlugins": [], + "telemetries": [], + "k8sGateways": [], + "k8sHTTPRoutes": [], + "authorizationPolicies": [], + "peerAuthentications": [], + "requestAuthentications": [], + "validations": {} + }, + "istio-system": { + "namespace": { + "name": "istio-system", + "cluster": "", + "isAmbient": false, + "labels": null, + "annotations": null + }, + "destinationRules": [], + "envoyFilters": [], + "gateways": [], + "serviceEntries": [], + "sidecars": [], + "virtualServices": [], + "workloadEntries": [], + "workloadGroups": [], + "wasmPlugins": [], + "telemetries": [], + "k8sGateways": [], + "k8sHTTPRoutes": [], + "authorizationPolicies": [], + "peerAuthentications": [], + "requestAuthentications": [], + "validations": {} + }, + "kiali": { + "namespace": { + "name": "kiali", + "cluster": "", + "isAmbient": false, + "labels": null, + "annotations": null + }, + "destinationRules": [], + "envoyFilters": [], + "gateways": [], + "serviceEntries": [], + "sidecars": [], + "virtualServices": [], + "workloadEntries": [], + "workloadGroups": [], + "wasmPlugins": [], + "telemetries": [], + "k8sGateways": [], + "k8sHTTPRoutes": [], + "authorizationPolicies": [], + "peerAuthentications": [], + "requestAuthentications": [], + "validations": {} + }, + "travel-agency": { + "namespace": { + "name": "travel-agency", + "cluster": "", + "isAmbient": false, + "labels": null, + "annotations": null + }, + "destinationRules": [ + { + "kind": "DestinationRule", + "apiVersion": "networking.istio.io/v1alpha3", + "metadata": { + "name": "travels", + "namespace": "travel-agency", + "resourceVersion": "79940", + "creationTimestamp": "2023-10-09T10:34:13Z", + "labels": { + "kiali_wizard": "request_routing" + } + }, + "spec": { + "host": "travels.travel-agency.svc.cluster.local", + "subsets": [ + { + "name": "v1", + "labels": { + "version": "v1" + } + }, + { + "name": "v2", + "labels": { + "version": "v2" + } + }, + { + "name": "v3", + "labels": { + "version": "v3" + } + } + ] + }, + "status": {} + } + ], + "envoyFilters": [], + "gateways": [], + "serviceEntries": [], + "sidecars": [], + "virtualServices": [ + { + "kind": "VirtualService", + "apiVersion": "networking.istio.io/v1alpha3", + "metadata": { + "name": "travels", + "namespace": "travel-agency", + "resourceVersion": "79939", + "creationTimestamp": "2023-10-09T10:34:13Z", + "labels": { + "kiali_wizard": "request_routing" + } + }, + "spec": { + "hosts": ["travels.travel-agency.svc.cluster.local"], + "http": [ + { + "route": [ + { + "destination": { + "host": "travels.travel-agency.svc.cluster.local", + "subset": "v1" + }, + "weight": 52 + }, + { + "destination": { + "host": "travels.travel-agency.svc.cluster.local", + "subset": "v2" + }, + "weight": 24 + }, + { + "destination": { + "host": "travels.travel-agency.svc.cluster.local", + "subset": "v3" + }, + "weight": 24 + } + ] + } + ] + }, + "status": {} + } + ], + "workloadEntries": [], + "workloadGroups": [], + "wasmPlugins": [], + "telemetries": [], + "k8sGateways": [], + "k8sHTTPRoutes": [], + "authorizationPolicies": [], + "peerAuthentications": [], + "requestAuthentications": [], + "validations": {} + }, + "travel-control": { + "namespace": { + "name": "travel-control", + "cluster": "", + "isAmbient": false, + "labels": null, + "annotations": null + }, + "destinationRules": [], + "envoyFilters": [], + "gateways": [], + "serviceEntries": [], + "sidecars": [], + "virtualServices": [], + "workloadEntries": [], + "workloadGroups": [], + "wasmPlugins": [], + "telemetries": [], + "k8sGateways": [], + "k8sHTTPRoutes": [], + "authorizationPolicies": [], + "peerAuthentications": [], + "requestAuthentications": [], + "validations": {} + }, + "travel-portal": { + "namespace": { + "name": "travel-portal", + "cluster": "", + "isAmbient": false, + "labels": null, + "annotations": null + }, + "destinationRules": [], + "envoyFilters": [], + "gateways": [], + "serviceEntries": [], + "sidecars": [], + "virtualServices": [], + "workloadEntries": [], + "workloadGroups": [], + "wasmPlugins": [], + "telemetries": [], + "k8sGateways": [], + "k8sHTTPRoutes": [], + "authorizationPolicies": [], + "peerAuthentications": [], + "requestAuthentications": [], + "validations": {} + } +} diff --git a/plugins/kiali/dev/__fixtures__/general/istioStatus.json b/plugins/kiali/dev/__fixtures__/general/istioStatus.json new file mode 100644 index 0000000000..accf21fb5c --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/general/istioStatus.json @@ -0,0 +1,7 @@ +[ + { "name": "istiod-7548d4ff85-fj8tb", "status": "Healthy", "is_core": true }, + { "name": "istiod-2", "status": "NotFound", "is_core": true }, + { "name": "istiod-3", "status": "Unhealthy", "is_core": true }, + { "name": "istiod-4", "status": "Unreachable", "is_core": true }, + { "name": "istiod-5", "status": "NotReady", "is_core": true } +] diff --git a/plugins/kiali/dev/__fixtures__/general/istioValidations.json b/plugins/kiali/dev/__fixtures__/general/istioValidations.json new file mode 100644 index 0000000000..2e03262db2 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/general/istioValidations.json @@ -0,0 +1,44 @@ +{ + "Kubernetes": { + "bookinfo": { + "errors": 1, + "objectCount": 2, + "warnings": 1 + }, + "default": { + "errors": 0, + "objectCount": 0, + "warnings": 0 + }, + "hostpath-provisioner": { + "errors": 0, + "objectCount": 0, + "warnings": 0 + }, + "istio-system": { + "errors": 0, + "objectCount": 0, + "warnings": 0 + }, + "kiali": { + "errors": 0, + "objectCount": 0, + "warnings": 0 + }, + "travel-agency": { + "errors": 0, + "objectCount": 2, + "warnings": 0 + }, + "travel-control": { + "errors": 0, + "objectCount": 0, + "warnings": 0 + }, + "travel-portal": { + "errors": 0, + "objectCount": 0, + "warnings": 0 + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/general/meshCanaryStatus.json b/plugins/kiali/dev/__fixtures__/general/meshCanaryStatus.json new file mode 100644 index 0000000000..013e5deacf --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/general/meshCanaryStatus.json @@ -0,0 +1,6 @@ +{ + "currentVersion": "1.3", + "upgradeVersion": "1.4", + "migratedNamespaces": ["bookinfo"], + "pendingNamespaces": ["travel-agency"] +} diff --git a/plugins/kiali/dev/__fixtures__/general/meshIstioResurceThresholds.json b/plugins/kiali/dev/__fixtures__/general/meshIstioResurceThresholds.json new file mode 100644 index 0000000000..87399806fe --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/general/meshIstioResurceThresholds.json @@ -0,0 +1 @@ +{ "memory": 64, "cpu": 8 } diff --git a/plugins/kiali-backend/__fixtures__/data/config/mesh_tls.json b/plugins/kiali/dev/__fixtures__/general/meshTls.json similarity index 100% rename from plugins/kiali-backend/__fixtures__/data/config/mesh_tls.json rename to plugins/kiali/dev/__fixtures__/general/meshTls.json diff --git a/plugins/kiali/dev/__fixtures__/general/namespaces.json b/plugins/kiali/dev/__fixtures__/general/namespaces.json new file mode 100644 index 0000000000..a1615edc99 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/general/namespaces.json @@ -0,0 +1,146 @@ +[ + { + "name": "bookinfo", + "cluster": "Kubernetes", + "isAmbient": false, + "labels": { + "istio-injection": "enabled", + "kubernetes.io/metadata.name": "bookinfo", + "pod-security.kubernetes.io/audit": "privileged", + "pod-security.kubernetes.io/audit-version": "v1.24", + "pod-security.kubernetes.io/warn": "privileged", + "pod-security.kubernetes.io/warn-version": "v1.24" + }, + "annotations": { + "openshift.io/description": "", + "openshift.io/display-name": "", + "openshift.io/requester": "kubeadmin", + "openshift.io/sa.scc.mcs": "s0:c26,c10", + "openshift.io/sa.scc.supplemental-groups": "1000670000/10000", + "openshift.io/sa.scc.uid-range": "1000670000/10000" + } + }, + { + "name": "default", + "cluster": "Kubernetes", + "isAmbient": false, + "labels": { + "kubernetes.io/metadata.name": "default" + }, + "annotations": { + "openshift.io/sa.scc.mcs": "s0:c1,c0", + "openshift.io/sa.scc.supplemental-groups": "1000000000/10000", + "openshift.io/sa.scc.uid-range": "1000000000/10000" + } + }, + { + "name": "hostpath-provisioner", + "cluster": "Kubernetes", + "isAmbient": false, + "labels": { + "kubernetes.io/metadata.name": "hostpath-provisioner", + "pod-security.kubernetes.io/audit": "privileged", + "pod-security.kubernetes.io/audit-version": "v1.24", + "pod-security.kubernetes.io/warn": "privileged", + "pod-security.kubernetes.io/warn-version": "v1.24" + }, + "annotations": { + "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"name\":\"hostpath-provisioner\"}}\n", + "openshift.io/sa.scc.mcs": "s0:c25,c20", + "openshift.io/sa.scc.supplemental-groups": "1000640000/10000", + "openshift.io/sa.scc.uid-range": "1000640000/10000" + } + }, + { + "name": "istio-system", + "cluster": "Kubernetes", + "isAmbient": false, + "labels": { + "kubernetes.io/metadata.name": "istio-system", + "pod-security.kubernetes.io/audit": "privileged", + "pod-security.kubernetes.io/audit-version": "v1.24", + "pod-security.kubernetes.io/warn": "privileged", + "pod-security.kubernetes.io/warn-version": "v1.24", + "topology.istio.io/network": "" + }, + "annotations": { + "openshift.io/description": "", + "openshift.io/display-name": "", + "openshift.io/requester": "kubeadmin", + "openshift.io/sa.scc.mcs": "s0:c26,c0", + "openshift.io/sa.scc.supplemental-groups": "1000650000/10000", + "openshift.io/sa.scc.uid-range": "1000650000/10000" + } + }, + { + "name": "kiali", + "cluster": "Kubernetes", + "isAmbient": false, + "labels": { + "kubernetes.io/metadata.name": "kiali", + "pod-security.kubernetes.io/audit": "restricted", + "pod-security.kubernetes.io/audit-version": "v1.24", + "pod-security.kubernetes.io/warn": "restricted", + "pod-security.kubernetes.io/warn-version": "v1.24" + }, + "annotations": { + "openshift.io/sa.scc.mcs": "s0:c27,c4", + "openshift.io/sa.scc.supplemental-groups": "1000710000/10000", + "openshift.io/sa.scc.uid-range": "1000710000/10000" + } + }, + { + "name": "travel-agency", + "cluster": "Kubernetes", + "isAmbient": false, + "labels": { + "istio-injection": "enabled", + "kubernetes.io/metadata.name": "travel-agency", + "pod-security.kubernetes.io/audit": "privileged", + "pod-security.kubernetes.io/audit-version": "v1.24", + "pod-security.kubernetes.io/warn": "privileged", + "pod-security.kubernetes.io/warn-version": "v1.24" + }, + "annotations": { + "openshift.io/sa.scc.mcs": "s0:c27,c14", + "openshift.io/sa.scc.supplemental-groups": "1000730000/10000", + "openshift.io/sa.scc.uid-range": "1000730000/10000" + } + }, + { + "name": "travel-control", + "cluster": "Kubernetes", + "isAmbient": false, + "labels": { + "istio-injection": "enabled", + "kubernetes.io/metadata.name": "travel-control", + "pod-security.kubernetes.io/audit": "privileged", + "pod-security.kubernetes.io/audit-version": "v1.24", + "pod-security.kubernetes.io/warn": "privileged", + "pod-security.kubernetes.io/warn-version": "v1.24" + }, + "annotations": { + "openshift.io/sa.scc.mcs": "s0:c27,c24", + "openshift.io/sa.scc.supplemental-groups": "1000750000/10000", + "openshift.io/sa.scc.uid-range": "1000750000/10000" + } + }, + { + "name": "travel-portal", + "cluster": "Kubernetes", + "isAmbient": false, + "labels": { + "istio-injection": "enabled", + "kubernetes.io/metadata.name": "travel-portal", + "pod-security.kubernetes.io/audit": "privileged", + "pod-security.kubernetes.io/audit-version": "v1.24", + "pod-security.kubernetes.io/warn": "privileged", + "pod-security.kubernetes.io/warn-version": "v1.24" + }, + "annotations": { + "openshift.io/sa.scc.mcs": "s0:c27,c19", + "openshift.io/sa.scc.supplemental-groups": "1000740000/10000", + "openshift.io/sa.scc.uid-range": "1000740000/10000" + } + } +] diff --git a/plugins/kiali/dev/__fixtures__/general/outbound_traffic_policy_mode.json b/plugins/kiali/dev/__fixtures__/general/outbound_traffic_policy_mode.json new file mode 100644 index 0000000000..b6f01c27d1 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/general/outbound_traffic_policy_mode.json @@ -0,0 +1 @@ +{ "mode": "ALLOW_ANY" } diff --git a/plugins/kiali/dev/__fixtures__/general/status.json b/plugins/kiali/dev/__fixtures__/general/status.json new file mode 100644 index 0000000000..56bb026b74 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/general/status.json @@ -0,0 +1,35 @@ +{ + "status": { + "Kiali commit hash": "c17d0550cfb033900c392ff5813368c1185954f1", + "Kiali container version": "v1.74.0-SNAPSHOT", + "Kiali state": "running", + "Kiali version": "v1.74.0-SNAPSHOT", + "Mesh name": "Istio", + "Mesh version": "1.18.2" + }, + "externalServices": [ + { + "name": "Istio", + "version": "1.18.2" + }, + { + "name": "Prometheus", + "version": "2.41.0" + }, + { + "name": "Kubernetes", + "version": "v1.26.3+b404935" + }, + { + "name": "Grafana" + }, + { + "name": "Jaeger" + } + ], + "warningMessages": [], + "istioEnvironment": { + "isMaistra": false, + "istioAPIEnabled": true + } +} diff --git a/plugins/kiali/dev/__fixtures__/index.ts b/plugins/kiali/dev/__fixtures__/index.ts new file mode 100644 index 0000000000..1d64a37ba2 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/index.ts @@ -0,0 +1,114 @@ +/* Config Data */ +import anonymousAuth from './general/auth_info_anonymous.json'; +import configData from './general/config.json'; +import istioCertsInfo from './general/istioCertsInfo.json'; +import istioConfig from './general/istioConfig.json'; +import istioStatus from './general/istioStatus.json'; +import istioValidations from './general/istioValidations.json'; +import meshCanaryStatus from './general/meshCanaryStatus.json'; +import meshIstioResourceThresholds from './general/meshIstioResurceThresholds.json'; +import meshTls from './general/meshTls.json'; +import namespacesData from './general/namespaces.json'; +import outboundTrafficPolicy from './general/outbound_traffic_policy_mode.json'; +import status from './general/status.json'; +/** health **/ + +import bookinfoHealthApp from './namespaces/bookinfo/health/app.json'; +import bookinfoHealthService from './namespaces/bookinfo/health/service.json'; +import bookinfoHealthWorkload from './namespaces/bookinfo/health/workload.json'; +import bookInfoMetrics from './namespaces/bookinfo/metrics'; +/* bookinfo */ +import bookinfoTls from './namespaces/bookinfo/tls.json'; +/** health **/ +import istioSystemHealthApp from './namespaces/istio-system/health/app.json'; +import istioSystemHealthService from './namespaces/istio-system/health/service.json'; +import istioSystemHealthWorkload from './namespaces/istio-system/health/workload.json'; +import istioSystemMetrics from './namespaces/istio-system/metrics'; +/* istio-system */ +import istioSystemTls from './namespaces/istio-system/tls.json'; +/** health **/ + +import travelAgencyHealthApp from './namespaces/travel-agency/health/app.json'; +import travelAgencyHealthService from './namespaces/travel-agency/health/service.json'; +import travelAgencyHealthWorkload from './namespaces/travel-agency/health/workload.json'; +import travelAgencyMetrics from './namespaces/travel-agency/metrics'; +/* Travel agency */ +import travelAgencyTls from './namespaces/travel-agency/tls.json'; +/** health **/ + +import travelControlHealthApp from './namespaces/travel-control/health/app.json'; +import travelControlHealthService from './namespaces/travel-control/health/service.json'; +import travelControlHealthWorkload from './namespaces/travel-control/health/workload.json'; +import travelControlMetrics from './namespaces/travel-control/metrics'; +/* Travel control */ +import travelControlTls from './namespaces/travel-control/tls.json'; +/** health **/ + +import travelPortalHealthApp from './namespaces/travel-portal/health/app.json'; +import travelPortalHealthService from './namespaces/travel-portal/health/service.json'; +import travelPortalHealthWorkload from './namespaces/travel-portal/health/workload.json'; +import travelPortalMetrics from './namespaces/travel-portal/metrics'; +/* Travel portal */ +import travelPortalTls from './namespaces/travel-portal/tls.json'; + +export const kialiData: { [index: string]: any } = { + auth: anonymousAuth, + config: configData, + namespaces: namespacesData, + meshTls: meshTls, + meshCanaryStatus: meshCanaryStatus, + meshIstioResourceThresholds: meshIstioResourceThresholds, + outboundTrafficPolicy: outboundTrafficPolicy, + istioValidations: istioValidations, + istioConfig: istioConfig, + istioStatus: istioStatus, + istioCertsInfo: istioCertsInfo, + namespacesData: { + 'istio-system': { + tls: istioSystemTls, + metrics: istioSystemMetrics, + health: { + app: istioSystemHealthApp, + service: istioSystemHealthService, + workload: istioSystemHealthWorkload, + }, + }, + bookinfo: { + tls: bookinfoTls, + metrics: bookInfoMetrics, + health: { + app: bookinfoHealthApp, + service: bookinfoHealthService, + workload: bookinfoHealthWorkload, + }, + }, + 'travel-control': { + tls: travelControlTls, + metrics: travelControlMetrics, + health: { + app: travelControlHealthApp, + service: travelControlHealthService, + workload: travelControlHealthWorkload, + }, + }, + 'travel-portal': { + tls: travelPortalTls, + metrics: travelPortalMetrics, + health: { + app: travelPortalHealthApp, + service: travelPortalHealthService, + workload: travelPortalHealthWorkload, + }, + }, + 'travel-agency': { + tls: travelAgencyTls, + metrics: travelAgencyMetrics, + health: { + app: travelAgencyHealthApp, + service: travelAgencyHealthService, + workload: travelAgencyHealthWorkload, + }, + }, + }, + status: status, +}; diff --git a/plugins/kiali/dev/__fixtures__/namespaces.json b/plugins/kiali/dev/__fixtures__/namespaces.json deleted file mode 100644 index fa2feaf36d..0000000000 --- a/plugins/kiali/dev/__fixtures__/namespaces.json +++ /dev/null @@ -1,44 +0,0 @@ -[ - { - "name": "bookinfo", - "cluster": "Kubernetes", - "isAmbient": false, - "labels": { - "istio-injection": "enabled", - "kubernetes.io/metadata.name": "bookinfo", - "pod-security.kubernetes.io/audit": "privileged", - "pod-security.kubernetes.io/audit-version": "v1.24", - "pod-security.kubernetes.io/warn": "privileged", - "pod-security.kubernetes.io/warn-version": "v1.24" - }, - "annotations": { - "openshift.io/description": "", - "openshift.io/display-name": "", - "openshift.io/requester": "kubeadmin", - "openshift.io/sa.scc.mcs": "s0:c26,c10", - "openshift.io/sa.scc.supplemental-groups": "1000670000/10000", - "openshift.io/sa.scc.uid-range": "1000670000/10000" - } - }, - { - "name": "istio-system", - "cluster": "Kubernetes", - "isAmbient": false, - "labels": { - "kubernetes.io/metadata.name": "istio-system", - "pod-security.kubernetes.io/audit": "baseline", - "pod-security.kubernetes.io/audit-version": "v1.24", - "pod-security.kubernetes.io/warn": "baseline", - "pod-security.kubernetes.io/warn-version": "v1.24", - "topology.istio.io/network": "" - }, - "annotations": { - "openshift.io/description": "", - "openshift.io/display-name": "", - "openshift.io/requester": "kubeadmin", - "openshift.io/sa.scc.mcs": "s0:c26,c0", - "openshift.io/sa.scc.supplemental-groups": "1000650000/10000", - "openshift.io/sa.scc.uid-range": "1000650000/10000" - } - } -] diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/health/app.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/health/app.json new file mode 100644 index 0000000000..9bd9fa35fb --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/health/app.json @@ -0,0 +1,120 @@ +{ + "details": { + "workloadStatuses": [ + { + "name": "details-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + } + ], + "requests": { + "inbound": { + "http": { + "200": 0.9999999999999999 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "kiali-traffic-generator": { + "workloadStatuses": [ + { + "name": "kiali-traffic-generator", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + } + ], + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "productpage": { + "workloadStatuses": [ + { + "name": "productpage-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + } + ], + "requests": { + "inbound": { + "http": { + "200": 0.9999999999999999 + } + }, + "outbound": { + "http": { + "200": 1.9999999999999998 + } + }, + "healthAnnotations": {} + } + }, + "ratings": { + "workloadStatuses": [ + { + "name": "ratings-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + } + ], + "requests": { + "inbound": { + "http": { + "200": 0.711111111111111 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "reviews": { + "workloadStatuses": [ + { + "name": "reviews-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + { + "name": "reviews-v2", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + { + "name": "reviews-v3", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + } + ], + "requests": { + "inbound": { + "http": { + "200": 0.9999999999999999 + } + }, + "outbound": { + "http": { + "200": 0.711111111111111 + } + }, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/health/service.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/health/service.json new file mode 100644 index 0000000000..6da4f68dbb --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/health/service.json @@ -0,0 +1,46 @@ +{ + "details": { + "requests": { + "inbound": { + "http": { + "200": 0.9999999999999999 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "productpage": { + "requests": { + "inbound": { + "http": { + "200": 0.9999999999999999 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "ratings": { + "requests": { + "inbound": { + "http": { + "200": 0.7555555555555555 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "reviews": { + "requests": { + "inbound": { + "http": { + "200": 1 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/health/workload.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/health/workload.json new file mode 100644 index 0000000000..12af3ccd76 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/health/workload.json @@ -0,0 +1,136 @@ +{ + "details-v1": { + "workloadStatus": { + "name": "details-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.9999999999999999 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "kiali-traffic-generator": { + "workloadStatus": { + "name": "kiali-traffic-generator", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "productpage-v1": { + "workloadStatus": { + "name": "productpage-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.9999999999999999 + } + }, + "outbound": { + "http": { + "200": 2 + } + }, + "healthAnnotations": {} + } + }, + "ratings-v1": { + "workloadStatus": { + "name": "ratings-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.6666666666666665 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "reviews-v1": { + "workloadStatus": { + "name": "reviews-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.3333333333333333 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "reviews-v2": { + "workloadStatus": { + "name": "reviews-v2", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.3777777777777777 + } + }, + "outbound": { + "http": { + "200": 0.3777777777777777 + } + }, + "healthAnnotations": {} + } + }, + "reviews-v3": { + "workloadStatus": { + "name": "reviews-v3", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.3555555555555555 + } + }, + "outbound": { + "http": { + "200": 0.2444444444444444 + } + }, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_120.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_120.json new file mode 100644 index 0000000000..56ae0787f5 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_120.json @@ -0,0 +1,28 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023800, "3.466666666666667"], + [1697023830, "3.399800039992002"], + [1697023860, "3.2664801740597667"], + [1697023890, "3.533333333333333"], + [1697023920, "3.866666666666667"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697023800, "0"], + [1697023830, "0"], + [1697023860, "0"], + [1697023890, "0"], + [1697023920, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_1800.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_1800.json new file mode 100644 index 0000000000..64876a240a --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_1800.json @@ -0,0 +1,40 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697022180, "3.6605924340032585"], + [1697022360, "3.672727272727272"], + [1697022540, "3.6606060606060598"], + [1697022720, "3.6666666666666656"], + [1697022900, "3.6606060606060598"], + [1697023080, "3.7515151515151506"], + [1697023260, "3.642218224270407"], + [1697023440, "3.6424242424242417"], + [1697023620, "3.7272727272727266"], + [1697023800, "3.636363636363636"], + [1697023980, "3.6363636363636362"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697022180, "0"], + [1697022360, "0"], + [1697022540, "0"], + [1697022720, "0"], + [1697022900, "0"], + [1697023080, "0"], + [1697023260, "0"], + [1697023440, "0"], + [1697023620, "0"], + [1697023800, "0"], + [1697023980, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_300.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_300.json new file mode 100644 index 0000000000..3b20582b5c --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_300.json @@ -0,0 +1,914 @@ +{ + "grpc_received": null, + "grpc_sent": null, + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1696410795, "3.577777777777777"], + [1696410810, "3.622222222222221"], + [1696410825, "3.599999999999999"], + [1696410840, "3.5999999999999996"], + [1696410855, "3.5111111111111106"], + [1696410870, "3.4666666666666663"], + [1696410885, "3.5333333333333328"], + [1696410900, "3.5111111111111106"], + [1696410915, "3.555555555555555"], + [1696410930, "3.621711372212227"], + [1696410945, "3.7333333333333325"], + [1696410960, "3.6888888888888887"], + [1696410975, "3.622733594701489"], + [1696410990, "3.5554084154912404"], + [1696411005, "3.577777777777777"], + [1696411020, "3.6222222222222222"], + [1696411035, "3.622397558974338"], + [1696411050, "3.666666666666666"], + [1696411065, "3.0355833333333333"], + [1696411080, "1.9189166666666662"], + [1696411095, "0.5111111111111111"], + [1696411110, "0"], + [1696411125, "0"], + [1696411140, "0"], + [1696411155, "0"], + [1696411170, "0"], + [1696411185, "0"], + [1696411200, "0"], + [1696411215, "0"], + [1696411230, "0"], + [1696411245, "0"], + [1696411260, "0"], + [1696411275, "0"], + [1696411290, "0"], + [1696411305, "0"], + [1696411320, "0"], + [1696411335, "0"], + [1696411350, "0"], + [1696411365, "0"], + [1696411380, "0"], + [1696411395, "0.5777777777777777"], + [1696411410, "1.8667499999999997"], + [1696411425, "3.0945277777777775"], + [1696411440, "3.7223055555555553"], + [1696411455, "3.844444444444444"], + [1696411470, "3.7777777777777772"], + [1696411485, "3.7111111111111104"], + [1696411500, "3.733333333333333"], + [1696411515, "3.688888888888888"], + [1696411530, "3.666666666666666"], + [1696411545, "3.6222222222222222"], + [1696411560, "3.6887333575271"], + [1696411575, "3.733333333333333"], + [1696411590, "3.7777777777777777"], + [1696411605, "3.644600024201295"], + [1696411620, "3.64440000197522"], + [1696411635, "3.577777777777777"], + [1696411650, "3.7111111111111112"], + [1696411665, "3.6667111130865067"], + [1696411680, "3.7555555555555555"], + [1696411695, "3.7111111111111104"], + [1696411710, "3.7111111111111112"], + [1696411725, "3.622133337283775"], + [1696411740, "3.6"], + [1696411755, "3.644444444444444"], + [1696411770, "3.6889777817285703"], + [1696411785, "3.7777284005480873"], + [1696411800, "3.8222222222222215"], + [1696411815, "3.7555555555555546"], + [1696411830, "3.6661952130599573"], + [1696411845, "3.622222222222222"], + [1696411860, "3.666666666666666"], + [1696411875, "3.711600148202358"], + [1696411890, "3.644444444444444"], + [1696411905, "3.644444444444444"], + [1696411920, "3.622222222222222"], + [1696411935, "3.7111111111111112"], + [1696411950, "3.533333333333333"], + [1696411965, "3.533333333333333"], + [1696411980, "3.5331555713566205"], + [1696411995, "3.733333333333333"], + [1696412010, "3.622222222222222"], + [1696412025, "3.622400015803874"], + [1696412040, "3.622222222222222"], + [1696412055, "3.7111111111111112"], + [1696412070, "3.666666666666666"], + [1696412085, "3.666666666666666"], + [1696412100, "3.644311119999408"], + [1696412115, "3.6666666666666665"], + [1696412130, "3.5777185290516256"], + [1696412145, "3.577911120000592"], + [1696412160, "3.599999999999999"], + [1696412175, "3.6222814920183337"], + [1696412190, "3.6444128423152504"], + [1696412205, "3.5111111111111106"], + [1696412220, "3.621333728219557"], + [1696412235, "3.64446419928685"], + [1696412250, "3.688888888888888"], + [1696412265, "3.6008892841262776"], + [1696412280, "3.555555555555555"], + [1696412295, "3.555555555555555"], + [1696412310, "3.5555555555555554"], + [1696412325, "3.644444444444444"], + [1696412340, "3.6888888888888887"], + [1696412355, "3.711111111111111"], + [1696412370, "3.7111111111111112"], + [1696412385, "3.666666666666666"], + [1696412400, "3.555555555555555"], + [1696412415, "3.5333333333333328"], + [1696412430, "3.5555111130863324"], + [1696412445, "3.6666666666666665"], + [1696412460, "3.7111111111111112"], + [1696412475, "3.755600001975396"], + [1696412490, "3.8000000000000003"], + [1696412505, "3.7777777777777772"], + [1696412520, "3.7999999999999994"], + [1696412535, "3.8444444444444446"], + [1696412550, "3.688888888888888"], + [1696412565, "3.644444444444444"], + [1696412580, "3.5555555555555554"], + [1696412595, "3.6"] + ], + "name": "request_count" + } + ], + "request_duration_millis": [ + { + "labels": {}, + "datapoints": [ + [1696410795, "7.5645962732919285"], + [1696410810, "7.019631901840506"], + [1696410825, "6.782716049382715"], + [1696410840, "6.498765432098765"], + [1696410855, "6.617088607594929"], + [1696410870, "6.762025316455705"], + [1696410885, "7.118867924528306"], + [1696410900, "7.021698113207562"], + [1696410915, "7.2767080745341595"], + [1696410930, "8.127719843059305"], + [1696410945, "8.459821428571418"], + [1696410960, "8.162195121951203"], + [1696410975, "7.567245817974092"], + [1696410990, "7.407068616263373"], + [1696411005, "8.43788819875777"], + [1696411020, "8.077914110429436"], + [1696411035, "8.08794526421048"], + [1696411050, "7.014759036144582"], + [1696411065, "6.607978236324356"], + [1696411080, "6.655912886939783"], + [1696411095, "2.7642857142856845"], + [1696411110, "NaN"], + [1696411125, "NaN"], + [1696411140, "NaN"], + [1696411155, "NaN"], + [1696411170, "NaN"], + [1696411185, "NaN"], + [1696411200, "NaN"], + [1696411215, "NaN"], + [1696411230, "NaN"], + [1696411245, "NaN"], + [1696411260, "NaN"], + [1696411275, "NaN"], + [1696411290, "NaN"], + [1696411305, "NaN"], + [1696411320, "NaN"], + [1696411335, "NaN"], + [1696411350, "NaN"], + [1696411365, "NaN"], + [1696411380, "NaN"], + [1696411395, "3.8761904761905015"], + [1696411410, "6.452448459725035"], + [1696411425, "5.9819901137018965"], + [1696411440, "6.213269220663208"], + [1696411455, "6.192774566473981"], + [1696411470, "6.533235294117629"], + [1696411485, "6.437425149700596"], + [1696411500, "6.775449101796406"], + [1696411515, "6.425449101796422"], + [1696411530, "7.216265060240964"], + [1696411545, "7.5265243902439165"], + [1696411560, "7.541374007531274"], + [1696411575, "6.799999999999992"], + [1696411590, "6.236011904761901"], + [1696411605, "6.2989043693660625"], + [1696411620, "6.499256365445137"], + [1696411635, "6.71073619631903"], + [1696411650, "7.01190476190475"], + [1696411665, "6.77995647248545"], + [1696411680, "7.267857142857117"], + [1696411695, "7.066265060240969"], + [1696411710, "7.394910179640704"], + [1696411725, "6.774941057751279"], + [1696411740, "6.828703703703713"], + [1696411755, "6.501552795031084"], + [1696411770, "7.861713569971116"], + [1696411785, "8.253635670380952"], + [1696411800, "9.162865497076009"], + [1696411815, "8.881764705882352"], + [1696411830, "8.529558572626945"], + [1696411845, "8.622256097560962"], + [1696411860, "7.677743902439009"], + [1696411875, "7.6418207924871995"], + [1696411890, "6.469090909090909"], + [1696411905, "6.387575757575752"], + [1696411920, "6.352147239263806"], + [1696411935, "6.634226190476188"], + [1696411950, "7.04748427672957"], + [1696411965, "7.104088050314491"], + [1696411980, "7.197714394440217"], + [1696411995, "6.841964285714277"], + [1696412010, "6.800304878048771"], + [1696412025, "6.63219087137394"], + [1696412040, "7.066564417177924"], + [1696412055, "7.158035714285704"], + [1696412070, "7.208928571428565"], + [1696412085, "6.9175757575757615"], + [1696412100, "6.680204190222556"], + [1696412115, "6.60304878048782"], + [1696412130, "7.147589279961249"], + [1696412145, "7.331397269920375"], + [1696412160, "7.555864197530868"], + [1696412175, "7.3379350122773825"], + [1696412190, "7.111091974580902"], + [1696412205, "7.103124999999996"], + [1696412220, "6.397247694068532"], + [1696412235, "6.805354054492854"], + [1696412250, "6.502727272727262"], + [1696412265, "6.650858726071548"], + [1696412280, "6.441509433962276"], + [1696412295, "6.476562500000013"], + [1696412310, "7.179754601226991"], + [1696412325, "6.864329268292677"], + [1696412340, "6.934848484848462"], + [1696412355, "6.306707317073169"], + [1696412370, "6.648181818181811"], + [1696412385, "6.394879518072293"], + [1696412400, "6.37331288343559"], + [1696412415, "6.716250000000013"], + [1696412430, "7.006688978351573"], + [1696412445, "7.872392638036815"], + [1696412460, "7.588757396449705"], + [1696412475, "7.960641995561795"], + [1696412490, "7.024418604651141"], + [1696412505, "6.798214285714275"], + [1696412520, "6.709826589595367"], + [1696412535, "6.770175438596499"], + [1696412550, "6.709281437125758"], + [1696412565, "6.748765432098778"], + [1696412580, "6.945652173913059"], + [1696412595, "6.937037037037037"] + ], + "stat": "avg", + "name": "request_duration_millis" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1696410795, "0"], + [1696410810, "0"], + [1696410825, "0"], + [1696410840, "0"], + [1696410855, "0"], + [1696410870, "0"], + [1696410885, "0"], + [1696410900, "0"], + [1696410915, "0"], + [1696410930, "0"], + [1696410945, "0"], + [1696410960, "0"], + [1696410975, "0"], + [1696410990, "0"], + [1696411005, "0"], + [1696411020, "0"], + [1696411035, "0"], + [1696411050, "0"], + [1696411065, "0"], + [1696411080, "0"], + [1696411095, "0"], + [1696411110, "0"], + [1696411125, "0"], + [1696411140, "0"], + [1696411155, "0"], + [1696411170, "0"], + [1696411185, "0"], + [1696411200, "0"], + [1696411215, "0"], + [1696411230, "0"], + [1696411245, "0"], + [1696411260, "0"], + [1696411275, "0"], + [1696411290, "0"], + [1696411305, "0"], + [1696411320, "0"], + [1696411335, "0"], + [1696411350, "0"], + [1696411365, "0"], + [1696411380, "0"], + [1696411395, "0"], + [1696411410, "0"], + [1696411425, "0"], + [1696411440, "0"], + [1696411455, "0"], + [1696411470, "0"], + [1696411485, "0"], + [1696411500, "0"], + [1696411515, "0"], + [1696411530, "0"], + [1696411545, "0"], + [1696411560, "0"], + [1696411575, "0"], + [1696411590, "0"], + [1696411605, "0"], + [1696411620, "0"], + [1696411635, "0"], + [1696411650, "0"], + [1696411665, "0"], + [1696411680, "0"], + [1696411695, "0"], + [1696411710, "0"], + [1696411725, "0"], + [1696411740, "0"], + [1696411755, "0"], + [1696411770, "0"], + [1696411785, "0"], + [1696411800, "0"], + [1696411815, "0"], + [1696411830, "0"], + [1696411845, "0"], + [1696411860, "0"], + [1696411875, "0"], + [1696411890, "0"], + [1696411905, "0"], + [1696411920, "0"], + [1696411935, "0"], + [1696411950, "0"], + [1696411965, "0"], + [1696411980, "0"], + [1696411995, "0"], + [1696412010, "0"], + [1696412025, "0"], + [1696412040, "0"], + [1696412055, "0"], + [1696412070, "0"], + [1696412085, "0"], + [1696412100, "0"], + [1696412115, "0"], + [1696412130, "0"], + [1696412145, "0"], + [1696412160, "0"], + [1696412175, "0"], + [1696412190, "0"], + [1696412205, "0"], + [1696412220, "0"], + [1696412235, "0"], + [1696412250, "0"], + [1696412265, "0"], + [1696412280, "0"], + [1696412295, "0"], + [1696412310, "0"], + [1696412325, "0"], + [1696412340, "0"], + [1696412355, "0"], + [1696412370, "0"], + [1696412385, "0"], + [1696412400, "0"], + [1696412415, "0"], + [1696412430, "0"], + [1696412445, "0"], + [1696412460, "0"], + [1696412475, "0"], + [1696412490, "0"], + [1696412505, "0"], + [1696412520, "0"], + [1696412535, "0"], + [1696412550, "0"], + [1696412565, "0"], + [1696412580, "0"], + [1696412595, "0"] + ], + "name": "request_error_count" + } + ], + "request_size": [ + { + "labels": {}, + "datapoints": [ + [1696410795, "279.4099378881988"], + [1696410810, "280.33742331288346"], + [1696410825, "279.99999999999994"], + [1696410840, "280.00000000000006"], + [1696410855, "277.9746835443038"], + [1696410870, "277.9746835443038"], + [1696410885, "278.45911949685535"], + [1696410900, "278.5849056603774"], + [1696410915, "279.53416149068323"], + [1696410930, "280.13979544724987"], + [1696410945, "282.79761904761904"], + [1696410960, "281.0365853658537"], + [1696410975, "281.2262147276294"], + [1696410990, "279.4102849337094"], + [1696411005, "279.9068322981367"], + [1696411020, "280.8282208588957"], + [1696411035, "279.9067354332076"], + [1696411050, "281.6867469879518"], + [1696411065, "285.3403241436331"], + [1696411080, "285.0850015565572"], + [1696411095, "325.71428571428567"], + [1696411110, "NaN"], + [1696411125, "NaN"], + [1696411140, "NaN"], + [1696411155, "NaN"], + [1696411170, "NaN"], + [1696411185, "NaN"], + [1696411200, "NaN"], + [1696411215, "NaN"], + [1696411230, "NaN"], + [1696411245, "NaN"], + [1696411260, "NaN"], + [1696411275, "NaN"], + [1696411290, "NaN"], + [1696411305, "NaN"], + [1696411320, "NaN"], + [1696411335, "NaN"], + [1696411350, "NaN"], + [1696411365, "NaN"], + [1696411380, "NaN"], + [1696411395, "324.52380952380946"], + [1696411410, "287.3358068446118"], + [1696411425, "289.0796102189919"], + [1696411440, "286.4486910955459"], + [1696411455, "284.53757225433526"], + [1696411470, "283.52941176470586"], + [1696411485, "282.00598802395206"], + [1696411500, "281.8862275449102"], + [1696411515, "281.76646706586826"], + [1696411530, "281.4457831325301"], + [1696411545, "280.67073170731703"], + [1696411560, "282.60971940114854"], + [1696411575, "282.7245508982036"], + [1696411590, "282.79761904761904"], + [1696411605, "279.6246759409596"], + [1696411620, "280.30628416048376"], + [1696411635, "280.21472392638043"], + [1696411650, "282.3214285714285"], + [1696411665, "281.68534107798405"], + [1696411680, "282.55952380952374"], + [1696411695, "281.92771084337346"], + [1696411710, "282.2455089820359"], + [1696411725, "280.70465809405835"], + [1696411740, "280.37037037037044"], + [1696411755, "280.27950310559004"], + [1696411770, "281.7281009043954"], + [1696411785, "283.1056240344476"], + [1696411800, "283.4795321637427"], + [1696411815, "283.17647058823525"], + [1696411830, "282.0170789560339"], + [1696411845, "280.6707317073171"], + [1696411860, "280.4268292682927"], + [1696411875, "281.3145869262265"], + [1696411890, "280.8787878787879"], + [1696411905, "281"], + [1696411920, "279.9693251533742"], + [1696411935, "282.32142857142856"], + [1696411950, "278.5849056603774"], + [1696411965, "278.58490566037733"], + [1696411980, "278.9356747237607"], + [1696411995, "282.32142857142856"], + [1696412010, "280.67073170731703"], + [1696412025, "278.58673793706083"], + [1696412040, "280.7055214723926"], + [1696412055, "282.9166666666667"], + [1696412070, "283.0357142857143"], + [1696412085, "281.6060606060606"], + [1696412100, "280.5815225148697"], + [1696412115, "280.9146341463414"], + [1696412130, "278.8113150533358"], + [1696412145, "279.0638643627106"], + [1696412160, "280.00000000000006"], + [1696412175, "280.4613205458113"], + [1696412190, "280.58222431127575"], + [1696412205, "278.93749999999994"], + [1696412220, "281.23413451827906"], + [1696412235, "281.886673285088"], + [1696412250, "281.24242424242425"], + [1696412265, "278.59406845764806"], + [1696412280, "278.45911949685535"], + [1696412295, "278.9375"], + [1696412310, "280.2147239263804"], + [1696412325, "280.5487804878049"], + [1696412340, "280.75757575757575"], + [1696412355, "280.3048780487805"], + [1696412370, "280.8787878787878"], + [1696412385, "281.4457831325301"], + [1696412400, "280.0920245398773"], + [1696412415, "279.06250000000006"], + [1696412430, "279.53558422973896"], + [1696412445, "280.58282208588963"], + [1696412460, "282.7514792899408"], + [1696412475, "281.7650686196597"], + [1696412490, "283.7790697674418"], + [1696412505, "282.2023809523809"], + [1696412520, "284.42196531791905"], + [1696412535, "283.59649122807014"], + [1696412550, "282.4850299401198"], + [1696412565, "280.37037037037044"], + [1696412580, "280.03105590062114"], + [1696412595, "279.99999999999994"] + ], + "stat": "avg", + "name": "request_size" + } + ], + "request_throughput": [ + { + "labels": {}, + "datapoints": [ + [1696410795, "999.6666666666665"], + [1696410810, "1015.4444444444443"], + [1696410825, "1007.9999999999999"], + [1696410840, "1007.9999999999999"], + [1696410855, "975.9999999999999"], + [1696410870, "975.9999999999999"], + [1696410885, "983.8888888888887"], + [1696410900, "984.3333333333333"], + [1696410915, "1000.111111111111"], + [1696410930, "1008.3601541927952"], + [1696410945, "1055.7777777777776"], + [1696410960, "1024.2222222222222"], + [1696410975, "1031.3065986813012"], + [1696410990, "999.6252784577467"], + [1696411005, "1001.4444444444443"], + [1696411020, "1017.2222222222221"], + [1696411035, "1001.4901341155481"], + [1696411050, "1039.1111111111109"], + [1696411065, "891.5379166666665"], + [1696411080, "585.0656944444444"], + [1696411095, "202.66666666666663"], + [1696411110, "0"], + [1696411125, "0"], + [1696411140, "0"], + [1696411155, "0"], + [1696411170, "0"], + [1696411185, "0"], + [1696411200, "0"], + [1696411215, "0"], + [1696411230, "0"], + [1696411245, "0"], + [1696411260, "0"], + [1696411275, "0"], + [1696411290, "0"], + [1696411305, "0"], + [1696411320, "0"], + [1696411335, "0"], + [1696411350, "0"], + [1696411365, "0"], + [1696411380, "0"], + [1696411395, "151.44444444444443"], + [1696411410, "504.4579166666666"], + [1696411425, "849.5969444444444"], + [1696411440, "1059.8840277777776"], + [1696411455, "1093.8888888888887"], + [1696411470, "1071.1111111111109"], + [1696411485, "1046.5555555555554"], + [1696411500, "1046.111111111111"], + [1696411515, "1045.6666666666665"], + [1696411530, "1038.2222222222222"], + [1696411545, "1022.8888888888888"], + [1696411560, "1048.7521151030826"], + [1696411575, "1049.2222222222222"], + [1696411590, "1055.7777777777776"], + [1696411605, "1006.692337326547"], + [1696411620, "1021.5482225481336"], + [1696411635, "1014.9999999999999"], + [1696411650, "1053.9999999999998"], + [1696411665, "1039.1184447703847"], + [1696411680, "1054.8888888888887"], + [1696411695, "1039.9999999999998"], + [1696411710, "1047.4444444444443"], + [1696411725, "1016.7497000133326"], + [1696411740, "1009.3333333333333"], + [1696411755, "1002.7777777777776"], + [1696411770, "1033.0280802603572"], + [1696411785, "1063.2056191287388"], + [1696411800, "1077.2222222222222"], + [1696411815, "1069.7777777777776"], + [1696411830, "1046.4651500995017"], + [1696411845, "1022.8888888888888"], + [1696411860, "1021.9999999999999"], + [1696411875, "1037.8754104717032"], + [1696411890, "1029.8888888888887"], + [1696411905, "1030.3333333333333"], + [1696411920, "1014.111111111111"], + [1696411935, "1054"], + [1696411950, "984.3333333333333"], + [1696411965, "984.3333333333333"], + [1696411980, "991.7217037497902"], + [1696411995, "1054"], + [1696412010, "1022.8888888888887"], + [1696412025, "984.3893383115535"], + [1696412040, "1016.7777777777776"], + [1696412055, "1056.2222222222222"], + [1696412070, "1056.6666666666665"], + [1696412085, "1032.5555555555554"], + [1696412100, "1016.2912176225288"], + [1696412115, "1023.7777777777776"], + [1696412130, "991.3137022554014"], + [1696412145, "992.264284285619"], + [1696412160, "1007.9999999999999"], + [1696412175, "1015.9098506401136"], + [1696412190, "1016.3228552523725"], + [1696412205, "991.7777777777776"], + [1696412220, "1030.941951725159"], + [1696412235, "1046.1194476546061"], + [1696412250, "1031.2222222222222"], + [1696412265, "984.613457833111"], + [1696412280, "983.8888888888887"], + [1696412295, "991.7777777777776"], + [1696412310, "1014.9999999999999"], + [1696412325, "1022.4444444444443"], + [1696412340, "1029.4444444444443"], + [1696412355, "1021.5555555555554"], + [1696412370, "1029.8888888888887"], + [1696412385, "1038.2222222222222"], + [1696412400, "1014.5555555555554"], + [1696412415, "992.2222222222222"], + [1696412430, "1000.1037781036893"], + [1696412445, "1016.3333333333333"], + [1696412460, "1061.8888888888887"], + [1696412475, "1045.6740003259401"], + [1696412490, "1084.6666666666665"], + [1696412505, "1053.5555555555554"], + [1696412520, "1093.4444444444443"], + [1696412535, "1077.6666666666665"], + [1696412550, "1048.3333333333333"], + [1696412565, "1009.3333333333333"], + [1696412580, "1001.8888888888888"], + [1696412595, "1007.9999999999999"] + ], + "name": "request_throughput" + } + ], + "response_size": [ + { + "labels": {}, + "datapoints": [ + [1696410795, "1741.1180124223602"], + [1696410810, "1730.1226993865032"], + [1696410825, "1732.3148148148143"], + [1696410840, "1737.9320987654323"], + [1696410855, "1755.7278481012659"], + [1696410870, "1736.6139240506334"], + [1696410885, "1734.4025157232707"], + [1696410900, "1740.1257861635222"], + [1696410915, "1720.8695652173915"], + [1696410930, "1731.7680297986026"], + [1696410945, "1698.6607142857142"], + [1696410960, "1746.25"], + [1696410975, "1730.4287021168816"], + [1696410990, "1733.7618095304606"], + [1696411005, "1734.8447204968948"], + [1696411020, "1717.484662576687"], + [1696411035, "1761.7615043666383"], + [1696411050, "1715.2710843373495"], + [1696411065, "1589.3159733643906"], + [1696411080, "1608.4669942204355"], + [1696411095, "413.21428571428567"], + [1696411110, "NaN"], + [1696411125, "NaN"], + [1696411140, "NaN"], + [1696411155, "NaN"], + [1696411170, "NaN"], + [1696411185, "NaN"], + [1696411200, "NaN"], + [1696411215, "NaN"], + [1696411230, "NaN"], + [1696411245, "NaN"], + [1696411260, "NaN"], + [1696411275, "NaN"], + [1696411290, "NaN"], + [1696411305, "NaN"], + [1696411320, "NaN"], + [1696411335, "NaN"], + [1696411350, "NaN"], + [1696411365, "NaN"], + [1696411380, "NaN"], + [1696411395, "421.1904761904761"], + [1696411410, "1518.7230036548897"], + [1696411425, "1486.5537839191707"], + [1696411440, "1606.3605924791486"], + [1696411455, "1686.7630057803472"], + [1696411470, "1712.8529411764707"], + [1696411485, "1726.3473053892217"], + [1696411500, "1738.6826347305391"], + [1696411515, "1712.6946107784431"], + [1696411530, "1715.5722891566263"], + [1696411545, "1707.9573170731705"], + [1696411560, "1713.6845952569065"], + [1696411575, "1720.3592814371257"], + [1696411590, "1717.7678571428576"], + [1696411605, "1744.7478495869427"], + [1696411620, "1713.7690722169127"], + [1696411635, "1741.9631901840492"], + [1696411650, "1717.1130952380952"], + [1696411665, "1728.747379767859"], + [1696411680, "1704.7321428571427"], + [1696411695, "1716.6566265060244"], + [1696411710, "1725.02994011976"], + [1696411725, "1749.1722864139313"], + [1696411740, "1745.2160493827162"], + [1696411755, "1742.2360248447203"], + [1696411770, "1718.0911398883477"], + [1696411785, "1708.4208953752093"], + [1696411800, "1697.719298245614"], + [1696411815, "1718.6176470588232"], + [1696411830, "1719.549525159515"], + [1696411845, "1732.9573170731708"], + [1696411860, "1714.7865853658536"], + [1696411875, "1715.8324995142395"], + [1696411890, "1724.1818181818182"], + [1696411905, "1723.6363636363637"], + [1696411920, "1741.4723926380368"], + [1696411935, "1705.267857142857"], + [1696411950, "1760.6289308176104"], + [1696411965, "1734.2767295597484"], + [1696411980, "1743.7822556900564"], + [1696411995, "1698.8392857142856"], + [1696412010, "1739.4817073170734"], + [1696412025, "1754.401064247901"], + [1696412040, "1735.644171779141"], + [1696412055, "1692.2321428571427"], + [1696412070, "1710.267857142857"], + [1696412085, "1717.6969696969695"], + [1696412100, "1736.5493995475795"], + [1696412115, "1726.4939024390244"], + [1696412130, "1751.554992190156"], + [1696412145, "1744.1711320746856"], + [1696412160, "1726.018518518519"], + [1696412175, "1728.9937953174717"], + [1696412190, "1729.5215082845393"], + [1696412205, "1744.40625"], + [1696412220, "1705.8735608967884"], + [1696412235, "1713.9425847508378"], + [1696412250, "1730.8484848484852"], + [1696412265, "1753.5145842244906"], + [1696412280, "1752.7044025157236"], + [1696412295, "1731.7187500000005"], + [1696412310, "1729.20245398773"], + [1696412325, "1708.2012195121954"], + [1696412340, "1730.5454545454545"], + [1696412355, "1721.3719512195123"], + [1696412370, "1731.151515151515"], + [1696412385, "1709.5481927710841"], + [1696412400, "1741.963190184049"], + [1696412415, "1749.9062500000002"], + [1696412430, "1733.560322153935"], + [1696412445, "1717.300613496933"], + [1696412460, "1690.059171597633"], + [1696412475, "1727.168339198239"], + [1696412490, "1707.5290697674416"], + [1696412505, "1736.3392857142853"], + [1696412520, "1686.300578034682"], + [1696412535, "1709.7660818713448"], + [1696412550, "1730.8982035928145"], + [1696412565, "1751.2654320987658"], + [1696412580, "1740.6832298136644"], + [1696412595, "1713.9197530864194"] + ], + "stat": "avg", + "name": "response_size" + } + ], + "response_throughput": [ + { + "labels": {}, + "datapoints": [ + [1696410795, "6229.333333333332"], + [1696410810, "6266.888888888888"], + [1696410825, "6236.333333333332"], + [1696410840, "6256.555555555555"], + [1696410855, "6164.555555555555"], + [1696410870, "6097.444444444445"], + [1696410885, "6128.222222222222"], + [1696410900, "6148.444444444444"], + [1696410915, "6156.888888888889"], + [1696410930, "6233.480233559637"], + [1696410945, "6341.666666666666"], + [1696410960, "6364.11111111111"], + [1696410975, "6345.790134710828"], + [1696410990, "6202.749952609931"], + [1696411005, "6206.888888888889"], + [1696411020, "6221.11111111111"], + [1696411035, "6303.480916802658"], + [1696411050, "6327.444444444443"], + [1696411065, "4965.773611111112"], + [1696411080, "3300.976388888888"], + [1696411095, "257.1111111111111"], + [1696411110, "0"], + [1696411125, "0"], + [1696411140, "0"], + [1696411155, "0"], + [1696411170, "0"], + [1696411185, "0"], + [1696411200, "0"], + [1696411215, "0"], + [1696411230, "0"], + [1696411245, "0"], + [1696411260, "0"], + [1696411275, "0"], + [1696411290, "0"], + [1696411305, "0"], + [1696411320, "0"], + [1696411335, "0"], + [1696411350, "0"], + [1696411365, "0"], + [1696411380, "0"], + [1696411395, "196.55555555555551"], + [1696411410, "2666.3291666666664"], + [1696411425, "4368.940277777778"], + [1696411440, "5943.668055555556"], + [1696411455, "6484.666666666667"], + [1696411470, "6470.777777777777"], + [1696411485, "6406.666666666667"], + [1696411500, "6452.444444444444"], + [1696411515, "6355.999999999999"], + [1696411530, "6328.555555555555"], + [1696411545, "6224.555555555555"], + [1696411560, "6359.4074106990765"], + [1696411575, "6384.444444444444"], + [1696411590, "6413"], + [1696411605, "6281.363705959198"], + [1696411620, "6245.660010172388"], + [1696411635, "6309.7777777777765"], + [1696411650, "6410.555555555556"], + [1696411665, "6377.2338375532745"], + [1696411680, "6364.333333333333"], + [1696411695, "6332.555555555556"], + [1696411710, "6401.7777777777765"], + [1696411725, "6335.735251272784"], + [1696411740, "6282.7777777777765"], + [1696411755, "6233.333333333332"], + [1696411770, "6299.820238924198"], + [1696411785, "6415.989445617153"], + [1696411800, "6451.333333333332"], + [1696411815, "6492.555555555555"], + [1696411830, "6380.637153645969"], + [1696411845, "6315.666666666666"], + [1696411860, "6249.444444444443"], + [1696411875, "6330.352006243607"], + [1696411890, "6321.999999999999"], + [1696411905, "6319.999999999999"], + [1696411920, "6307.999999999999"], + [1696411935, "6366.333333333333"], + [1696411950, "6220.888888888889"], + [1696411965, "6127.777777777777"], + [1696411980, "6199.80470871725"], + [1696411995, "6342.333333333333"], + [1696412010, "6339.444444444444"], + [1696412025, "6199.19568159145"], + [1696412040, "6286.888888888888"], + [1696412055, "6317.666666666665"], + [1696412070, "6384.999999999999"], + [1696412085, "6298.222222222221"], + [1696412100, "6289.936300542926"], + [1696412115, "6292.11111111111"], + [1696412130, "6227.6542244341745"], + [1696412145, "6201.7299301434905"], + [1696412160, "6213.666666666667"], + [1696412175, "6262.902224593014"], + [1696412190, "6264.660000592539"], + [1696412205, "6202.333333333333"], + [1696412220, "6253.354064860062"], + [1696412235, "6360.672000474116"], + [1696412250, "6346.444444444444"], + [1696412265, "6197.310903611481"], + [1696412280, "6192.888888888889"], + [1696412295, "6157.222222222223"], + [1696412310, "6263.555555555555"], + [1696412325, "6225.444444444444"], + [1696412340, "6345.333333333332"], + [1696412355, "6273.444444444444"], + [1696412370, "6347.555555555555"], + [1696412385, "6306.333333333332"], + [1696412400, "6309.7777777777765"], + [1696412415, "6221.888888888889"], + [1696412430, "6202.21655333837"], + [1696412445, "6220.444444444444"], + [1696412460, "6347.11111111111"], + [1696412475, "6409.790380807049"], + [1696412490, "6526.555555555555"], + [1696412505, "6482.333333333332"], + [1696412520, "6482.888888888889"], + [1696412535, "6497.1111111111095"], + [1696412550, "6423.555555555555"], + [1696412565, "6304.555555555555"], + [1696412580, "6227.7777777777765"], + [1696412595, "6170.11111111111"] + ], + "name": "response_throughput" + } + ], + "tcp_closed": null, + "tcp_opened": null, + "tcp_received": null, + "tcp_sent": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_3600.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_3600.json new file mode 100644 index 0000000000..9e2895fe2f --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_3600.json @@ -0,0 +1,32 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "2.6002743899782135"], + [1697022000, "3.634782608695652"], + [1697022360, "3.678260869565217"], + [1697022720, "3.6753623188405795"], + [1697023080, "3.7101449275362324"], + [1697023440, "3.6318840579710145"], + [1697023800, "3.6811594202898554"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "0"], + [1697022000, "0"], + [1697022360, "0"], + [1697022720, "0"], + [1697023080, "0"], + [1697023440, "0"], + [1697023800, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_60.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_60.json new file mode 100644 index 0000000000..5a7ba4ce06 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_60.json @@ -0,0 +1,24 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023800, "3.466666666666667"], + [1697023830, "3.399800039992002"], + [1697023860, "3.2664801740597667"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697023800, "0"], + [1697023830, "0"], + [1697023860, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_600.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_600.json new file mode 100644 index 0000000000..c53996c283 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/inbound/metrics_inbound_600.json @@ -0,0 +1,40 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "3.399866684442075"], + [1697023710, "3.7333333333333334"], + [1697023740, "3.9327959496369327"], + [1697023770, "3.6666666666666665"], + [1697023800, "3.466666666666667"], + [1697023830, "3.399800039992002"], + [1697023860, "3.2664801740597667"], + [1697023890, "3.533333333333333"], + [1697023920, "3.866666666666667"], + [1697023950, "3.733333333333334"], + [1697023980, "3.466666666666667"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "0"], + [1697023710, "0"], + [1697023740, "0"], + [1697023770, "0"], + [1697023800, "0"], + [1697023830, "0"], + [1697023860, "0"], + [1697023890, "0"], + [1697023920, "0"], + [1697023950, "0"], + [1697023980, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/index.ts b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/index.ts new file mode 100644 index 0000000000..e975e594e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/index.ts @@ -0,0 +1,37 @@ +/* Inbound Metrics */ + +import inbound60 from './inbound/metrics_inbound_60.json'; +import inbound120 from './inbound/metrics_inbound_120.json'; +import inbound300 from './inbound/metrics_inbound_300.json'; +import inbound600 from './inbound/metrics_inbound_600.json'; +import inbound1800 from './inbound/metrics_inbound_1800.json'; +import inbound3600 from './inbound/metrics_inbound_3600.json'; +/* Outbound Metrics */ + +import outbound60 from './outbound/metrics_outbound_60.json'; +import outbound120 from './outbound/metrics_outbound_120.json'; +import outbound300 from './outbound/metrics_outbound_300.json'; +import outbound600 from './outbound/metrics_outbound_600.json'; +import outbound1800 from './outbound/metrics_outbound_1800.json'; +import outbound3600 from './outbound/metrics_outbound_3600.json'; + +export const bookInfoMetrics = { + inbound: { + 60: inbound60, + 120: inbound120, + 300: inbound300, + 600: inbound600, + 1800: inbound1800, + 3600: inbound3600, + }, + outbound: { + 60: outbound60, + 120: outbound120, + 300: outbound300, + 600: outbound600, + 1800: outbound1800, + 3600: outbound3600, + }, +}; + +export default bookInfoMetrics; diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_120.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_120.json new file mode 100644 index 0000000000..3a2f963923 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_120.json @@ -0,0 +1,28 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023830, "2.4"], + [1697023860, "2.2664801740597667"], + [1697023890, "2.533333333333333"], + [1697023920, "2.8666666666666667"], + [1697023950, "2.733333333333334"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697023830, "0"], + [1697023860, "0"], + [1697023890, "0"], + [1697023920, "0"], + [1697023950, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_1800.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_1800.json new file mode 100644 index 0000000000..1f6372ba41 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_1800.json @@ -0,0 +1,40 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697022180, "2.660592434003259"], + [1697022360, "2.6727272727272724"], + [1697022540, "2.66060606060606"], + [1697022720, "2.6666666666666665"], + [1697022900, "2.66060606060606"], + [1697023080, "2.751515151515151"], + [1697023260, "2.642218224270407"], + [1697023440, "2.6424242424242417"], + [1697023620, "2.7272727272727266"], + [1697023800, "2.636363636363636"], + [1697023980, "2.6363636363636362"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697022180, "0"], + [1697022360, "0"], + [1697022540, "0"], + [1697022720, "0"], + [1697022900, "0"], + [1697023080, "0"], + [1697023260, "0"], + [1697023440, "0"], + [1697023620, "0"], + [1697023800, "0"], + [1697023980, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_300.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_300.json new file mode 100644 index 0000000000..e5384d2042 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_300.json @@ -0,0 +1,40 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "2.4"], + [1697023710, "2.7333333333333334"], + [1697023740, "2.9327959496369327"], + [1697023770, "2.6666666666666665"], + [1697023800, "2.466666666666667"], + [1697023830, "2.4"], + [1697023860, "2.2664801740597667"], + [1697023890, "2.533333333333333"], + [1697023920, "2.8666666666666667"], + [1697023950, "2.733333333333334"], + [1697023980, "2.466666666666667"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "0"], + [1697023710, "0"], + [1697023740, "0"], + [1697023770, "0"], + [1697023800, "0"], + [1697023830, "0"], + [1697023860, "0"], + [1697023890, "0"], + [1697023920, "0"], + [1697023950, "0"], + [1697023980, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_3600.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_3600.json new file mode 100644 index 0000000000..b15fb136cb --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_3600.json @@ -0,0 +1,32 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "1.8706855010893246"], + [1697022000, "2.634782608695652"], + [1697022360, "2.678260869565217"], + [1697022720, "2.6753623188405795"], + [1697023080, "2.7101449275362324"], + [1697023440, "2.631884057971014"], + [1697023800, "2.6811594202898554"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "0"], + [1697022000, "0"], + [1697022360, "0"], + [1697022720, "0"], + [1697023080, "0"], + [1697023440, "0"], + [1697023800, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_60.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_60.json new file mode 100644 index 0000000000..d10d586b91 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_60.json @@ -0,0 +1,24 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023830, "2.4"], + [1697023860, "2.2664801740597667"], + [1697023890, "2.533333333333333"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697023830, "0"], + [1697023860, "0"], + [1697023890, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_600.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_600.json new file mode 100644 index 0000000000..2ce8ed7f51 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/metrics/outbound/metrics_outbound_600.json @@ -0,0 +1,144 @@ +{ + "grpc_received": null, + "grpc_sent": null, + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023260, "2.5770227926554257"], + [1697023320, "2.688875062342908"], + [1697023380, "2.5334024768184116"], + [1697023440, "2.644444444444444"], + [1697023500, "2.888888888888889"], + [1697023560, "2.8222222222222224"], + [1697023620, "2.577792593580313"], + [1697023680, "2.511111111111111"], + [1697023740, "2.799815353777718"], + [1697023800, "2.5777777777777775"], + [1697023860, "2.422111639341834"] + ], + "name": "request_count" + } + ], + "request_duration_millis": [ + { + "labels": {}, + "datapoints": [ + [1697023260, "0.8984028601338787"], + [1697023320, "0.7599175779653324"], + [1697023380, "1.1891073830431969"], + [1697023440, "0.8486956521739024"], + [1697023500, "1.3678294573643095"], + [1697023560, "1.3087301587301081"], + [1697023620, "1.0917565417025843"], + [1697023680, "1.2628205128205447"], + [1697023740, "1.460967924929601"], + [1697023800, "1.292016806722755"], + [1697023860, "1.284750805346726"] + ], + "stat": "avg", + "name": "request_duration_millis" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697023260, "0"], + [1697023320, "0"], + [1697023380, "0"], + [1697023440, "0"], + [1697023500, "0"], + [1697023560, "0"], + [1697023620, "0"], + [1697023680, "0"], + [1697023740, "0"], + [1697023800, "0"], + [1697023860, "0"] + ], + "name": "request_error_count" + } + ], + "request_size": [ + { + "labels": {}, + "datapoints": [ + [1697023260, "1321.2978379025685"], + [1697023320, "1318.96540098226"], + [1697023380, "1321.3024875544975"], + [1697023440, "1319.5652173913045"], + [1697023500, "1320.5426356589146"], + [1697023560, "1319.047619047619"], + [1697023620, "1321.30451418782"], + [1697023680, "1321.7948717948716"], + [1697023740, "1321.778861892338"], + [1697023800, "1321.4285714285716"], + [1697023860, "1327.7766258130607"] + ], + "stat": "avg", + "name": "request_size" + } + ], + "request_throughput": [ + { + "labels": {}, + "datapoints": [ + [1697023260, "3375.6524699856404"], + [1697023320, "3399.9827661980453"], + [1697023380, "3376.750009260288"], + [1697023440, "3372.222222222222"], + [1697023500, "3785.555555555555"], + [1697023560, "3693.333333333333"], + [1697023620, "3376.686668000089"], + [1697023680, "3436.666666666666"], + [1697023740, "3641.998202908425"], + [1697023800, "3494.4444444444443"], + [1697023860, "3186.4987189170774"] + ], + "name": "request_throughput" + } + ], + "response_size": [ + { + "labels": {}, + "datapoints": [ + [1697023260, "1238.7218631817639"], + [1697023320, "1226.7230258729253"], + [1697023380, "1238.6907292600722"], + [1697023440, "1224.782608695652"], + [1697023500, "1233.720930232558"], + [1697023560, "1231.7460317460318"], + [1697023620, "1235.218636496714"], + [1697023680, "1249.1452991452988"], + [1697023740, "1234.6894311611843"], + [1697023800, "1239.075630252101"], + [1697023860, "1236.10002345071"] + ], + "stat": "avg", + "name": "response_size" + } + ], + "response_throughput": [ + { + "labels": {}, + "datapoints": [ + [1697023260, "3164.687322664851"], + [1697023320, "3162.203605765669"], + [1697023380, "3165.625563334197"], + [1697023440, "3129.9999999999995"], + [1697023500, "3536.666666666666"], + [1697023560, "3448.8888888888887"], + [1697023620, "3156.688149580342"], + [1697023680, "3247.777777777777"], + [1697023740, "3402.0340459986323"], + [1697023800, "3276.6666666666665"], + [1697023860, "2966.4862783430335"] + ], + "name": "response_throughput" + } + ], + "tcp_closed": null, + "tcp_opened": null, + "tcp_received": null, + "tcp_sent": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/tls.json b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/tls.json new file mode 100644 index 0000000000..ea7db32cbb --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/bookinfo/tls.json @@ -0,0 +1 @@ +{ "status": "MTLS_NOT_ENABLED", "autoMTLSEnabled": true, "minTLS": "" } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/health/app.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/health/app.json new file mode 100644 index 0000000000..55a1b7dec6 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/health/app.json @@ -0,0 +1,114 @@ +{ + "grafana": { + "workloadStatuses": [ + { + "name": "grafana", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + } + ], + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "istio-egressgateway": { + "workloadStatuses": [ + { + "name": "istio-egressgateway", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + } + ], + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "istio-ingressgateway": { + "workloadStatuses": [ + { + "name": "istio-ingressgateway", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + } + ], + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "istiod": { + "workloadStatuses": [ + { + "name": "istiod", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + } + ], + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "jaeger": { + "workloadStatuses": [ + { + "name": "jaeger", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + } + ], + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "kiali": { + "workloadStatuses": [ + { + "name": "kiali", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + } + ], + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "prometheus": { + "workloadStatuses": [ + { + "name": "prometheus", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + } + ], + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/health/service.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/health/service.json new file mode 100644 index 0000000000..af1aa51acc --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/health/service.json @@ -0,0 +1,65 @@ +{ + "grafana": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "istio-egressgateway": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "istio-ingressgateway": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "istiod": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "jaeger-collector": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "kiali": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "prometheus": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "tracing": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "zipkin": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/health/workload.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/health/workload.json new file mode 100644 index 0000000000..3855649f3b --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/health/workload.json @@ -0,0 +1,100 @@ +{ + "grafana": { + "workloadStatus": { + "name": "grafana", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "istio-egressgateway": { + "workloadStatus": { + "name": "istio-egressgateway", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "istio-ingressgateway": { + "workloadStatus": { + "name": "istio-ingressgateway", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "istiod": { + "workloadStatus": { + "name": "istiod", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "jaeger": { + "workloadStatus": { + "name": "jaeger", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "kiali": { + "workloadStatus": { + "name": "kiali", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "prometheus": { + "workloadStatus": { + "name": "prometheus", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": -1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_120.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_120.json new file mode 100644 index 0000000000..680a665149 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_120.json @@ -0,0 +1,100 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697024040, "0.002755125239989775"], + [1697024070, "0.0028308143301925487"], + [1697024100, "0.0027977164583027226"], + [1697024130, "0.017605061010355652"], + [1697024160, "0.0016924311084703827"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697024040, "145.055744"], + [1697024070, "143.683584"], + [1697024100, "143.683584"], + [1697024130, "143.679488"], + [1697024160, "143.683584"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697024040, "NaN"], + [1697024070, "NaN"], + [1697024100, "NaN"], + [1697024130, "NaN"], + [1697024160, "NaN"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697024040, "0.0013333333333333049"], + [1697024070, "0.0013333333333333049"], + [1697024100, "0.002000000000000076"], + [1697024130, "0.002000000000000076"], + [1697024160, "0.0013333333333333049"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697024040, "165.003264"], + [1697024070, "163.6352"], + [1697024100, "163.6352"], + [1697024130, "163.6352"], + [1697024160, "163.6352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": null, + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_1800.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_1800.json new file mode 100644 index 0000000000..12112e1412 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_1800.json @@ -0,0 +1,130 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697022360, "0.004423229563643965"], + [1697022540, "0.002818351158753509"], + [1697022720, "0.0033681828956744772"], + [1697022900, "0.004075735098607482"], + [1697023080, "0.004858861411539032"], + [1697023260, "0.003327461760086153"], + [1697023440, "0.0029723897808957888"], + [1697023620, "0.005595762889521851"], + [1697023800, "0.0034129233521214435"], + [1697023980, "0.0034297933448419722"], + [1697024160, "0.005304226914689294"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697022360, "145.154048"], + [1697022540, "143.589376"], + [1697022720, "146.763776"], + [1697022900, "155.20972799999998"], + [1697023080, "152.662016"], + [1697023260, "148.979712"], + [1697023440, "146.354176"], + [1697023620, "144.191488"], + [1697023800, "146.18624"], + [1697023980, "144.396288"], + [1697024160, "143.683584"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697022360, "NaN"], + [1697022540, "NaN"], + [1697022720, "NaN"], + [1697022900, "NaN"], + [1697023080, "NaN"], + [1697023260, "NaN"], + [1697023440, "NaN"], + [1697023620, "NaN"], + [1697023800, "NaN"], + [1697023980, "0.00026259236363636437"], + [1697024160, "NaN"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697022360, "0.002242424242424248"], + [1697022540, "0.0013333333333333478"], + [1697022720, "0.0017575757575757738"], + [1697022900, "0.001999999999999989"], + [1697023080, "0.002363636363636367"], + [1697023260, "0.0016363636363636335"], + [1697023440, "0.0015757575757575635"], + [1697023620, "0.002727272727272744"], + [1697023800, "0.001757575757575752"], + [1697023980, "0.0017575757575757738"], + [1697024160, "0.002666666666666674"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697022360, "165.09747199999998"], + [1697022540, "163.688448"], + [1697022720, "165.851136"], + [1697022900, "175.038464"], + [1697023080, "172.531712"], + [1697023260, "168.40704"], + [1697023440, "166.641664"], + [1697023620, "164.35609599999998"], + [1697023800, "166.244352"], + [1697023980, "164.462592"], + [1697024160, "163.6352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": null, + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_300.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_300.json new file mode 100644 index 0000000000..1b3825ca9e --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_300.json @@ -0,0 +1,130 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697023860, "0.00277104088632311"], + [1697023890, "0.002440995810258295"], + [1697023920, "0.0030462017153864134"], + [1697023950, "0.0011749084878141453"], + [1697023980, "0.003215558196758648"], + [1697024010, "0.0020194318109019596"], + [1697024040, "0.002755125239989775"], + [1697024070, "0.0028308143301925487"], + [1697024100, "0.0027977164583027226"], + [1697024130, "0.017605061010355652"], + [1697024160, "0.0016924311084703827"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697023860, "144.982016"], + [1697023890, "144.846848"], + [1697023920, "145.51449599999998"], + [1697023950, "144.52326399999998"], + [1697023980, "144.396288"], + [1697024010, "144.392192"], + [1697024040, "145.055744"], + [1697024070, "143.683584"], + [1697024100, "143.683584"], + [1697024130, "143.679488"], + [1697024160, "143.683584"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697023860, "NaN"], + [1697023890, "NaN"], + [1697023920, "NaN"], + [1697023950, "NaN"], + [1697023980, "NaN"], + [1697024010, "NaN"], + [1697024040, "NaN"], + [1697024070, "NaN"], + [1697024100, "NaN"], + [1697024130, "NaN"], + [1697024160, "NaN"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697023860, "0.0019999999999998387"], + [1697023890, "0.002000000000000076"], + [1697023920, "0.0013333333333333049"], + [1697023950, "0.0013333333333333049"], + [1697023980, "0.0013333333333335417"], + [1697024010, "0.0013333333333333049"], + [1697024040, "0.0013333333333333049"], + [1697024070, "0.0013333333333333049"], + [1697024100, "0.002000000000000076"], + [1697024130, "0.002000000000000076"], + [1697024160, "0.0013333333333333049"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697023860, "164.769792"], + [1697023890, "164.769792"], + [1697023920, "165.58079999999998"], + [1697023950, "164.462592"], + [1697023980, "164.462592"], + [1697024010, "164.462592"], + [1697024040, "165.003264"], + [1697024070, "163.6352"], + [1697024100, "163.6352"], + [1697024130, "163.6352"], + [1697024160, "163.6352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": null, + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_3600.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_3600.json new file mode 100644 index 0000000000..6178363f65 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_3600.json @@ -0,0 +1,115 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "0.0022837365589533235"], + [1697022000, "0.003630157034545756"], + [1697022360, "0.0034882143205133696"], + [1697022720, "0.003109542147831563"], + [1697023080, "0.004421874876878809"], + [1697023440, "0.0031209359563211837"], + [1697023800, "0.004399331006493985"], + [1697024160, "0.004336317402418327"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697021640, "143.09376"], + [1697022000, "145.137664"], + [1697022360, "145.154048"], + [1697022720, "146.763776"], + [1697023080, "152.662016"], + [1697023440, "146.354176"], + [1697023800, "146.18624"], + [1697024160, "143.683584"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "NaN"], + [1697022000, "NaN"], + [1697022360, "NaN"], + [1697022720, "NaN"], + [1697023080, "0.00021478099999999977"], + [1697023440, "NaN"], + [1697023800, "NaN"], + [1697024160, "0.0002625923636363643"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "0.001045284722222216"], + [1697022000, "0.0018260869565217364"], + [1697022360, "0.0017971014492753651"], + [1697022720, "0.0015652173913043557"], + [1697023080, "0.002173913043478261"], + [1697023440, "0.0015942028985507267"], + [1697023800, "0.002202898550724642"], + [1697024160, "0.002202898550724642"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697021640, "163.19692799999999"], + [1697022000, "165.09747199999998"], + [1697022360, "165.09747199999998"], + [1697022720, "165.851136"], + [1697023080, "172.531712"], + [1697023440, "166.641664"], + [1697023800, "166.244352"], + [1697024160, "163.6352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": null, + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_60.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_60.json new file mode 100644 index 0000000000..74a54ee770 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_60.json @@ -0,0 +1,90 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697024100, "0.0027977164583027226"], + [1697024130, "0.017605061010355652"], + [1697024160, "0.0016924311084703827"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697024100, "143.683584"], + [1697024130, "143.679488"], + [1697024160, "143.683584"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697024100, "NaN"], + [1697024130, "NaN"], + [1697024160, "NaN"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697024100, "0.002000000000000076"], + [1697024130, "0.002000000000000076"], + [1697024160, "0.0013333333333333049"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697024100, "163.6352"], + [1697024130, "163.6352"], + [1697024160, "163.6352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": null, + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_600.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_600.json new file mode 100644 index 0000000000..9e292c84ec --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/inbound/metrics_inbound_600.json @@ -0,0 +1,141 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697023560, "0.012649111781990258"], + [1697023620, "0.0028395890688735514"], + [1697023680, "0.0029086472614529356"], + [1697023740, "0.003109156035267781"], + [1697023800, "0.002981445175995798"], + [1697023860, "0.0030650943556152"], + [1697023920, "0.002949315857020238"], + [1697023980, "0.0030294256967151605"], + [1697024040, "0.003211951468553024"], + [1697024100, "0.0031811090223253153"], + [1697024160, "0.009876169457103496"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697023560, "144.203776"], + [1697023620, "144.191488"], + [1697023680, "144.859136"], + [1697023740, "145.522688"], + [1697023800, "146.18624"], + [1697023860, "144.982016"], + [1697023920, "145.51449599999998"], + [1697023980, "144.396288"], + [1697024040, "145.055744"], + [1697024100, "143.683584"], + [1697024160, "143.683584"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "grpc_received": null, + "grpc_sent": null, + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697023560, "NaN"], + [1697023620, "NaN"], + [1697023680, "NaN"], + [1697023740, "NaN"], + [1697023800, "NaN"], + [1697023860, "0.0002625923636363643"], + [1697023920, "NaN"], + [1697023980, "NaN"], + [1697024040, "NaN"], + [1697024100, "NaN"], + [1697024160, "NaN"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697023560, "0.004888888888888863"], + [1697023620, "0.0015555555555555618"], + [1697023680, "0.0015555555555555618"], + [1697023740, "0.0015555555555555618"], + [1697023800, "0.0015555555555555618"], + [1697023860, "0.0019999999999999966"], + [1697023920, "0.0015555555555555618"], + [1697023980, "0.0013333333333333836"], + [1697024040, "0.0015555555555555618"], + [1697024100, "0.0017777777777778186"], + [1697024160, "0.00511111111111112"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697023560, "164.35609599999998"], + [1697023620, "164.35609599999998"], + [1697023680, "164.892672"], + [1697023740, "165.70368"], + [1697023800, "166.244352"], + [1697023860, "164.769792"], + [1697023920, "165.58079999999998"], + [1697023980, "164.462592"], + [1697024040, "165.003264"], + [1697024100, "163.6352"], + [1697024160, "163.6352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": null, + "request_duration_millis": null, + "request_error_count": null, + "request_size": null, + "request_throughput": null, + "response_size": null, + "response_throughput": null, + "tcp_closed": null, + "tcp_opened": null, + "tcp_received": null, + "tcp_sent": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/index.ts b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/index.ts new file mode 100644 index 0000000000..c1b81f13ea --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/index.ts @@ -0,0 +1,37 @@ +/* Inbound Metrics */ + +import inbound60 from './inbound/metrics_inbound_60.json'; +import inbound120 from './inbound/metrics_inbound_120.json'; +import inbound300 from './inbound/metrics_inbound_300.json'; +import inbound600 from './inbound/metrics_inbound_600.json'; +import inbound1800 from './inbound/metrics_inbound_1800.json'; +import inbound3600 from './inbound/metrics_inbound_3600.json'; +/* Outbound Metrics */ + +import outbound60 from './outbound/metrics_outbound_60.json'; +import outbound120 from './outbound/metrics_outbound_120.json'; +import outbound300 from './outbound/metrics_outbound_300.json'; +import outbound600 from './outbound/metrics_outbound_600.json'; +import outbound1800 from './outbound/metrics_outbound_1800.json'; +import outbound3600 from './outbound/metrics_outbound_3600.json'; + +export const istioSystemMetrics = { + inbound: { + 60: inbound60, + 120: inbound120, + 300: inbound300, + 600: inbound600, + 1800: inbound1800, + 3600: inbound3600, + }, + outbound: { + 60: outbound60, + 120: outbound120, + 300: outbound300, + 600: outbound600, + 1800: outbound1800, + 3600: outbound3600, + }, +}; + +export default istioSystemMetrics; diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_120.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_120.json new file mode 100644 index 0000000000..1ed12e8c7e --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_120.json @@ -0,0 +1,112 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697024010, "0.0020194318109019596"], + [1697024040, "0.002755125239989775"], + [1697024070, "0.0028308143301925487"], + [1697024100, "0.0027977164583027226"], + [1697024130, "0.017605061010355652"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697024010, "144.392192"], + [1697024040, "145.055744"], + [1697024070, "143.683584"], + [1697024100, "143.683584"], + [1697024130, "143.679488"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697024010, "NaN"], + [1697024040, "NaN"], + [1697024070, "NaN"], + [1697024100, "NaN"], + [1697024130, "NaN"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697024010, "0.0013333333333333049"], + [1697024040, "0.0013333333333333049"], + [1697024070, "0.0013333333333333049"], + [1697024100, "0.002000000000000076"], + [1697024130, "0.002000000000000076"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697024010, "164.462592"], + [1697024040, "165.003264"], + [1697024070, "163.6352"], + [1697024100, "163.6352"], + [1697024130, "163.6352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697024010, "1"], + [1697024040, "1"], + [1697024070, "0.9996667777407532"], + [1697024100, "1"], + [1697024130, "1"] + ], + "name": "request_count" + } + ], + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_1800.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_1800.json new file mode 100644 index 0000000000..b23b5c5d65 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_1800.json @@ -0,0 +1,148 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697022180, "0.0026138895855586384"], + [1697022360, "0.004423229563643965"], + [1697022540, "0.002818351158753509"], + [1697022720, "0.0033681828956744772"], + [1697022900, "0.004075735098607482"], + [1697023080, "0.004858861411539032"], + [1697023260, "0.003327461760086153"], + [1697023440, "0.0029723897808957888"], + [1697023620, "0.005595762889521851"], + [1697023800, "0.0034129233521214435"], + [1697023980, "0.0034297933448419722"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697022180, "145.154048"], + [1697022360, "145.154048"], + [1697022540, "143.589376"], + [1697022720, "146.763776"], + [1697022900, "155.20972799999998"], + [1697023080, "152.662016"], + [1697023260, "148.979712"], + [1697023440, "146.354176"], + [1697023620, "144.191488"], + [1697023800, "146.18624"], + [1697023980, "144.396288"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697022180, "NaN"], + [1697022360, "NaN"], + [1697022540, "NaN"], + [1697022720, "NaN"], + [1697022900, "NaN"], + [1697023080, "NaN"], + [1697023260, "NaN"], + [1697023440, "NaN"], + [1697023620, "NaN"], + [1697023800, "NaN"], + [1697023980, "0.00026259236363636437"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697022180, "0.0013939393939393964"], + [1697022360, "0.002242424242424248"], + [1697022540, "0.0013333333333333478"], + [1697022720, "0.0017575757575757738"], + [1697022900, "0.001999999999999989"], + [1697023080, "0.002363636363636367"], + [1697023260, "0.0016363636363636335"], + [1697023440, "0.0015757575757575635"], + [1697023620, "0.002727272727272744"], + [1697023800, "0.001757575757575752"], + [1697023980, "0.0017575757575757738"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697022180, "165.09747199999998"], + [1697022360, "165.09747199999998"], + [1697022540, "163.688448"], + [1697022720, "165.851136"], + [1697022900, "175.038464"], + [1697023080, "172.531712"], + [1697023260, "168.40704"], + [1697023440, "166.641664"], + [1697023620, "164.35609599999998"], + [1697023800, "166.244352"], + [1697023980, "164.462592"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697022180, "0.9999999999999999"], + [1697022360, "0.9999999999999999"], + [1697022540, "0.9999999999999999"], + [1697022720, "0.9999999999999999"], + [1697022900, "0.9999999999999999"], + [1697023080, "0.9999999999999999"], + [1697023260, "0.9999999999999999"], + [1697023440, "0.9999999999999999"], + [1697023620, "0.9999999999999999"], + [1697023800, "0.9999999999999999"], + [1697023980, "0.9999999999999999"] + ], + "name": "request_count" + } + ], + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_300.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_300.json new file mode 100644 index 0000000000..341f41eb51 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_300.json @@ -0,0 +1,148 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697023830, "0.004117320729759894"], + [1697023860, "0.00277104088632311"], + [1697023890, "0.002440995810258295"], + [1697023920, "0.0030462017153864134"], + [1697023950, "0.0011749084878141453"], + [1697023980, "0.003215558196758648"], + [1697024010, "0.0020194318109019596"], + [1697024040, "0.002755125239989775"], + [1697024070, "0.0028308143301925487"], + [1697024100, "0.0027977164583027226"], + [1697024130, "0.017605061010355652"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697023830, "144.850944"], + [1697023860, "144.982016"], + [1697023890, "144.846848"], + [1697023920, "145.51449599999998"], + [1697023950, "144.52326399999998"], + [1697023980, "144.396288"], + [1697024010, "144.392192"], + [1697024040, "145.055744"], + [1697024070, "143.683584"], + [1697024100, "143.683584"], + [1697024130, "143.679488"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697023830, "0.00026259236363636437"], + [1697023860, "NaN"], + [1697023890, "NaN"], + [1697023920, "NaN"], + [1697023950, "NaN"], + [1697023980, "NaN"], + [1697024010, "NaN"], + [1697024040, "NaN"], + [1697024070, "NaN"], + [1697024100, "NaN"], + [1697024130, "NaN"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697023830, "0.0026666666666668466"], + [1697023860, "0.0019999999999998387"], + [1697023890, "0.002000000000000076"], + [1697023920, "0.0013333333333333049"], + [1697023950, "0.0013333333333333049"], + [1697023980, "0.0013333333333335417"], + [1697024010, "0.0013333333333333049"], + [1697024040, "0.0013333333333333049"], + [1697024070, "0.0013333333333333049"], + [1697024100, "0.002000000000000076"], + [1697024130, "0.002000000000000076"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697023830, "164.22912"], + [1697023860, "164.769792"], + [1697023890, "164.769792"], + [1697023920, "165.58079999999998"], + [1697023950, "164.462592"], + [1697023980, "164.462592"], + [1697024010, "164.462592"], + [1697024040, "165.003264"], + [1697024070, "163.6352"], + [1697024100, "163.6352"], + [1697024130, "163.6352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023830, "0.9998000399920017"], + [1697023860, "1"], + [1697023890, "1"], + [1697023920, "1"], + [1697023950, "1"], + [1697023980, "1"], + [1697024010, "1"], + [1697024040, "1"], + [1697024070, "0.9996667777407532"], + [1697024100, "1"], + [1697024130, "1"] + ], + "name": "request_count" + } + ], + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_3600.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_3600.json new file mode 100644 index 0000000000..cd77133738 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_3600.json @@ -0,0 +1,124 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "0.0022837365589533235"], + [1697022000, "0.003630157034545756"], + [1697022360, "0.0034882143205133696"], + [1697022720, "0.003109542147831563"], + [1697023080, "0.004421874876878809"], + [1697023440, "0.0031209359563211837"], + [1697023800, "0.004399331006493985"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697021640, "143.09376"], + [1697022000, "145.137664"], + [1697022360, "145.154048"], + [1697022720, "146.763776"], + [1697023080, "152.662016"], + [1697023440, "146.354176"], + [1697023800, "146.18624"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "NaN"], + [1697022000, "NaN"], + [1697022360, "NaN"], + [1697022720, "NaN"], + [1697023080, "0.00021478099999999977"], + [1697023440, "NaN"], + [1697023800, "NaN"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "0.001045284722222216"], + [1697022000, "0.0018260869565217364"], + [1697022360, "0.0017971014492753651"], + [1697022720, "0.0015652173913043557"], + [1697023080, "0.002173913043478261"], + [1697023440, "0.0015942028985507267"], + [1697023800, "0.002202898550724642"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697021640, "163.19692799999999"], + [1697022000, "165.09747199999998"], + [1697022360, "165.09747199999998"], + [1697022720, "165.851136"], + [1697023080, "172.531712"], + [1697023440, "166.641664"], + [1697023800, "166.244352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "0.7295888888888888"], + [1697022000, "1"], + [1697022360, "1"], + [1697022720, "1"], + [1697023080, "1"], + [1697023440, "1"], + [1697023800, "1"] + ], + "name": "request_count" + } + ], + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_60.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_60.json new file mode 100644 index 0000000000..d9aa2a50c6 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_60.json @@ -0,0 +1,100 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697024070, "0.0028308143301925487"], + [1697024100, "0.0027977164583027226"], + [1697024130, "0.017605061010355652"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697024070, "143.683584"], + [1697024100, "143.683584"], + [1697024130, "143.679488"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697024070, "NaN"], + [1697024100, "NaN"], + [1697024130, "NaN"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697024070, "0.0013333333333333049"], + [1697024100, "0.002000000000000076"], + [1697024130, "0.002000000000000076"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697024070, "163.6352"], + [1697024100, "163.6352"], + [1697024130, "163.6352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697024070, "0.9996667777407532"], + [1697024100, "1"], + [1697024130, "1"] + ], + "name": "request_count" + } + ], + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_600.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_600.json new file mode 100644 index 0000000000..4fcd086822 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/metrics/outbound/metrics_outbound_600.json @@ -0,0 +1,252 @@ +{ + "container_cpu_usage_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697023500, "0.004063051366539051"], + [1697023560, "0.012649111781990258"], + [1697023620, "0.0028395890688735514"], + [1697023680, "0.0029086472614529356"], + [1697023740, "0.003109156035267781"], + [1697023800, "0.002981445175995798"], + [1697023860, "0.0030650943556152"], + [1697023920, "0.002949315857020238"], + [1697023980, "0.0030294256967151605"], + [1697024040, "0.003211951468553024"], + [1697024100, "0.0031811090223253153"] + ], + "name": "container_cpu_usage_seconds_total" + } + ], + "container_memory_working_set_bytes": [ + { + "labels": { + "__name__": "container_memory_working_set_bytes", + "beta_kubernetes_io_arch": "amd64", + "beta_kubernetes_io_os": "linux", + "container": "discovery", + "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod86ae28e5_296a_4c6f_81ae_e3102580203a.slice/crio-311ddafa211336c162b5aeb91d70fbd048f94c9f18142285c0473eae845da2de.scope", + "image": "gcr.io/istio-release/pilot:1.18.2", + "instance": "crc-8cf2w-master-0", + "job": "kubernetes-nodes-cadvisor", + "kubernetes_io_arch": "amd64", + "kubernetes_io_hostname": "crc-8cf2w-master-0", + "kubernetes_io_os": "linux", + "name": "k8s_discovery_istiod-7548d4ff85-9czcn_istio-system_86ae28e5-296a-4c6f-81ae-e3102580203a_2", + "namespace": "istio-system", + "node_openshift_io_os_id": "rhcos", + "pod": "istiod-7548d4ff85-9czcn", + "topology_hostpath_csi_node": "crc-8cf2w-master-0" + }, + "datapoints": [ + [1697023500, "144.195584"], + [1697023560, "144.203776"], + [1697023620, "144.191488"], + [1697023680, "144.859136"], + [1697023740, "145.522688"], + [1697023800, "146.18624"], + [1697023860, "144.982016"], + [1697023920, "145.51449599999998"], + [1697023980, "144.396288"], + [1697024040, "145.055744"], + [1697024100, "143.683584"] + ], + "name": "container_memory_working_set_bytes" + } + ], + "grpc_received": null, + "grpc_sent": null, + "pilot_proxy_convergence_time": [ + { + "labels": {}, + "datapoints": [ + [1697023500, "NaN"], + [1697023560, "NaN"], + [1697023620, "NaN"], + [1697023680, "NaN"], + [1697023740, "NaN"], + [1697023800, "NaN"], + [1697023860, "0.0002625923636363643"], + [1697023920, "NaN"], + [1697023980, "NaN"], + [1697024040, "NaN"], + [1697024100, "NaN"] + ], + "stat": "avg", + "name": "pilot_proxy_convergence_time" + } + ], + "process_cpu_seconds_total": [ + { + "labels": {}, + "datapoints": [ + [1697023500, "0.0019999999999999966"], + [1697023560, "0.004888888888888863"], + [1697023620, "0.0015555555555555618"], + [1697023680, "0.0015555555555555618"], + [1697023740, "0.0015555555555555618"], + [1697023800, "0.0015555555555555618"], + [1697023860, "0.0019999999999999966"], + [1697023920, "0.0015555555555555618"], + [1697023980, "0.0013333333333333836"], + [1697024040, "0.0015555555555555618"], + [1697024100, "0.0017777777777778186"] + ], + "name": "process_cpu_seconds_total" + } + ], + "process_resident_memory_bytes": [ + { + "labels": { + "__name__": "process_resident_memory_bytes", + "app": "istiod", + "install_operator_istio_io_owning_resource": "unknown", + "instance": "10.217.0.34:15014", + "istio": "pilot", + "istio_io_rev": "default", + "job": "kubernetes-pods", + "namespace": "istio-system", + "operator_istio_io_component": "Pilot", + "pod": "istiod-7548d4ff85-9czcn", + "pod_template_hash": "7548d4ff85", + "sidecar_istio_io_inject": "false" + }, + "datapoints": [ + [1697023500, "163.81951999999998"], + [1697023560, "164.35609599999998"], + [1697023620, "164.35609599999998"], + [1697023680, "164.892672"], + [1697023740, "165.70368"], + [1697023800, "166.244352"], + [1697023860, "164.769792"], + [1697023920, "165.58079999999998"], + [1697023980, "164.462592"], + [1697024040, "165.003264"], + [1697024100, "163.6352"] + ], + "name": "process_resident_memory_bytes" + } + ], + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023500, "0.9999999999999999"], + [1697023560, "0.9999999999999999"], + [1697023620, "0.9999999999999999"], + [1697023680, "0.9999555575307764"], + [1697023740, "0.9999999999999999"], + [1697023800, "0.9999999999999999"], + [1697023860, "0.9999999999999999"], + [1697023920, "0.9999999999999999"], + [1697023980, "0.9999999999999999"], + [1697024040, "0.9999999999999999"], + [1697024100, "0.9999999999999999"] + ], + "name": "request_count" + } + ], + "request_duration_millis": [ + { + "labels": {}, + "datapoints": [ + [1697023500, "17.144444444444446"], + [1697023560, "17.98888888888889"], + [1697023620, "15.245555555555297"], + [1697023680, "15.845555555555297"], + [1697023740, "16.65555555555556"], + [1697023800, "15.968888888889017"], + [1697023860, "15.96888888888837"], + [1697023920, "15.522222222222222"], + [1697023980, "13.882222222222481"], + [1697024040, "15.981111111110982"], + [1697024100, "16.5466666666668"] + ], + "stat": "avg", + "name": "request_duration_millis" + } + ], + "request_error_count": null, + "request_size": [ + { + "labels": {}, + "datapoints": [ + [1697023500, "1950"], + [1697023560, "1950"], + [1697023620, "1950"], + [1697023680, "1950"], + [1697023740, "1950"], + [1697023800, "1950"], + [1697023860, "1950"], + [1697023920, "1950"], + [1697023980, "1950"], + [1697024040, "1950"], + [1697024100, "1950"] + ], + "stat": "avg", + "name": "request_size" + } + ], + "request_throughput": [ + { + "labels": {}, + "datapoints": [ + [1697023500, "1949.9999999999998"], + [1697023560, "1949.9999999999998"], + [1697023620, "1949.9999999999998"], + [1697023680, "1949.913337185014"], + [1697023740, "1949.9999999999998"], + [1697023800, "1949.9999999999998"], + [1697023860, "1949.9999999999998"], + [1697023920, "1949.9999999999998"], + [1697023980, "1949.9999999999998"], + [1697024040, "1949.9999999999998"], + [1697024100, "1949.9999999999998"] + ], + "name": "request_throughput" + } + ], + "response_size": [ + { + "labels": {}, + "datapoints": [ + [1697023500, "6127.777777777778"], + [1697023560, "6083.333333333334"], + [1697023620, "5972.222222222223"], + [1697023680, "5883.333333333334"], + [1697023740, "6083.333333333334"], + [1697023800, "6038.888888888889"], + [1697023860, "5972.222222222223"], + [1697023920, "5994.444444444444"], + [1697023980, "5905.555555555556"], + [1697024040, "6127.777777777778"], + [1697024100, "6016.666666666667"] + ], + "stat": "avg", + "name": "response_size" + } + ], + "response_throughput": [ + { + "labels": {}, + "datapoints": [ + [1697023500, "6127.777777777777"], + [1697023560, "6083.333333333333"], + [1697023620, "5972.222222222222"], + [1697023680, "5883.071863472735"], + [1697023740, "6083.333333333333"], + [1697023800, "6038.888888888888"], + [1697023860, "5972.222222222222"], + [1697023920, "5994.444444444443"], + [1697023980, "5905.555555555555"], + [1697024040, "6127.777777777777"], + [1697024100, "6016.666666666666"] + ], + "name": "response_throughput" + } + ], + "tcp_closed": null, + "tcp_opened": null, + "tcp_received": null, + "tcp_sent": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/istio-system/tls.json b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/tls.json new file mode 100644 index 0000000000..ea7db32cbb --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/istio-system/tls.json @@ -0,0 +1 @@ +{ "status": "MTLS_NOT_ENABLED", "autoMTLSEnabled": true, "minTLS": "" } diff --git a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-agency-health.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/health/app.json similarity index 56% rename from plugins/kiali-backend/__fixtures__/data/namespaces/travel-agency-health.json rename to plugins/kiali/dev/__fixtures__/namespaces/travel-agency/health/app.json index 64899ff352..84a00bf3c8 100644 --- a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-agency-health.json +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/health/app.json @@ -10,8 +10,16 @@ } ], "requests": { - "inbound": { "http": { "200": 0.26666666666666666 } }, - "outbound": { "http": { "200": 0.26666666666666666 } }, + "inbound": { + "http": { + "200": 0.26322191455252564 + } + }, + "outbound": { + "http": { + "200": 0.2649572649572649 + } + }, "healthAnnotations": {} } }, @@ -26,7 +34,11 @@ } ], "requests": { - "inbound": { "http": { "200": 1.3333333333333333 } }, + "inbound": { + "http": { + "200": 1.3299145299145296 + } + }, "outbound": {}, "healthAnnotations": {} } @@ -42,8 +54,16 @@ } ], "requests": { - "inbound": { "http": { "200": 0.26666666666666666 } }, - "outbound": { "http": { "200": 0.26666666666666666 } }, + "inbound": { + "http": { + "200": 0.2653657058650162 + } + }, + "outbound": { + "http": { + "200": 0.2666666666666666 + } + }, "healthAnnotations": {} } }, @@ -58,8 +78,16 @@ } ], "requests": { - "inbound": { "http": { "200": 0.7999999999999999 } }, - "outbound": { "http": { "200": 0.39999999999999997 } }, + "inbound": { + "http": { + "200": 0.7991927774830533 + } + }, + "outbound": { + "http": { + "200": 0.39829059829059826 + } + }, "healthAnnotations": {} } }, @@ -74,8 +102,16 @@ } ], "requests": { - "inbound": { "http": { "200": 0.39658119658119656 } }, - "outbound": { "http": { "200": 0.39658119658119656 } }, + "inbound": { + "http": { + "200": 0.39883943943412903 + } + }, + "outbound": { + "http": { + "200": 0.39999999999999997 + } + }, "healthAnnotations": {} } }, @@ -89,7 +125,11 @@ "syncedProxies": 1 } ], - "requests": { "inbound": {}, "outbound": {}, "healthAnnotations": {} } + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } }, "travels": { "workloadStatuses": [ @@ -99,11 +139,33 @@ "currentReplicas": 1, "availableReplicas": 1, "syncedProxies": 1 + }, + { + "name": "travels-v2", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + { + "name": "travels-v3", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 } ], "requests": { - "inbound": { "http": { "200": 0.7965611411095852 } }, - "outbound": { "http": { "200": 1.986324786324786 } }, + "inbound": { + "http": { + "200": 0.7942120752085292 + } + }, + "outbound": { + "http": { + "200": 1.9840915760326658 + } + }, "healthAnnotations": {} } } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/health/service.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/health/service.json new file mode 100644 index 0000000000..338f0ad2c2 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/health/service.json @@ -0,0 +1,75 @@ +{ + "cars": { + "requests": { + "inbound": { + "http": { + "200": 0.260085535042735 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "discounts": { + "requests": { + "inbound": { + "http": { + "200": 1.3299145299145296 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "flights": { + "requests": { + "inbound": { + "http": { + "200": 0.26561828319088315 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "hotels": { + "requests": { + "inbound": { + "http": { + "200": 0.7984701908831908 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "insurances": { + "requests": { + "inbound": { + "http": { + "200": 0.3991372467236467 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "mysqldb": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "travels": { + "requests": { + "inbound": { + "http": { + "200": 0.793200482030932 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/health/workload.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/health/workload.json new file mode 100644 index 0000000000..1b21415624 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/health/workload.json @@ -0,0 +1,188 @@ +{ + "cars-v1": { + "workloadStatus": { + "name": "cars-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.2600759354226021 + } + }, + "outbound": { + "http": { + "200": 0.2649572649572649 + } + }, + "healthAnnotations": {} + } + }, + "discounts-v1": { + "workloadStatus": { + "name": "discounts-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 1.3299145299145296 + } + }, + "outbound": {}, + "healthAnnotations": {} + } + }, + "flights-v1": { + "workloadStatus": { + "name": "flights-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.2656132557771446 + } + }, + "outbound": { + "http": { + "200": 0.2666666666666666 + } + }, + "healthAnnotations": {} + } + }, + "hotels-v1": { + "workloadStatus": { + "name": "hotels-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.7984947065527065 + } + }, + "outbound": { + "http": { + "200": 0.39829059829059826 + } + }, + "healthAnnotations": {} + } + }, + "insurances-v1": { + "workloadStatus": { + "name": "insurances-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.3991459420702754 + } + }, + "outbound": { + "http": { + "200": 0.39999999999999997 + } + }, + "healthAnnotations": {} + } + }, + "mysqldb-v1": { + "workloadStatus": { + "name": "mysqldb-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "travels-v1": { + "workloadStatus": { + "name": "travels-v1", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.49743589743589733 + } + }, + "outbound": { + "http": { + "200": 1.1008547008547007 + } + }, + "healthAnnotations": {} + } + }, + "travels-v2": { + "workloadStatus": { + "name": "travels-v2", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.1514719596391263 + } + }, + "outbound": { + "http": { + "200": 0.32564116856600195 + } + }, + "healthAnnotations": {} + } + }, + "travels-v3": { + "workloadStatus": { + "name": "travels-v3", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": { + "http": { + "200": 0.1476955061728395 + } + }, + "outbound": { + "http": { + "200": 0.29358963325102877 + } + }, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_120.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_120.json new file mode 100644 index 0000000000..ddf90f9504 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_120.json @@ -0,0 +1,28 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697024130, "3.933244474064202"], + [1697024160, "3.800053774557242"], + [1697024190, "3.8666666666666685"], + [1697024220, "3.9334756314478847"], + [1697024250, "3.800000000000001"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697024130, "0"], + [1697024160, "0"], + [1697024190, "0"], + [1697024220, "0"], + [1697024250, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_1800.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_1800.json new file mode 100644 index 0000000000..8909e1ecf8 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_1800.json @@ -0,0 +1,40 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697022360, "3.872727272727272"], + [1697022540, "3.8545359783060222"], + [1697022720, "3.8545454545454536"], + [1697022900, "3.8424242424242423"], + [1697023080, "3.8849503289542557"], + [1697023260, "3.872730798962184"], + [1697023440, "3.866666666666666"], + [1697023620, "3.8787878787878785"], + [1697023800, "3.7999692964648504"], + [1697023980, "3.866666666666666"], + [1697024160, "3.8545352074830523"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697022360, "0"], + [1697022540, "0"], + [1697022720, "0"], + [1697022900, "0"], + [1697023080, "0"], + [1697023260, "0"], + [1697023440, "0"], + [1697023620, "0"], + [1697023800, "0"], + [1697023980, "0"], + [1697024160, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_300.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_300.json new file mode 100644 index 0000000000..67504e1639 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_300.json @@ -0,0 +1,40 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023950, "3.8000000000000007"], + [1697023980, "3.8000000000000016"], + [1697024010, "3.799946691548685"], + [1697024040, "3.933386677335468"], + [1697024070, "3.8000000000000016"], + [1697024100, "3.866729028197065"], + [1697024130, "3.933244474064202"], + [1697024160, "3.800053774557242"], + [1697024190, "3.8666666666666685"], + [1697024220, "3.9334756314478847"], + [1697024250, "3.800000000000001"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697023950, "0"], + [1697023980, "0"], + [1697024010, "0"], + [1697024040, "0"], + [1697024070, "0"], + [1697024100, "0"], + [1697024130, "0"], + [1697024160, "0"], + [1697024190, "0"], + [1697024220, "0"], + [1697024250, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_3600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_3600.json new file mode 100644 index 0000000000..936ede0342 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_3600.json @@ -0,0 +1,34 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "2.741467670887799"], + [1697022000, "3.8637681159420296"], + [1697022360, "3.886961159447176"], + [1697022720, "3.852173913043479"], + [1697023080, "3.87536231884058"], + [1697023440, "3.8695668557168306"], + [1697023800, "3.831869372789426"], + [1697024160, "3.8637611596017596"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "0"], + [1697022000, "0"], + [1697022360, "0"], + [1697022720, "0"], + [1697023080, "0"], + [1697023440, "0"], + [1697023800, "0"], + [1697024160, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_60.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_60.json new file mode 100644 index 0000000000..ef4e583f44 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_60.json @@ -0,0 +1,24 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697024190, "3.8666666666666685"], + [1697024220, "3.9334756314478847"], + [1697024250, "3.800000000000001"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697024190, "0"], + [1697024220, "0"], + [1697024250, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_600.json new file mode 100644 index 0000000000..f626ff6190 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/inbound/metrics_inbound_600.json @@ -0,0 +1,216 @@ +{ + "grpc_received": null, + "grpc_sent": null, + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "3.9333333333333322"], + [1697023680, "3.8444444444444428"], + [1697023740, "3.844444444444443"], + [1697023800, "3.6443941298905074"], + [1697023860, "3.911016329996248"], + [1697023920, "3.844444444444443"], + [1697023980, "3.8444444444444446"], + [1697024040, "3.844454815506219"], + [1697024100, "3.8666222273573743"], + [1697024160, "3.8666133439978667"], + [1697024220, "3.86663111585122"] + ], + "name": "request_count" + } + ], + "request_duration_millis": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "6.566379310344839"], + [1697023680, "6.0295977011493616"], + [1697023740, "5.244848484848487"], + [1697023800, "5.478065206312723"], + [1697023860, "5.412254385266055"], + [1697023920, "5.532183908045853"], + [1697023980, "4.92413793103454"], + [1697024040, "6.368985326269782"], + [1697024100, "7.1145999315657855"], + [1697024160, "5.6739383767877145"], + [1697024220, "5.092213150551359"] + ], + "stat": "avg", + "name": "request_duration_millis" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "0"], + [1697023680, "0"], + [1697023740, "0"], + [1697023800, "0"], + [1697023860, "0"], + [1697023920, "0"], + [1697023980, "0"], + [1697024040, "0"], + [1697024100, "0"], + [1697024160, "0"], + [1697024220, "0"] + ], + "name": "request_error_count" + } + ], + "request_size": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "1366.0919540229886"], + [1697023680, "1366.666666666667"], + [1697023740, "1360.3030303030305"], + [1697023800, "1365.3831644528366"], + [1697023860, "1364.942895021214"], + [1697023920, "1364.9425287356325"], + [1697023980, "1364.367816091954"], + [1697024040, "1365.5168872809536"], + [1697024100, "1364.3682110995646"], + [1697024160, "1365.607152888307"], + [1697024220, "1364.9426661211412"] + ], + "stat": "avg", + "name": "request_size" + } + ], + "request_throughput": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "5282.222222222221"], + [1697023680, "5284.444444444443"], + [1697023740, "4987.7777777777765"], + [1697023800, "5127.703630078002"], + [1697023860, "5277.649823272713"], + [1697023920, "5277.777777777778"], + [1697023980, "5275.555555555556"], + [1697024040, "5280.014815802535"], + [1697024100, "5275.496451337396"], + [1697024160, "5249.928014397122"], + [1697024220, "5277.729784176925"] + ], + "name": "request_throughput" + } + ], + "response_size": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "1598.275862068966"], + [1697023680, "1598.2758620689665"], + [1697023740, "1628.1818181818187"], + [1697023800, "1572.5156425114612"], + [1697023860, "1598.289301932234"], + [1697023920, "1598.2758620689658"], + [1697023980, "1598.2758620689654"], + [1697024040, "1598.2777065514515"], + [1697024100, "1598.278817440177"], + [1697024160, "1600.8746926872575"], + [1697024220, "1598.2809030603103"] + ], + "stat": "avg", + "name": "response_size" + } + ], + "response_throughput": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "6180"], + [1697023680, "6180.000000000001"], + [1697023740, "5969.999999999999"], + [1697023800, "5905.59073700882"], + [1697023860, "6179.900479829393"], + [1697023920, "6180"], + [1697023980, "6180"], + [1697024040, "6180.026075812462"], + [1697024100, "6179.940401028648"], + [1697024160, "6154.388455642205"], + [1697024220, "6179.962671643781"] + ], + "name": "response_throughput" + } + ], + "tcp_closed": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "1.733333333333333"], + [1697023680, "1.733333333333333"], + [1697023740, "1.733333333333333"], + [1697023800, "1.733333333333333"], + [1697023860, "1.733333333333333"], + [1697023920, "1.733333333333333"], + [1697023980, "1.733333333333333"], + [1697024040, "1.733333333333333"], + [1697024100, "1.733333333333333"], + [1697024160, "1.733333333333333"], + [1697024220, "1.733333333333333"] + ], + "name": "tcp_closed" + } + ], + "tcp_opened": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "1.733333333333333"], + [1697023680, "1.733333333333333"], + [1697023740, "1.733333333333333"], + [1697023800, "1.733333333333333"], + [1697023860, "1.733333333333333"], + [1697023920, "1.733333333333333"], + [1697023980, "1.733333333333333"], + [1697024040, "1.733333333333333"], + [1697024100, "1.733333333333333"], + [1697024160, "1.733333333333333"], + [1697024220, "1.733333333333333"] + ], + "name": "tcp_opened" + } + ], + "tcp_received": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "957.5999999999998"], + [1697023680, "958.2888888888888"], + [1697023740, "957.6222222222221"], + [1697023800, "958.1555555555556"], + [1697023860, "957.3999999999999"], + [1697023920, "957.4444444444443"], + [1697023980, "957.2444444444443"], + [1697024040, "958.2444444444443"], + [1697024100, "957.511111111111"], + [1697024160, "958.1333333333333"], + [1697024220, "957.3333333333333"] + ], + "name": "tcp_received" + } + ], + "tcp_sent": [ + { + "labels": {}, + "datapoints": [ + [1697023620, "324.9555555555555"], + [1697023680, "326.1333333333333"], + [1697023740, "325.17777777777775"], + [1697023800, "326.1111111111111"], + [1697023860, "324.75555555555553"], + [1697023920, "324.66666666666663"], + [1697023980, "324.3555555555555"], + [1697024040, "326.0222222222222"], + [1697024100, "324.66666666666663"], + [1697024160, "325.99999999999994"], + [1697024220, "324.7777777777777"] + ], + "name": "tcp_sent" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/index.ts b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/index.ts new file mode 100644 index 0000000000..3988cf5a5d --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/index.ts @@ -0,0 +1,37 @@ +/* Inbound Metrics */ + +import inbound60 from './inbound/metrics_inbound_60.json'; +import inbound120 from './inbound/metrics_inbound_120.json'; +import inbound300 from './inbound/metrics_inbound_300.json'; +import inbound600 from './inbound/metrics_inbound_600.json'; +import inbound1800 from './inbound/metrics_inbound_1800.json'; +import inbound3600 from './inbound/metrics_inbound_3600.json'; +/* Outbound Metrics */ + +import outbound60 from './outbound/metrics_outbound_60.json'; +import outbound120 from './outbound/metrics_outbound_120.json'; +import outbound300 from './outbound/metrics_outbound_300.json'; +import outbound600 from './outbound/metrics_outbound_600.json'; +import outbound1800 from './outbound/metrics_outbound_1800.json'; +import outbound3600 from './outbound/metrics_outbound_3600.json'; + +export const travelAgencyMetrics = { + inbound: { + 60: inbound60, + 120: inbound120, + 300: inbound300, + 600: inbound600, + 1800: inbound1800, + 3600: inbound3600, + }, + outbound: { + 60: outbound60, + 120: outbound120, + 300: outbound300, + 600: outbound600, + 1800: outbound1800, + 3600: outbound3600, + }, +}; + +export default travelAgencyMetrics; diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_120.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_120.json new file mode 100644 index 0000000000..1084dd865d --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_120.json @@ -0,0 +1,16 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697024190, "3.0666666666666673"], + [1697024220, "3.1334756314478835"], + [1697024250, "3.0000000000000004"], + [1697024280, "3.0666666666666673"], + [1697024310, "3.13326224118013"] + ], + "name": "request_count" + } + ], + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_1800.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_1800.json new file mode 100644 index 0000000000..240a8b90d2 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_1800.json @@ -0,0 +1,22 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697022360, "3.0727272727272723"], + [1697022540, "3.0545359783060224"], + [1697022720, "3.072727272727272"], + [1697022900, "3.0484848484848484"], + [1697023080, "3.0728291168330446"], + [1697023260, "3.072727272727272"], + [1697023440, "3.0727272727272723"], + [1697023620, "3.0606060606060606"], + [1697023800, "2.9999692964648506"], + [1697023980, "3.0606060606060597"], + [1697024160, "3.0605915159448593"] + ], + "name": "request_count" + } + ], + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_300.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_300.json new file mode 100644 index 0000000000..e4e25a85d0 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_300.json @@ -0,0 +1,22 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697024010, "3.0666000222148173"], + [1697024040, "3.1333866773354675"], + [1697024070, "3.0000000000000004"], + [1697024100, "3.0666756171822707"], + [1697024130, "3.133244474064201"], + [1697024160, "3.000053774557241"], + [1697024190, "3.0666666666666673"], + [1697024220, "3.1334756314478835"], + [1697024250, "3.0000000000000004"], + [1697024280, "3.0666666666666673"], + [1697024310, "3.13326224118013"] + ], + "name": "request_count" + } + ], + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_3600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_3600.json new file mode 100644 index 0000000000..2c501bbf59 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_3600.json @@ -0,0 +1,19 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "2.1670810770697164"], + [1697022000, "3.069565217391305"], + [1697022360, "3.0869611594471746"], + [1697022720, "3.0608695652173914"], + [1697023080, "3.069565217391305"], + [1697023440, "3.0695652173913044"], + [1697023800, "3.0318693727894255"], + [1697024160, "3.0637611596017598"] + ], + "name": "request_count" + } + ], + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_60.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_60.json new file mode 100644 index 0000000000..0f2af383be --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_60.json @@ -0,0 +1,14 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697024250, "3.0000000000000004"], + [1697024280, "3.0666666666666673"], + [1697024310, "3.13326224118013"] + ], + "name": "request_count" + } + ], + "request_error_count": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_600.json new file mode 100644 index 0000000000..f768e774be --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/metrics/outbound/metrics_outbound_600.json @@ -0,0 +1,198 @@ +{ + "grpc_received": null, + "grpc_sent": null, + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "3.066666666666666"], + [1697023740, "3.0666666666666664"], + [1697023800, "2.822109677148661"], + [1697023860, "3.0665718855518036"], + [1697023920, "3.066666666666666"], + [1697023980, "3.0666666666666664"], + [1697024040, "3.0666666666666664"], + [1697024100, "3.0666311158512194"], + [1697024160, "3.066613343997867"], + [1697024220, "3.0666311158512203"], + [1697024280, "3.066666666666667"] + ], + "name": "request_count" + } + ], + "request_duration_millis": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "4.850362318840522"], + [1697023740, "4.438372093023219"], + [1697023800, "4.504722864182922"], + [1697023860, "4.575570249658066"], + [1697023920, "4.5568840579709216"], + [1697023980, "4.083333333333391"], + [1697024040, "5.183333333333363"], + [1697024100, "6.056815740306035"], + [1697024160, "4.519259624156209"], + [1697024220, "4.197780125318008"], + [1697024280, "3.9851449275362336"] + ], + "stat": "avg", + "name": "request_duration_millis" + } + ], + "request_error_count": null, + "request_size": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "1397.1014492753623"], + [1697023740, "1391.0852713178294"], + [1697023800, "1396.6183165397285"], + [1697023860, "1394.9289248450104"], + [1697023920, "1394.927536231884"], + [1697023980, "1394.2028985507245"], + [1697024040, "1395.6521739130435"], + [1697024100, "1394.2034109857157"], + [1697024160, "1395.9862068965522"], + [1697024220, "1394.9280570674496"], + [1697024280, "1395.6521739130435"] + ], + "stat": "avg", + "name": "request_size" + } + ], + "request_throughput": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "4284.444444444443"], + [1697023740, "3987.7777777777774"], + [1697023800, "4127.6258419284695"], + [1697023860, "4277.649823272714"], + [1697023920, "4277.777777777777"], + [1697023980, "4275.555555555556"], + [1697024040, "4280"], + [1697024100, "4275.507561954702"], + [1697024160, "4249.928014397121"], + [1697024220, "4277.729784176925"], + [1697024280, "4279.999999999999"] + ], + "name": "request_throughput" + } + ], + "response_size": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "1384.7826086956525"], + [1697023740, "1408.139534883721"], + [1697023800, "1343.996157532804"], + [1697023860, "1384.7929561031394"], + [1697023920, "1384.782608695652"], + [1697023980, "1384.7826086956522"], + [1697024040, "1384.7826086956527"], + [1697024100, "1384.7864897606667"], + [1697024160, "1386.5022441160374"], + [1697024220, "1384.7864897606673"], + [1697024280, "1384.7826086956522"] + ], + "stat": "avg", + "name": "response_size" + } + ], + "response_throughput": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "4246.666666666667"], + [1697023740, "4036.666666666666"], + [1697023800, "3972.1040498949824"], + [1697023860, "4246.567146496061"], + [1697023920, "4246.666666666666"], + [1697023980, "4246.666666666667"], + [1697024040, "4246.666666666668"], + [1697024100, "4246.629338310448"], + [1697024160, "4221.055122308871"], + [1697024220, "4246.629338310448"], + [1697024280, "4246.666666666666"] + ], + "name": "response_throughput" + } + ], + "tcp_closed": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "1.733333333333333"], + [1697023740, "1.733333333333333"], + [1697023800, "1.733333333333333"], + [1697023860, "1.733333333333333"], + [1697023920, "1.733333333333333"], + [1697023980, "1.733333333333333"], + [1697024040, "1.733333333333333"], + [1697024100, "1.733333333333333"], + [1697024160, "1.733333333333333"], + [1697024220, "1.733333333333333"], + [1697024280, "1.733333333333333"] + ], + "name": "tcp_closed" + } + ], + "tcp_opened": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "1.733333333333333"], + [1697023740, "1.733333333333333"], + [1697023800, "1.733333333333333"], + [1697023860, "1.733333333333333"], + [1697023920, "1.733333333333333"], + [1697023980, "1.733333333333333"], + [1697024040, "1.733333333333333"], + [1697024100, "1.733333333333333"], + [1697024160, "1.733333333333333"], + [1697024220, "1.733333333333333"], + [1697024280, "1.733333333333333"] + ], + "name": "tcp_opened" + } + ], + "tcp_received": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "958.2888888888888"], + [1697023740, "957.6222222222221"], + [1697023800, "958.1555555555556"], + [1697023860, "957.3999999999999"], + [1697023920, "957.4444444444443"], + [1697023980, "957.2444444444443"], + [1697024040, "958.2444444444443"], + [1697024100, "957.511111111111"], + [1697024160, "958.1333333333333"], + [1697024220, "957.3333333333333"], + [1697024280, "957.7555555555554"] + ], + "name": "tcp_received" + } + ], + "tcp_sent": [ + { + "labels": {}, + "datapoints": [ + [1697023680, "326.1333333333333"], + [1697023740, "325.17777777777775"], + [1697023800, "326.1111111111111"], + [1697023860, "324.75555555555553"], + [1697023920, "324.66666666666663"], + [1697023980, "324.3555555555555"], + [1697024040, "326.0222222222222"], + [1697024100, "324.66666666666663"], + [1697024160, "325.99999999999994"], + [1697024220, "324.7777777777777"], + [1697024280, "325.26666666666665"] + ], + "name": "tcp_sent" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/tls.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/tls.json new file mode 100644 index 0000000000..ea7db32cbb --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-agency/tls.json @@ -0,0 +1 @@ +{ "status": "MTLS_NOT_ENABLED", "autoMTLSEnabled": true, "minTLS": "" } diff --git a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-control-health.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/health/app.json similarity index 69% rename from plugins/kiali-backend/__fixtures__/data/namespaces/travel-control-health.json rename to plugins/kiali/dev/__fixtures__/namespaces/travel-control/health/app.json index 2c1939bc20..2800f2b95a 100644 --- a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-control-health.json +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/health/app.json @@ -9,6 +9,10 @@ "syncedProxies": 1 } ], - "requests": { "inbound": {}, "outbound": {}, "healthAnnotations": {} } + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } } } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/health/service.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/health/service.json new file mode 100644 index 0000000000..c3873c7c04 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/health/service.json @@ -0,0 +1,9 @@ +{ + "control": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/health/workload.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/health/workload.json new file mode 100644 index 0000000000..6b1c459332 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/health/workload.json @@ -0,0 +1,16 @@ +{ + "control": { + "workloadStatus": { + "name": "control", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_120.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_120.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_120.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_1800.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_1800.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_1800.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_300.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_300.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_300.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_3600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_3600.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_3600.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_60.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_60.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_60.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_600.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/inbound/metrics_inbound_600.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/index.ts b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/index.ts new file mode 100644 index 0000000000..3e1973c9ba --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/index.ts @@ -0,0 +1,37 @@ +/* Inbound Metrics */ + +import inbound60 from './inbound/metrics_inbound_60.json'; +import inbound120 from './inbound/metrics_inbound_120.json'; +import inbound300 from './inbound/metrics_inbound_300.json'; +import inbound600 from './inbound/metrics_inbound_600.json'; +import inbound1800 from './inbound/metrics_inbound_1800.json'; +import inbound3600 from './inbound/metrics_inbound_3600.json'; +/* Outbound Metrics */ + +import outbound60 from './outbound/metrics_outbound_60.json'; +import outbound120 from './outbound/metrics_outbound_120.json'; +import outbound300 from './outbound/metrics_outbound_300.json'; +import outbound600 from './outbound/metrics_outbound_600.json'; +import outbound1800 from './outbound/metrics_outbound_1800.json'; +import outbound3600 from './outbound/metrics_outbound_3600.json'; + +export const travelControlMetrics = { + inbound: { + 60: inbound60, + 120: inbound120, + 300: inbound300, + 600: inbound600, + 1800: inbound1800, + 3600: inbound3600, + }, + outbound: { + 60: outbound60, + 120: outbound120, + 300: outbound300, + 600: outbound600, + 1800: outbound1800, + 3600: outbound3600, + }, +}; + +export default travelControlMetrics; diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_120.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_120.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_120.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_1800.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_1800.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_1800.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_300.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_300.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_300.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_3600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_3600.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_3600.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_60.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_60.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_60.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_600.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/metrics/outbound/metrics_outbound_600.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-control/tls.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/tls.json new file mode 100644 index 0000000000..ea7db32cbb --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-control/tls.json @@ -0,0 +1 @@ +{ "status": "MTLS_NOT_ENABLED", "autoMTLSEnabled": true, "minTLS": "" } diff --git a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-portal-health.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/health/app.json similarity index 69% rename from plugins/kiali-backend/__fixtures__/data/namespaces/travel-portal-health.json rename to plugins/kiali/dev/__fixtures__/namespaces/travel-portal/health/app.json index 0a99412007..bd0b97a47f 100644 --- a/plugins/kiali-backend/__fixtures__/data/namespaces/travel-portal-health.json +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/health/app.json @@ -10,8 +10,16 @@ } ], "requests": { - "inbound": { "http": { "200": 0.7965811965811965 } }, - "outbound": { "http": { "200": 0.26666666666666666 } }, + "inbound": { + "http": { + "200": 0.7885940361045931 + } + }, + "outbound": { + "http": { + "200": 0.2620244359339096 + } + }, "healthAnnotations": {} } }, @@ -27,7 +35,11 @@ ], "requests": { "inbound": {}, - "outbound": { "http": { "200": 0.26666666666666666 } }, + "outbound": { + "http": { + "200": 0.26284883186391517 + } + }, "healthAnnotations": {} } }, @@ -43,7 +55,11 @@ ], "requests": { "inbound": {}, - "outbound": { "http": { "200": 0.2632478632478632 } }, + "outbound": { + "http": { + "200": 0.26372076830676827 + } + }, "healthAnnotations": {} } } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/health/service.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/health/service.json new file mode 100644 index 0000000000..bf448926fc --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/health/service.json @@ -0,0 +1,23 @@ +{ + "travels": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "viaggi": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "voyages": { + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/health/workload.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/health/workload.json new file mode 100644 index 0000000000..db0f480e3d --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/health/workload.json @@ -0,0 +1,44 @@ +{ + "travels": { + "workloadStatus": { + "name": "travels", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "viaggi": { + "workloadStatus": { + "name": "viaggi", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + }, + "voyages": { + "workloadStatus": { + "name": "voyages", + "desiredReplicas": 1, + "currentReplicas": 1, + "availableReplicas": 1, + "syncedProxies": 1 + }, + "requests": { + "inbound": {}, + "outbound": {}, + "healthAnnotations": {} + } + } +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_120.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_120.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_120.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_1800.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_1800.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_1800.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_300.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_300.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_300.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_3600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_3600.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_3600.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_60.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_60.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_60.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_600.json new file mode 100644 index 0000000000..c7215c95e7 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/inbound/metrics_inbound_600.json @@ -0,0 +1 @@ +{ "request_count": null, "request_error_count": null } diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/index.ts b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/index.ts new file mode 100644 index 0000000000..c2fb5a67a9 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/index.ts @@ -0,0 +1,37 @@ +/* Inbound Metrics */ + +import inbound60 from './inbound/metrics_inbound_60.json'; +import inbound120 from './inbound/metrics_inbound_120.json'; +import inbound300 from './inbound/metrics_inbound_300.json'; +import inbound600 from './inbound/metrics_inbound_600.json'; +import inbound1800 from './inbound/metrics_inbound_1800.json'; +import inbound3600 from './inbound/metrics_inbound_3600.json'; +/* Outbound Metrics */ + +import outbound60 from './outbound/metrics_outbound_60.json'; +import outbound120 from './outbound/metrics_outbound_120.json'; +import outbound300 from './outbound/metrics_outbound_300.json'; +import outbound600 from './outbound/metrics_outbound_600.json'; +import outbound1800 from './outbound/metrics_outbound_1800.json'; +import outbound3600 from './outbound/metrics_outbound_3600.json'; + +export const travelPortalMetrics = { + inbound: { + 60: inbound60, + 120: inbound120, + 300: inbound300, + 600: inbound600, + 1800: inbound1800, + 3600: inbound3600, + }, + outbound: { + 60: outbound60, + 120: outbound120, + 300: outbound300, + 600: outbound600, + 1800: outbound1800, + 3600: outbound3600, + }, +}; + +export default travelPortalMetrics; diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_120.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_120.json new file mode 100644 index 0000000000..7b786affa9 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_120.json @@ -0,0 +1,28 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697024340, "0.8"], + [1697024370, "0.7999999999999999"], + [1697024400, "0.7999999999999999"], + [1697024430, "0.7999999999999999"], + [1697024460, "0.7998933901918976"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697024340, "0"], + [1697024370, "0"], + [1697024400, "0"], + [1697024430, "0"], + [1697024460, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_1800.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_1800.json new file mode 100644 index 0000000000..7138de3b07 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_1800.json @@ -0,0 +1,40 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697022540, "0.7999999999999998"], + [1697022720, "0.7818181818181817"], + [1697022900, "0.793939393939394"], + [1697023080, "0.812121212121212"], + [1697023260, "0.800003526234912"], + [1697023440, "0.7939393939393938"], + [1697023620, "0.8181818181818182"], + [1697023800, "0.7999999999999998"], + [1697023980, "0.8060606060606059"], + [1697024160, "0.7939436915381931"], + [1697024340, "0.7999999999999998"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697022540, "0"], + [1697022720, "0"], + [1697022900, "0"], + [1697023080, "0"], + [1697023260, "0"], + [1697023440, "0"], + [1697023620, "0"], + [1697023800, "0"], + [1697023980, "0"], + [1697024160, "0"], + [1697024340, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_300.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_300.json new file mode 100644 index 0000000000..a738918bed --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_300.json @@ -0,0 +1,40 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697024160, "0.8"], + [1697024190, "0.7999999999999999"], + [1697024220, "0.7999999999999999"], + [1697024250, "0.7999999999999999"], + [1697024280, "0.7999999999999999"], + [1697024310, "0.7999999999999999"], + [1697024340, "0.8"], + [1697024370, "0.7999999999999999"], + [1697024400, "0.7999999999999999"], + [1697024430, "0.7999999999999999"], + [1697024460, "0.7998933901918976"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697024160, "0"], + [1697024190, "0"], + [1697024220, "0"], + [1697024250, "0"], + [1697024280, "0"], + [1697024310, "0"], + [1697024340, "0"], + [1697024370, "0"], + [1697024400, "0"], + [1697024430, "0"], + [1697024460, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_3600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_3600.json new file mode 100644 index 0000000000..4e6646498e --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_3600.json @@ -0,0 +1,34 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "0.5743865938180828"], + [1697022000, "0.7942028985507248"], + [1697022360, "0.8"], + [1697022720, "0.791304347826087"], + [1697023080, "0.8057971014492753"], + [1697023440, "0.8000016383255255"], + [1697023800, "0.8"], + [1697024160, "0.8000000000000002"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697021640, "0"], + [1697022000, "0"], + [1697022360, "0"], + [1697022720, "0"], + [1697023080, "0"], + [1697023440, "0"], + [1697023800, "0"], + [1697024160, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_60.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_60.json new file mode 100644 index 0000000000..f4d2cc631f --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_60.json @@ -0,0 +1,24 @@ +{ + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697024400, "0.7999999999999999"], + [1697024430, "0.7999999999999999"], + [1697024460, "0.7998933901918976"] + ], + "name": "request_count" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697024400, "0"], + [1697024430, "0"], + [1697024460, "0"] + ], + "name": "request_error_count" + } + ] +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_600.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_600.json new file mode 100644 index 0000000000..0e48ec8977 --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/metrics/outbound/metrics_outbound_600.json @@ -0,0 +1,144 @@ +{ + "grpc_received": null, + "grpc_sent": null, + "request_count": [ + { + "labels": {}, + "datapoints": [ + [1697023860, "0.8444444444444442"], + [1697023920, "0.7777777777777777"], + [1697023980, "0.7777777777777778"], + [1697024040, "0.7777881488395523"], + [1697024100, "0.7999911115061552"], + [1697024160, "0.7999999999999999"], + [1697024220, "0.7999999999999998"], + [1697024280, "0.7999999999999998"], + [1697024340, "0.8"], + [1697024400, "0.8"], + [1697024460, "0.799976300509539"] + ], + "name": "request_count" + } + ], + "request_duration_millis": [ + { + "labels": {}, + "datapoints": [ + [1697023860, "8.619444444444401"], + [1697023920, "9.27083333333308"], + [1697023980, "8.147222222222279"], + [1697024040, "10.913917295711464"], + [1697024100, "11.169437376778708"], + [1697024160, "10.068055555555624"], + [1697024220, "8.520833333333282"], + [1697024280, "8.076388888889193"], + [1697024340, "9.351388888888751"], + [1697024400, "8.795833333333498"], + [1697024460, "9.931840961833021"] + ], + "stat": "avg", + "name": "request_duration_millis" + } + ], + "request_error_count": [ + { + "labels": {}, + "datapoints": [ + [1697023860, "0"], + [1697023920, "0"], + [1697023980, "0"], + [1697024040, "0"], + [1697024100, "0"], + [1697024160, "0"], + [1697024220, "0"], + [1697024280, "0"], + [1697024340, "0"], + [1697024400, "0"], + [1697024460, "0"] + ], + "name": "request_error_count" + } + ], + "request_size": [ + { + "labels": {}, + "datapoints": [ + [1697023860, "1250.0000000000005"], + [1697023920, "1250.0000000000002"], + [1697023980, "1250"], + [1697024040, "1250"], + [1697024100, "1250.0000000000002"], + [1697024160, "1250"], + [1697024220, "1250.0000000000002"], + [1697024280, "1250.0000000000002"], + [1697024340, "1250"], + [1697024400, "1249.9999999999998"], + [1697024460, "1250"] + ], + "stat": "avg", + "name": "request_size" + } + ], + "request_throughput": [ + { + "labels": {}, + "datapoints": [ + [1697023860, "1000.0000000000001"], + [1697023920, "1000"], + [1697023980, "1000"], + [1697024040, "1000.014815802535"], + [1697024100, "999.9888893826942"], + [1697024160, "1000"], + [1697024220, "1000"], + [1697024280, "1000"], + [1697024340, "1000"], + [1697024400, "999.9999999999999"], + [1697024460, "999.9703756369238"] + ], + "name": "request_throughput" + } + ], + "response_size": [ + { + "labels": {}, + "datapoints": [ + [1697023860, "2416.666666666667"], + [1697023920, "2416.666666666667"], + [1697023980, "2416.6666666666665"], + [1697024040, "2416.663456623676"], + [1697024100, "2416.665679045266"], + [1697024160, "2416.6666666666665"], + [1697024220, "2416.666666666667"], + [1697024280, "2416.666666666667"], + [1697024340, "2416.666666666666"], + [1697024400, "2419.444444444444"], + [1697024460, "2416.666172912655"] + ], + "stat": "avg", + "name": "response_size" + } + ], + "response_throughput": [ + { + "labels": {}, + "datapoints": [ + [1697023860, "1933.333333333333"], + [1697023920, "1933.3333333333333"], + [1697023980, "1933.333333333333"], + [1697024040, "1933.3594091457946"], + [1697024100, "1933.3110627182"], + [1697024160, "1933.333333333333"], + [1697024220, "1933.333333333333"], + [1697024280, "1933.333333333333"], + [1697024340, "1933.333333333333"], + [1697024400, "1935.5555555555552"], + [1697024460, "1933.2756645732115"] + ], + "name": "response_throughput" + } + ], + "tcp_closed": null, + "tcp_opened": null, + "tcp_received": null, + "tcp_sent": null +} diff --git a/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/tls.json b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/tls.json new file mode 100644 index 0000000000..ea7db32cbb --- /dev/null +++ b/plugins/kiali/dev/__fixtures__/namespaces/travel-portal/tls.json @@ -0,0 +1 @@ +{ "status": "MTLS_NOT_ENABLED", "autoMTLSEnabled": true, "minTLS": "" } diff --git a/plugins/kiali/dev/__fixtures__/status.json b/plugins/kiali/dev/__fixtures__/status.json deleted file mode 100644 index 68f9a26bbd..0000000000 --- a/plugins/kiali/dev/__fixtures__/status.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "status": { - "status": { - "Kiali commit hash": "3987a086369a9e1a4c5705ca84d4bd8db64642e9", - "Kiali container version": "v1.74.0-SNAPSHOT", - "Kiali state": "running", - "Kiali version": "v1.74.0-SNAPSHOT", - "Mesh name": "Istio", - "Mesh version": "1.18.2" - }, - "externalServices": [ - { "name": "Istio", "version": "1.18.2" }, - { "name": "Prometheus", "version": "2.41.0" }, - { "name": "Kubernetes", "version": "v1.26.3+b404935" }, - { "name": "Grafana" }, - { "name": "Jaeger" } - ], - "warningMessages": [], - "istioEnvironment": { "isMaistra": false, "istioAPIEnabled": true } - }, - "auth": { "strategy": "anonymous", "sessionInfo": {} } -} diff --git a/plugins/kiali/dev/index.tsx b/plugins/kiali/dev/index.tsx index 289cd2beba..e12f04e029 100644 --- a/plugins/kiali/dev/index.tsx +++ b/plugins/kiali/dev/index.tsx @@ -5,112 +5,254 @@ import { createDevApp } from '@backstage/dev-utils'; import { EntityProvider } from '@backstage/plugin-catalog-react'; import { TestApiProvider } from '@backstage/test-utils'; -import { - FetchResponse, - FetchResponseWrapper, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { KialiApi, kialiApiRef } from '../src/api'; import { KialiPage, kialiPlugin } from '../src/plugin'; -import overviewJson from './__fixtures__/1-overview.json'; -import configJson from './__fixtures__/config.json'; -import namespacesJson from './__fixtures__/namespaces.json'; -import statusJson from './__fixtures__/status.json'; - -const mockEntity: Entity = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'backstage', - description: 'backstage.io', - annotations: { - 'backstage.io/kubernetes-namespace': 'istio-system,bookinfo', - }, - }, - spec: { - lifecycle: 'production', - type: 'service', - owner: 'user:guest', - }, -}; +import { KialiApi, kialiApiRef } from '../src/services/Api'; +import { KialiProvider } from '../src/store/KialiProvider'; +import { AuthInfo } from '../src/types/Auth'; +import { CertsInfo } from '../src/types/CertsInfo'; +import { DurationInSeconds, TimeInSeconds } from '../src/types/Common'; +import { + AppHealth, + NamespaceAppHealth, + NamespaceServiceHealth, + NamespaceWorkloadHealth, + ServiceHealth, + WorkloadHealth, +} from '../src/types/Health'; +import { IstioConfigsMap } from '../src/types/IstioConfigList'; +import { + CanaryUpgradeStatus, + OutboundTrafficPolicy, + ValidationStatus, +} from '../src/types/IstioObjects'; +import { + ComponentStatus, + IstiodResourceThresholds, +} from '../src/types/IstioStatus'; +import { IstioMetricsMap } from '../src/types/Metrics'; +import { IstioMetricsOptions } from '../src/types/MetricsOptions'; +import { Namespace } from '../src/types/Namespace'; +import { ServerConfig } from '../src/types/ServerConfig'; +import { StatusState } from '../src/types/StatusState'; +import { TLSStatus } from '../src/types/TLSStatus'; +import { filterNsByAnnotation } from '../src/utils/entityFilter'; +import { kialiData } from './__fixtures__'; +import { mockEntity } from './mockEntity'; class MockKialiClient implements KialiApi { - readonly resource: FetchResponse; - readonly status: FetchResponse; - readonly config: FetchResponse; - readonly namespaces: FetchResponse; - - constructor( - fixtureData: any, - status: any = statusJson, - config: any = configJson, - namespaces: any = namespacesJson, - ) { - this.resource = fixtureData; - this.status = status; - this.config = config; - this.namespaces = namespaces; - } - - setEntity(_: Entity): void {} - - async getConfig(): Promise { - return { - errors: [], - warnings: [], - response: this.config, - }; + private entity?: Entity; + + constructor() { + this.entity = undefined; + } + + setEntity(entity?: Entity): void { + this.entity = entity; + } + + async status(): Promise { + return kialiData.status; } - async getNamespaces(): Promise { - return { - errors: [], - warnings: [], - response: this.namespaces, + async getAuthInfo(): Promise { + return kialiData.auth; + } + async getStatus(): Promise { + return kialiData.status; + } + + async getNamespaces(): Promise { + return filterNsByAnnotation( + kialiData.namespaces as Namespace[], + this.entity, + ); + } + + async getServerConfig(): Promise { + return kialiData.config; + } + + async getNamespaceAppHealth( + namespace: string, + duration: DurationInSeconds, + cluster?: string, + queryTime?: TimeInSeconds, + ): Promise { + const ret: NamespaceAppHealth = {}; + const params: any = { + type: 'app', + rateInterval: `${String(duration)}s`, + queryTime: String(queryTime), + clusterName: cluster, }; + const data = kialiData.namespacesData[namespace].health[params.type]; + Object.keys(data).forEach(k => { + ret[k] = AppHealth.fromJson(namespace, k, data[k], { + rateInterval: duration, + hasSidecar: true, + hasAmbient: false, + }); + }); + return ret; } - async getInfo(): Promise { - return { - errors: [], - warnings: [], - response: this.status, + async getNamespaceServiceHealth( + namespace: string, + duration: DurationInSeconds, + cluster?: string, + queryTime?: TimeInSeconds, + ): Promise { + const ret: NamespaceServiceHealth = {}; + const params: any = { + type: 'service', + rateInterval: `${String(duration)}s`, + queryTime: String(queryTime), + clusterName: cluster, }; + const data = kialiData.namespacesData[namespace].health[params.type]; + Object.keys(data).forEach(k => { + ret[k] = ServiceHealth.fromJson(namespace, k, data[k], { + rateInterval: duration, + hasSidecar: true, + hasAmbient: false, + }); + }); + return ret; } - async getOverview(): Promise { - return { - errors: [], - warnings: [], - response: this.resource, + async getNamespaceWorkloadHealth( + namespace: string, + duration: DurationInSeconds, + cluster?: string, + queryTime?: TimeInSeconds, + ): Promise { + const ret: NamespaceWorkloadHealth = {}; + const params: any = { + type: 'workload', + rateInterval: `${String(duration)}s`, + queryTime: String(queryTime), + clusterName: cluster, }; + const data = kialiData.namespacesData[namespace].health[params.type]; + Object.keys(data).forEach(k => { + ret[k] = WorkloadHealth.fromJson(namespace, k, data[k], { + rateInterval: duration, + hasSidecar: true, + hasAmbient: false, + }); + }); + return ret; + } + + async getNamespaceTls( + namespace: string, + cluster?: string, + ): Promise { + const queryParams: any = {}; + if (cluster) { + queryParams.clusterName = cluster; + } + return kialiData.namespacesData[namespace].tls; + } + + async getMeshTls(cluster?: string): Promise { + const queryParams: any = {}; + if (cluster) { + queryParams.clusterName = cluster; + } + return kialiData.meshTls; + } + + async getOutboundTrafficPolicyMode(): Promise { + return kialiData.outboundTrafficPolicy; + } + + async getCanaryUpgradeStatus(): Promise { + return kialiData.meshCanaryStatus; + } + + async getIstiodResourceThresholds(): Promise { + return kialiData.meshIstioResourceThresholds; + } + + async getConfigValidations(cluster?: string): Promise { + const queryParams: any = {}; + if (cluster) { + queryParams.clusterName = cluster; + } + return kialiData.istioValidations; + } + + async getAllIstioConfigs( + namespaces: string[], + objects: string[], + validate: boolean, + labelSelector: string, + workloadSelector: string, + cluster?: string, + ): Promise { + const params: any = + namespaces && namespaces.length > 0 + ? { namespaces: namespaces.join(',') } + : {}; + if (objects && objects.length > 0) { + params.objects = objects.join(','); + } + if (validate) { + params.validate = validate; + } + if (labelSelector) { + params.labelSelector = labelSelector; + } + if (workloadSelector) { + params.workloadSelector = workloadSelector; + } + if (cluster) { + params.clusterName = cluster; + } + return kialiData.istioConfig; + } + + async getNamespaceMetrics( + namespace: string, + params: IstioMetricsOptions, + ): Promise> { + return kialiData.namespacesData[namespace].metrics[params.direction][ + params.duration as number + ]; + } + + async getIstioStatus(cluster?: string): Promise { + const queryParams: any = {}; + if (cluster) { + queryParams.clusterName = cluster; + } + return kialiData.istioStatus; + } + + async getIstioCertsInfo(): Promise { + return kialiData.istioCertsInfo; + } + isDevEnv(): boolean { + return true; } } +// @ts-expect-error +const MockProvider = ({ children }) => ( + + + {children} + + +); createDevApp() .registerPlugin(kialiPlugin) .addPage({ element: ( - - - - - - ), - title: 'Kiali Plugin Page', - path: '/kiali', - }) - .addPage({ - element: ( - - - - - + + + ), title: 'Overview Page', path: '/kiali/overview', diff --git a/plugins/kiali/dev/mockEntity.ts b/plugins/kiali/dev/mockEntity.ts new file mode 100644 index 0000000000..38ef109873 --- /dev/null +++ b/plugins/kiali/dev/mockEntity.ts @@ -0,0 +1,19 @@ +import { Entity } from '@backstage/catalog-model'; + +export const mockEntity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'backstage', + description: 'backstage.io', + annotations: { + 'backstage.io/kubernetes-namespace': + 'istio-system,bookinfo,travel-agency,travel-portal,travel-control', + }, + }, + spec: { + lifecycle: 'production', + type: 'service', + owner: 'user:guest', + }, +}; diff --git a/plugins/kiali/images/overview_tab.png b/plugins/kiali/images/overview_tab.png index 5a94aca9f9..e64e5ed802 100644 Binary files a/plugins/kiali/images/overview_tab.png and b/plugins/kiali/images/overview_tab.png differ diff --git a/plugins/kiali/package.json b/plugins/kiali/package.json index 35dabf5428..7d2dc2e1b8 100644 --- a/plugins/kiali/package.json +++ b/plugins/kiali/package.json @@ -31,13 +31,25 @@ "@backstage/errors": "^1.2.3", "@backstage/plugin-catalog-react": "^1.8.5", "@backstage/theme": "^0.4.3", - "@janus-idp/backstage-plugin-kiali-common": "1.4.1", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.11.3", "@material-ui/lab": "^4.0.0-alpha.45", "@patternfly/patternfly": "^5.1.0", "@patternfly/react-charts": "^7.1.1", - "react-use": "^17.4.0" + "@patternfly/react-core": "^5.1.1", + "@patternfly/react-icons": "^5.1.1", + "axios": "^1.5.1", + "cytoscape": "3.15.5", + "deep-freeze": "0.0.1", + "history": "^5.3.0", + "json-beautify": "1.0.1", + "lodash": "^4.17.21", + "moment": "^2.29.4", + "react-ace": "9.1.3", + "react-copy-to-clipboard": "5.x", + "react-use": "^17.4.0", + "typesafe-actions": "^4.2.1", + "typestyle": "^2.4.0" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0", @@ -52,14 +64,21 @@ "@testing-library/jest-dom": "5.17.0", "@testing-library/react": "12.1.5", "@testing-library/user-event": "14.5.1", - "@types/node": "18.18.5", + "@types/node": "20.2.5", + "@types/react-copy-to-clipboard": "^5.0.6", + "@types/react-router-dom": "^5.2.0", "cross-fetch": "4.0.0", - "msw": "1.3.2" + "jest-canvas-mock": "^2.5.2", + "msw": "1.3.2", + "react": "17.0.2", + "react-dom": "17.0.2", + "react-router-dom": "6.14.1" }, "files": [ "dist", "dist-scalprum" ], + "configSchema": "config.d.ts", "repository": "github:janus-idp/backstage-plugins", "keywords": [ "backstage", diff --git a/plugins/kiali/src/Router.tsx b/plugins/kiali/src/Router.tsx index d9d27177c6..a9e238f3fb 100644 --- a/plugins/kiali/src/Router.tsx +++ b/plugins/kiali/src/Router.tsx @@ -7,12 +7,13 @@ import { useEntity } from '@backstage/plugin-catalog-react'; import { Button } from '@material-ui/core'; -import { KUBERNETES_NAMESPACE } from '@janus-idp/backstage-plugin-kiali-common'; - -import { KialiComponent, KialiNoPath } from './components/KialiComponent'; +import { KialiNoPath, KialiPage } from './pages/Kiali'; +import { KialiProvider } from './store/KialiProvider'; export const KUBERNETES_ANNOTATION = 'backstage.io/kubernetes-id'; -const KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION = +export const KUBERNETES_NAMESPACE = 'backstage.io/kubernetes-namespace'; + +export const KUBERNETES_LABEL_SELECTOR_QUERY_ANNOTATION = 'backstage.io/kubernetes-label-selector'; export const isKubernetesAvailable = (entity: Entity) => @@ -38,11 +39,13 @@ export const Router = () => { kubernetesLabelSelectorQueryAnnotationValue ) { return ( - - } /> - } /> - } /> - + + + } /> + } /> + } /> + + ); } diff --git a/plugins/kiali/src/actions/ActionKeys.ts b/plugins/kiali/src/actions/ActionKeys.ts new file mode 100644 index 0000000000..004213390f --- /dev/null +++ b/plugins/kiali/src/actions/ActionKeys.ts @@ -0,0 +1,106 @@ +export enum ActionKeys { + INCREMENT_LOADING_COUNTER = 'INCREMENT_LOADING_COUNTER', + DECREMENT_LOADING_COUNTER = 'DECREMENT_LOADING_COUNTER', + SET_PAGE_VISIBILITY_HIDDEN = 'SET_PAGE_VISIBILITY_HIDDEN', + SET_PAGE_VISIBILITY_VISIBLE = 'SET_PAGE_VISIBILITY_VISIBLE', + + GRAPH_ON_NAMESPACE_CHANGE = 'GRAPH_ON_NAMESPACE_CHANGE', + GRAPH_SET_DEFINITION = 'GRAPH_SET_DEFINITION', + GRAPH_SET_EDGE_MODE = 'GRAPH_SET_EDGE_MODE', + GRAPH_SET_LAYOUT = 'GRAPH_SET_LAYOUT', + GRAPH_SET_NAMESPACE_LAYOUT = 'GRAPH_SET_NAMESPACE_LAYOUT', + GRAPH_SET_NODE = 'GRAPH_SET_NODE', + GRAPH_SET_RANK_RESULT = 'GRAPH_SET_RANK_RESULT', + GRAPH_SET_UPDATE_TIME = 'GRAPH_SET_UPDATE_TIME', + + GRAPH_TOOLBAR_RESET_SETTINGS = 'GRAPH_TOOLBAR_RESET_SETTINGS', + + GRAPH_TOOLBAR_SET_EDGE_LABELS = 'GRAPH_TOOLBAR_SET_EDGE_LABEL_MODE', + GRAPH_TOOLBAR_SET_FIND_VALUE = 'GRAPH_TOOLBAR_SET_FIND_VALUE', + GRAPH_TOOLBAR_SET_GRAPH_TYPE = 'GRAPH_TOOLBAR_SET_GRAPH_TYPE', + GRAPH_TOOLBAR_SET_HIDE_VALUE = 'GRAPH_TOOLBAR_SET_HIDE_VALUE', + GRAPH_TOOLBAR_SET_IDLE_NODES = 'GRAPH_TOOLBAR_SET_IDLE_NODES', + GRAPH_TOOLBAR_SET_RANK_BY = 'GRAPH_TOOLBAR_SET_RANK_BY', + GRAPH_TOOLBAR_SET_TRAFFIC_RATES = 'GRAPH_TOOLBAR_SET_TRAFFIC_RATES', + + // Toggle Actions + GRAPH_TOOLBAR_TOGGLE_BOX_BY_CLUSTER = 'GRAPH_TOOLBAR_TOGGLE_BOX_BY_CLUSTER', + GRAPH_TOOLBAR_TOGGLE_BOX_BY_NAMESPACE = 'GRAPH_TOOLBAR_TOGGLE_BOX_BY_NAMESPACE', + GRAPH_TOOLBAR_TOGGLE_COMPRESS_ON_HIDE = 'GRAPH_TOOLBAR_TOGGLE_COMPRESS_ON_HIDE', + GRAPH_TOOLBAR_TOGGLE_GRAPH_VIRTUAL_SERVICES = 'GRAPH_TOOLBAR_TOGGLE_GRAPH_VIRTUAL_SERVICES', + GRAPH_TOOLBAR_TOGGLE_GRAPH_MISSING_SIDECARS = 'GRAPH_TOOLBAR_TOGGLE_GRAPH_MISSING_SIDECARS', + GRAPH_TOOLBAR_TOGGLE_GRAPH_SECURITY = 'GRAPH_TOOLBAR_TOGGLE_GRAPH_SECURITY', + GRAPH_TOOLBAR_TOGGLE_LEGEND = 'GRAPH_TOOLBAR_TOGGLE_LEGEND', + GRAPH_TOOLBAR_TOGGLE_FIND_HELP = 'GRAPH_TOOLBAR_TOGGLE_FIND_HELP', + GRAPH_TOOLBAR_TOGGLE_IDLE_EDGES = 'GRAPH_TOOLBAR_TOGGLE_IDLE_EDGES', + GRAPH_TOOLBAR_TOGGLE_IDLE_NODES = 'GRAPH_TOOLBAR_TOGGLE_IDLE_NODES', + GRAPH_TOOLBAR_TOGGLE_OPERATION_NODES = 'GRAPH_TOOLBAR_TOGGLE_OPERATION_NODES', + GRAPH_TOOLBAR_TOGGLE_RANK = 'GRAPH_TOOLBAR_TOGGLE_RANK', + GRAPH_TOOLBAR_TOGGLE_RANK_BY = 'GRAPH_TOOLBAR_TOGGLE_RANK_BY', + GRAPH_TOOLBAR_TOGGLE_SERVICE_NODES = 'GRAPH_TOOLBAR_TOGGLE_SERVICE_NODES', + GRAPH_TOOLBAR_TOGGLE_TRAFFIC_ANIMATION = 'GRAPH_TOOLBAR_TOGGLE_TRAFFIC_ANIMATION', + + GRAPH_UPDATE_SUMMARY = 'GRAPH_UPDATE_SUMMARY', + + // Disable Actions + ENABLE_GRAPH_FILTERS = 'ENABLE_GRAPH_FILTERS', + + HELP_STATUS_REFRESH = 'HELP_STATUS_REFRESH', + + JAEGER_SET_URL = 'JAEGER_SET_URL', + JAEGER_SET_ENABLED = 'JAEGER_SET_ENABLED', + JAEGER_SET_INFO = 'JAEGER_SET_INFO', + JAEGER_SET_TRACE_ID = 'JAEGER_SET_TRACE_ID', + JAEGER_SET_TRACE = 'JAEGER_SET_TRACE', + + LOGIN_REQUEST = 'LOGIN_REQUEST', + LOGIN_EXTEND = 'LOGIN_EXTEND', + LOGIN_SUCCESS = 'LOGIN_SUCCESS', + LOGIN_FAILURE = 'LOGIN_FAILURE', + LOGOUT_SUCCESS = 'LOGOUT_SUCCESS', + SESSION_EXPIRED = 'SESSION_EXPIRED', + SET_LANDING_ROUTE = 'SET_LANDING_ROUTE', + + MTLS_SET_INFO = 'MTLS_SET_INFO', + + ISTIO_STATUS_SET_INFO = 'ISTIO_STATUS_SET_INFO', + ISTIO_SET_CERTS_INFO = 'ISTIO_SET_CERTS_INFO', + + MC_ADD_MESSAGE = 'MC_ADD_MESSAGE', + MC_REMOVE_MESSAGE = 'MC_REMOVE_MESSAGE', + MC_MARK_MESSAGE_AS_READ = 'MC_MARK_MESSAGE_AS_READ', + MC_TOGGLE_MESSAGE_DETAIL = 'MC_TOGGLE_MESSAGE_DETAIL', + MC_SHOW = 'MC_SHOW', + MC_HIDE = 'MC_HIDE', + MC_TOGGLE_EXPAND = 'MC_TOGGLE_EXPAND', + MC_TOGGLE_GROUP = 'MC_TOGGLE_GROUP', + MC_HIDE_NOTIFICATION = 'MC_HIDE_NOTIFICATION', + MC_EXPAND_GROUP = 'MC_EXPAND_GROUP', + + METRICS_STATS_SET = 'METRICS_STATS_SET', + + NAMESPACE_REQUEST_STARTED = 'NAMESPACE_REQUEST_STARTED', + NAMESPACE_SUCCESS = 'NAMESPACE_SUCCESS', + NAMESPACE_FAILED = 'NAMESPACE_FAILED', + TOGGLE_ACTIVE_NAMESPACE = 'TOGGLE_ACTIVE_NAMESPACE', + SET_ACTIVE_NAMESPACES = 'SET_ACTIVE_NAMESPACES', + NAMESPACE_SET_FILTER = 'NAMESPACE_SET_FILTER', + + CLUSTER_SET_FILTER = 'CLUSTER_SET_FILTER', + SET_ACTIVE_CLUSTERS = 'SET_ACTIVE_CLUSTERS', + TOGGLE_ACTIVE_CLUSTER = 'TOGGLE_ACTIVE_CLUSTER', + + NAV_COLLAPSE = 'NAV_COLLAPSE', + SET_DURATION = 'SET_DURATION', + SET_KIOSK = 'SET_KIOSK', + SET_THEME = 'SET_THEME', + SET_LAST_REFRESH = 'SET_LAST_REFRESH', + SET_REFRESH_INTERVAL = 'SET_REFRESH_INTERVAL', + SET_REPLAY_QUERY_TIME = 'SET_REPLAY_QUERY_TIME', + SET_TIME_RANGE = 'SET_TIME_RANGE', + TOGGLE_REPLAY_ACTIVE = 'TOGGLE_REPLAY_ACTIVE', + + TOUR_END = 'TOUR_END', + TOUR_SET_STOP = 'TOUR_SET_STOP', + TOUR_START = 'TOUR_START', +} diff --git a/plugins/kiali/src/actions/HelpDropdownActions.ts b/plugins/kiali/src/actions/HelpDropdownActions.ts new file mode 100644 index 0000000000..3c794dbe8d --- /dev/null +++ b/plugins/kiali/src/actions/HelpDropdownActions.ts @@ -0,0 +1,19 @@ +import { ActionType, createAction } from 'typesafe-actions'; + +import { StatusState } from '../types/StatusState'; +import { ActionKeys } from './ActionKeys'; + +export const HelpDropdownActions: { [key: string]: any } = { + statusRefresh: createAction( + ActionKeys.HELP_STATUS_REFRESH, + resolve => (status: StatusState) => + resolve({ + status: status.status, + externalServices: status.externalServices, + warningMessages: status.warningMessages, + istioEnvironment: status.istioEnvironment, + }), + ), +}; + +export type HelpDropdownAction = ActionType; diff --git a/plugins/kiali/src/actions/IstioCertsInfoActions.ts b/plugins/kiali/src/actions/IstioCertsInfoActions.ts new file mode 100644 index 0000000000..125e4dc31e --- /dev/null +++ b/plugins/kiali/src/actions/IstioCertsInfoActions.ts @@ -0,0 +1,10 @@ +import { ActionType, createStandardAction } from 'typesafe-actions'; + +import { CertsInfo } from '../types/CertsInfo'; +import { ActionKeys } from './ActionKeys'; + +export const IstioCertsInfoActions = { + setinfo: createStandardAction(ActionKeys.ISTIO_SET_CERTS_INFO)(), +}; + +export type IstioCertsInfoAction = ActionType; diff --git a/plugins/kiali/src/actions/IstioStatusActions.ts b/plugins/kiali/src/actions/IstioStatusActions.ts new file mode 100644 index 0000000000..608e0c25dd --- /dev/null +++ b/plugins/kiali/src/actions/IstioStatusActions.ts @@ -0,0 +1,12 @@ +import { ActionType, createStandardAction } from 'typesafe-actions'; + +import { ComponentStatus } from '../types/IstioStatus'; +import { ActionKeys } from './ActionKeys'; + +export const IstioStatusActions = { + setinfo: createStandardAction(ActionKeys.ISTIO_STATUS_SET_INFO)< + ComponentStatus[] + >(), +}; + +export type IstioStatusAction = ActionType; diff --git a/plugins/kiali/src/actions/KialiAppAction.ts b/plugins/kiali/src/actions/KialiAppAction.ts new file mode 100644 index 0000000000..e7a0278ba2 --- /dev/null +++ b/plugins/kiali/src/actions/KialiAppAction.ts @@ -0,0 +1,18 @@ +import { HelpDropdownAction } from './HelpDropdownActions'; +import { IstioCertsInfoAction } from './IstioCertsInfoActions'; +import { IstioStatusAction } from './IstioStatusActions'; +import { LoginAction } from './LoginActions'; +import { MeshTlsAction } from './MeshTlsActions'; +import { MessageCenterAction } from './MessageCenterActions'; +import { NamespaceAction } from './NamespaceAction'; +import { UserSettingsAction } from './UserSettingsActions'; + +export type KialiAppAction = + | HelpDropdownAction + | LoginAction + | NamespaceAction + | UserSettingsAction + | IstioCertsInfoAction + | IstioStatusAction + | MeshTlsAction + | MessageCenterAction; diff --git a/plugins/kiali/src/actions/LoginActions.ts b/plugins/kiali/src/actions/LoginActions.ts new file mode 100644 index 0000000000..a74dbcc9e4 --- /dev/null +++ b/plugins/kiali/src/actions/LoginActions.ts @@ -0,0 +1,63 @@ +import { + ActionType, + createAction, + createStandardAction, +} from 'typesafe-actions'; + +import { LoginSession, LoginStatus } from '../store/Store'; +import { ActionKeys } from './ActionKeys'; + +export interface LoginPayload { + error?: any; + landingRoute?: string; + session?: LoginSession; + status: LoginStatus; +} + +// synchronous action creators +export const LoginActions: { [key: string]: any } = { + loginRequest: createAction(ActionKeys.LOGIN_REQUEST), + loginExtend: createAction( + ActionKeys.LOGIN_EXTEND, + resolve => (session: LoginSession) => + resolve({ + status: LoginStatus.loggedIn, + session: session, + error: undefined, + } as LoginPayload), + ), + loginSuccess: createAction( + ActionKeys.LOGIN_SUCCESS, + resolve => (session: LoginSession) => + resolve({ + status: LoginStatus.loggedIn, + session: session, + error: undefined, + uiExpiresOn: session.expiresOn, + } as LoginPayload), + ), + loginFailure: createAction( + ActionKeys.LOGIN_FAILURE, + resolve => (error: any) => + resolve({ + status: LoginStatus.error, + session: undefined, + error: error, + } as LoginPayload), + ), + logoutSuccess: createAction( + ActionKeys.LOGOUT_SUCCESS, + resolve => () => + resolve({ + status: LoginStatus.loggedOut, + session: undefined, + error: undefined, + } as LoginPayload), + ), + sessionExpired: createAction(ActionKeys.SESSION_EXPIRED), + setLandingRoute: createStandardAction(ActionKeys.SET_LANDING_ROUTE)< + string | undefined + >(), +}; + +export type LoginAction = ActionType; diff --git a/plugins/kiali/src/actions/MeshTlsActions.ts b/plugins/kiali/src/actions/MeshTlsActions.ts new file mode 100644 index 0000000000..0612b11225 --- /dev/null +++ b/plugins/kiali/src/actions/MeshTlsActions.ts @@ -0,0 +1,10 @@ +import { ActionType, createStandardAction } from 'typesafe-actions'; + +import { TLSStatus } from '../types/TLSStatus'; +import { ActionKeys } from './ActionKeys'; + +export const MeshTlsActions = { + setinfo: createStandardAction(ActionKeys.MTLS_SET_INFO)(), +}; + +export type MeshTlsAction = ActionType; diff --git a/plugins/kiali/src/actions/MessageCenterActions.ts b/plugins/kiali/src/actions/MessageCenterActions.ts new file mode 100644 index 0000000000..e382ff3a1c --- /dev/null +++ b/plugins/kiali/src/actions/MessageCenterActions.ts @@ -0,0 +1,59 @@ +import { ActionType, createAction } from 'typesafe-actions'; + +import { MessageType } from '../types/MessageCenter'; +import { ActionKeys } from './ActionKeys'; + +const DEFAULT_GROUP_ID = 'default'; +const DEFAULT_MESSAGE_TYPE = MessageType.ERROR; + +type numberOrNumberArray = number | number[]; + +const toNumberArray = (n: numberOrNumberArray) => (Array.isArray(n) ? n : [n]); + +export const MessageCenterActions = { + addMessage: createAction( + ActionKeys.MC_ADD_MESSAGE, + resolve => + ( + content: string, + detail: string, + groupId: string = DEFAULT_GROUP_ID, + messageType: MessageType = DEFAULT_MESSAGE_TYPE, + showNotification: boolean = true, + ) => + resolve({ content, detail, groupId, messageType, showNotification }), + ), + removeMessage: createAction( + ActionKeys.MC_REMOVE_MESSAGE, + resolve => (messageId: numberOrNumberArray) => + resolve({ messageId: toNumberArray(messageId) }), + ), + toggleMessageDetail: createAction( + ActionKeys.MC_TOGGLE_MESSAGE_DETAIL, + resolve => (messageId: numberOrNumberArray) => + resolve({ messageId: toNumberArray(messageId) }), + ), + markAsRead: createAction( + ActionKeys.MC_MARK_MESSAGE_AS_READ, + resolve => (messageId: numberOrNumberArray) => + resolve({ messageId: toNumberArray(messageId) }), + ), + toggleGroup: createAction( + ActionKeys.MC_TOGGLE_GROUP, + resolve => (groupId: string) => resolve({ groupId }), + ), + expandGroup: createAction( + ActionKeys.MC_EXPAND_GROUP, + resolve => (groupId: string) => resolve({ groupId }), + ), + hideNotification: createAction( + ActionKeys.MC_HIDE_NOTIFICATION, + resolve => (messageId: numberOrNumberArray) => + resolve({ messageId: toNumberArray(messageId) }), + ), + showMessageCenter: createAction(ActionKeys.MC_SHOW), + hideMessageCenter: createAction(ActionKeys.MC_HIDE), + toggleExpandedMessageCenter: createAction(ActionKeys.MC_TOGGLE_EXPAND), +}; + +export type MessageCenterAction = ActionType; diff --git a/plugins/kiali/src/actions/NamespaceAction.ts b/plugins/kiali/src/actions/NamespaceAction.ts new file mode 100644 index 0000000000..55201d68c7 --- /dev/null +++ b/plugins/kiali/src/actions/NamespaceAction.ts @@ -0,0 +1,30 @@ +import { + ActionType, + createAction, + createStandardAction, +} from 'typesafe-actions'; + +import { Namespace } from '../types/Namespace'; +import { ActionKeys } from './ActionKeys'; + +export const NamespaceActions = { + toggleActiveNamespace: createStandardAction( + ActionKeys.TOGGLE_ACTIVE_NAMESPACE, + )(), + setActiveNamespaces: createStandardAction(ActionKeys.SET_ACTIVE_NAMESPACES)< + Namespace[] + >(), + setFilter: createStandardAction(ActionKeys.NAMESPACE_SET_FILTER)(), + requestStarted: createAction(ActionKeys.NAMESPACE_REQUEST_STARTED), + requestFailed: createAction(ActionKeys.NAMESPACE_FAILED), + receiveList: createAction( + ActionKeys.NAMESPACE_SUCCESS, + resolve => (newList: Namespace[], receivedAt: Date) => + resolve({ + list: newList, + receivedAt: receivedAt, + }), + ), +}; + +export type NamespaceAction = ActionType; diff --git a/plugins/kiali/src/actions/UserSettingsActions.ts b/plugins/kiali/src/actions/UserSettingsActions.ts new file mode 100644 index 0000000000..bc758c545a --- /dev/null +++ b/plugins/kiali/src/actions/UserSettingsActions.ts @@ -0,0 +1,33 @@ +import { + ActionType, + createAction, + createStandardAction, +} from 'typesafe-actions'; + +import { + DurationInSeconds, + IntervalInMilliseconds, + TimeInMilliseconds, + TimeRange, +} from '../types/Common'; +import { ActionKeys } from './ActionKeys'; + +export const UserSettingsActions = { + navCollapse: createAction( + ActionKeys.NAV_COLLAPSE, + resolve => (collapsed: boolean) => resolve({ collapse: collapsed }), + ), + setDuration: createStandardAction( + ActionKeys.SET_DURATION, + )(), + setTimeRange: createStandardAction(ActionKeys.SET_TIME_RANGE)(), + setRefreshInterval: createStandardAction( + ActionKeys.SET_REFRESH_INTERVAL, + )(), + setReplayQueryTime: createStandardAction( + ActionKeys.SET_REPLAY_QUERY_TIME, + )(), + toggleReplayActive: createAction(ActionKeys.TOGGLE_REPLAY_ACTIVE), +}; + +export type UserSettingsAction = ActionType; diff --git a/plugins/kiali/src/actions/index.ts b/plugins/kiali/src/actions/index.ts new file mode 100644 index 0000000000..698497743b --- /dev/null +++ b/plugins/kiali/src/actions/index.ts @@ -0,0 +1,4 @@ +export * from './HelpDropdownActions'; +export * from './LoginActions'; +export * from './MessageCenterActions'; +export * from './NamespaceAction'; diff --git a/plugins/kiali/src/api/apiClient.ts b/plugins/kiali/src/api/apiClient.ts deleted file mode 100644 index c774d5aad3..0000000000 --- a/plugins/kiali/src/api/apiClient.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; -import { - createApiRef, - DiscoveryApi, - IdentityApi, -} from '@backstage/core-plugin-api'; - -import { - DirectionType, - FetchResponseWrapper, - OverviewType, -} from '@janus-idp/backstage-plugin-kiali-common'; - -export interface KialiApi { - getConfig(): Promise; - getInfo(): Promise; - getOverview( - overviewType: OverviewType, - duration: number, - direction: DirectionType, - ): Promise; - getNamespaces(): Promise; - setEntity(entity: Entity): void; -} - -export const kialiApiRef = createApiRef({ - id: 'plugin.kiali.service', -}); - -export const KialiEndpoints = { - getInfo: 'info', - getOverview: 'overview', - getConfig: 'config', - getNamespaces: 'namespaces', -}; - -/** - * Provides A KialiClient class to query backend - */ -export class KialiApiClient implements KialiApi { - private readonly discoveryApi: DiscoveryApi; - private readonly identityApi: IdentityApi; - protected entity: Entity | null; - - constructor(options: { - discoveryApi: DiscoveryApi; - identityApi: IdentityApi; - }) { - this.discoveryApi = options.discoveryApi; - this.identityApi = options.identityApi; - this.entity = null; - } - - setEntity = (entity: Entity) => { - this.entity = entity; - }; - - private async getAPI( - endpoint: string, - requestBody: any, - ): Promise { - const url = `${await this.discoveryApi.getBaseUrl('kiali')}/${endpoint}`; - const { token: idToken } = await this.identityApi.getCredentials(); - const jsonResponse = await fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - ...(idToken && { Authorization: `Bearer ${idToken}` }), - }, - body: JSON.stringify(requestBody), - }); - return jsonResponse.json(); - } - - async getInfo(): Promise { - return this.getAPI(KialiEndpoints.getInfo, {}); - } - - async getNamespaces(): Promise { - const requestBody = { - entityRef: this.entity ? stringifyEntityRef(this.entity) : '', - }; - return this.getAPI(KialiEndpoints.getNamespaces, requestBody); - } - - async getConfig(): Promise { - const requestBody = { - entityRef: this.entity ? stringifyEntityRef(this.entity) : '', - }; - return this.getAPI(KialiEndpoints.getConfig, requestBody); - } - - async getOverview( - overviewType: OverviewType, - duration: number, - direction: DirectionType, - ): Promise { - const requestBody = { - entityRef: this.entity ? stringifyEntityRef(this.entity) : '', - query: { - duration, - overviewType, - direction, - }, - }; - return this.getAPI(KialiEndpoints.getOverview, requestBody); - } -} diff --git a/plugins/kiali/src/api/index.ts b/plugins/kiali/src/api/index.ts deleted file mode 100644 index dcb4f49d74..0000000000 --- a/plugins/kiali/src/api/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './apiClient'; diff --git a/plugins/kiali/src/app/History.ts b/plugins/kiali/src/app/History.ts new file mode 100644 index 0000000000..3c25ac51f4 --- /dev/null +++ b/plugins/kiali/src/app/History.ts @@ -0,0 +1,220 @@ +import { + createBrowserHistory, + createHashHistory, + createMemoryHistory, +} from 'history'; + +import { toValidDuration } from '../config/ServerConfig'; +import { BoundsInMilliseconds } from '../types/Common'; + +const historyMode = (window as any).HISTORY_MODE + ? (window as any).HISTORY_MODE + : 'browser'; + +const createHistory = () => { + if (process.env.TEST_RUNNER) { + return createMemoryHistory(); + } else if (historyMode === 'hash') { + return createHashHistory(); + } + return createBrowserHistory(); +}; + +let history = createHistory(); + +/** + * Some platforms set a different basename for each page (e.g., Openshift Console) + * A setHistory method is defined to be able to modify the history basename when user + * routes to a different page within Kiali in these platforms. + * This method is not used in standalone Kiali application + */ +export const setHistory = () => { + history = createHistory(); +}; + +export { history }; + +export enum URLParam { + AGGREGATOR = 'aggregator', + BY_LABELS = 'bylbl', + CLUSTERNAME = 'clusterName', + DIRECTION = 'direction', + DISPLAY_MODE = 'displayMode', + DURATION = 'duration', + FOCUS_SELECTOR = 'focusSelector', + FROM = 'from', + GRAPH_ANIMATION = 'animation', + GRAPH_BADGE_SECURITY = 'badgeSecurity', + GRAPH_BADGE_SIDECAR = 'badgeSidecar', + GRAPH_BADGE_VS = 'badgeVS', + GRAPH_BOX_CLUSTER = 'boxCluster', + GRAPH_BOX_NAMESPACE = 'boxNamespace', + GRAPH_COMPRESS_ON_HIDE = 'graphCompressOnHide', + GRAPH_EDGE_LABEL = 'edges', + GRAPH_EDGE_MODE = 'edgeMode', + GRAPH_FIND = 'graphFind', + GRAPH_HIDE = 'graphHide', + GRAPH_IDLE_EDGES = 'idleEdges', + GRAPH_IDLE_NODES = 'idleNodes', + GRAPH_LAYOUT = 'layout', + GRAPH_NAMESPACE_LAYOUT = 'namespaceLayout', + GRAPH_OPERATION_NODES = 'operationNodes', + GRAPH_RANK = 'rank', + GRAPH_RANK_BY = 'rankBy', + GRAPH_REPLAY_ACTIVE = 'replayActive', + GRAPH_REPLAY_INTERVAL = 'replayInterval', + GRAPH_REPLAY_START = 'replayStart', + GRAPH_SERVICE_NODES = 'injectServiceNodes', + GRAPH_TRAFFIC = 'traffic', + GRAPH_TYPE = 'graphType', + JAEGER_ERRORS_ONLY = 'errs', + JAEGER_LIMIT_TRACES = 'limit', + JAEGER_PERCENTILE = 'percentile', + JAEGER_SHOW_SPANS_AVG = 'showSpansAvg', + JAEGER_TRACE_ID = 'traceId', + JAEGER_SPAN_ID = 'spanId', + NAMESPACES = 'namespaces', + OVERVIEW_TYPE = 'otype', + DIRECTION_TYPE = 'drtype', + QUANTILES = 'quantiles', + RANGE_DURATION = 'rangeDuration', + REFRESH_INTERVAL = 'refresh', + REPORTER = 'reporter', + SHOW_AVERAGE = 'avg', + SHOW_SPANS = 'spans', + SHOW_TRENDLINES = 'trendlines', + SORT = 'sort', + TO = 'to', + EXPERIMENTAL_FLAGS = 'xflags', +} + +export interface URLParamValue { + name: URLParam; + value: any; +} + +export enum ParamAction { + APPEND, + SET, +} + +export class HistoryManager { + static setParam = (name: URLParam | string, value: string) => { + const urlParams = new URLSearchParams(history.location.search); + urlParams.set(name, value); + history.replace(`${history.location.pathname}?${urlParams.toString()}`); + }; + + static getParam = ( + name: URLParam | string, + urlParams?: URLSearchParams, + ): string | undefined => { + let calculatedParams: URLSearchParams | undefined = urlParams; + if (!calculatedParams) { + calculatedParams = new URLSearchParams(history.location.search); + } + const p = calculatedParams.get(name); + return p ?? undefined; + }; + + static getNumericParam = ( + name: URLParam, + urlParams?: URLSearchParams, + ): number | undefined => { + const p = HistoryManager.getParam(name, urlParams); + return p !== undefined ? Number(p) : undefined; + }; + + static getBooleanParam = ( + name: URLParam | string, + urlParams?: URLSearchParams, + ): boolean | undefined => { + const p = HistoryManager.getParam(name, urlParams); + return p !== undefined ? p === 'true' : undefined; + }; + + static deleteParam = (name: URLParam, historyReplace?: boolean) => { + const urlParams = new URLSearchParams(history.location.search); + urlParams.delete(name); + if (historyReplace) { + history.replace(`${history.location.pathname}?${urlParams.toString()}`); + } else { + history.push(`${history.location.pathname}?${urlParams.toString()}`); + } + }; + + static setParams = ( + params: URLParamValue[], + paramAction?: ParamAction, + historyReplace?: boolean, + ) => { + const urlParams = new URLSearchParams(history.location.search); + + if (params.length > 0 && paramAction === ParamAction.APPEND) { + params.forEach(param => urlParams.delete(param.name)); + } + + params.forEach(param => { + if (param.value === '') { + urlParams.delete(param.name); + } else if (paramAction === ParamAction.APPEND) { + urlParams.append(param.name, param.value); + } else { + urlParams.set(param.name, param.value); + } + }); + + if (historyReplace) { + history.replace(`${history.location.pathname}?${urlParams.toString()}`); + } else { + history.push(`${history.location.pathname}?${urlParams.toString()}`); + } + }; + + static getClusterName = (urlParams?: URLSearchParams): string | undefined => { + let calculatedParams: URLSearchParams | undefined = urlParams; + if (!calculatedParams) { + calculatedParams = new URLSearchParams(history.location.search); + } + return calculatedParams.get(URLParam.CLUSTERNAME) || undefined; + }; + + static getDuration = (urlParams?: URLSearchParams): number | undefined => { + const duration = HistoryManager.getNumericParam( + URLParam.DURATION, + urlParams, + ); + if (duration) { + return toValidDuration(Number(duration)); + } + return undefined; + }; + + static getRangeDuration = ( + urlParams?: URLSearchParams, + ): number | undefined => { + const rangeDuration = HistoryManager.getNumericParam( + URLParam.RANGE_DURATION, + urlParams, + ); + if (rangeDuration) { + return toValidDuration(Number(rangeDuration)); + } + return undefined; + }; + + static getTimeBounds = ( + urlParams?: URLSearchParams, + ): BoundsInMilliseconds | undefined => { + const from = HistoryManager.getNumericParam(URLParam.FROM, urlParams); + if (from) { + const to = HistoryManager.getNumericParam(URLParam.TO, urlParams); + // "to" can be undefined (stands for "now") + return { + from: from, + to: to, + }; + } + return undefined; + }; +} diff --git a/plugins/kiali/src/assets/img/go-logo.png b/plugins/kiali/src/assets/img/go-logo.png new file mode 100644 index 0000000000..aee71daf20 Binary files /dev/null and b/plugins/kiali/src/assets/img/go-logo.png differ diff --git a/plugins/kiali/src/assets/img/graphql-logo.svg b/plugins/kiali/src/assets/img/graphql-logo.svg new file mode 100644 index 0000000000..95c03941cf --- /dev/null +++ b/plugins/kiali/src/assets/img/graphql-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/grpc-logo.svg b/plugins/kiali/src/assets/img/grpc-logo.svg new file mode 100644 index 0000000000..6f5c5a4c95 --- /dev/null +++ b/plugins/kiali/src/assets/img/grpc-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/hollow-pin.png b/plugins/kiali/src/assets/img/hollow-pin.png new file mode 100644 index 0000000000..14477559f6 Binary files /dev/null and b/plugins/kiali/src/assets/img/hollow-pin.png differ diff --git a/plugins/kiali/src/assets/img/jaeger-icon.svg b/plugins/kiali/src/assets/img/jaeger-icon.svg new file mode 100644 index 0000000000..d4fae63a2f --- /dev/null +++ b/plugins/kiali/src/assets/img/jaeger-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/java-logo.png b/plugins/kiali/src/assets/img/java-logo.png new file mode 100644 index 0000000000..75ad9e281b Binary files /dev/null and b/plugins/kiali/src/assets/img/java-logo.png differ diff --git a/plugins/kiali/src/assets/img/kiali-title.svg b/plugins/kiali/src/assets/img/kiali-title.svg new file mode 100644 index 0000000000..79ef71ed63 --- /dev/null +++ b/plugins/kiali/src/assets/img/kiali-title.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/aggregate.svg b/plugins/kiali/src/assets/img/legend-nooptimize/aggregate.svg new file mode 100755 index 0000000000..13908e47c4 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/aggregate.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/app.svg b/plugins/kiali/src/assets/img/legend-nooptimize/app.svg new file mode 100755 index 0000000000..a72267f4b1 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/app.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/edge-danger.svg b/plugins/kiali/src/assets/img/legend-nooptimize/edge-danger.svg new file mode 100755 index 0000000000..1fc4ed9d81 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/edge-danger.svg @@ -0,0 +1,76 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/edge-idle.svg b/plugins/kiali/src/assets/img/legend-nooptimize/edge-idle.svg new file mode 100755 index 0000000000..2c62a1eb10 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/edge-idle.svg @@ -0,0 +1,76 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/edge-success.svg b/plugins/kiali/src/assets/img/legend-nooptimize/edge-success.svg new file mode 100755 index 0000000000..65fee59c66 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/edge-success.svg @@ -0,0 +1,76 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/edge-tcp.svg b/plugins/kiali/src/assets/img/legend-nooptimize/edge-tcp.svg new file mode 100755 index 0000000000..b58e722729 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/edge-tcp.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/edge-warn.svg b/plugins/kiali/src/assets/img/legend-nooptimize/edge-warn.svg new file mode 100755 index 0000000000..e30a4ba648 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/edge-warn.svg @@ -0,0 +1,76 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/external-namespace.svg b/plugins/kiali/src/assets/img/legend-nooptimize/external-namespace.svg new file mode 100755 index 0000000000..6857f7e774 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/external-namespace.svg @@ -0,0 +1,83 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/mtls-badge.svg b/plugins/kiali/src/assets/img/legend-nooptimize/mtls-badge.svg new file mode 100755 index 0000000000..164474f83c --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/mtls-badge.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-circuit-breaker.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-circuit-breaker.svg new file mode 100755 index 0000000000..eb1ce6ec8f --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-circuit-breaker.svg @@ -0,0 +1,75 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-fault-injection.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-fault-injection.svg new file mode 100644 index 0000000000..ffd0490210 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-fault-injection.svg @@ -0,0 +1,79 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-gateways.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-gateways.svg new file mode 100755 index 0000000000..296ab4777f --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-gateways.svg @@ -0,0 +1,81 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-mirroring.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-mirroring.svg new file mode 100644 index 0000000000..c4c9ed65ce --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-mirroring.svg @@ -0,0 +1,80 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-missing-sidecar.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-missing-sidecar.svg new file mode 100755 index 0000000000..f8005984ad --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-missing-sidecar.svg @@ -0,0 +1,119 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-request-timeout.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-request-timeout.svg new file mode 100644 index 0000000000..09df86b5a9 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-request-timeout.svg @@ -0,0 +1,95 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-traffic-shifting.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-traffic-shifting.svg new file mode 100644 index 0000000000..6ee8675e05 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-traffic-shifting.svg @@ -0,0 +1,82 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-traffic-source.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-traffic-source.svg new file mode 100755 index 0000000000..e31cafcac7 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-traffic-source.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-virtual-services.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-virtual-services.svg new file mode 100755 index 0000000000..f187caa18c --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-virtual-services.svg @@ -0,0 +1,75 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-workload-entry.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-workload-entry.svg new file mode 100644 index 0000000000..cc6a5eeee9 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-badge-workload-entry.svg @@ -0,0 +1,500 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-color-danger.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-color-danger.svg new file mode 100755 index 0000000000..88fa40b792 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-color-danger.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-color-idle.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-color-idle.svg new file mode 100755 index 0000000000..21ea604d15 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-color-idle.svg @@ -0,0 +1,62 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-color-normal.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-color-normal.svg new file mode 100755 index 0000000000..bbc283b45c --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-color-normal.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node-color-warning.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node-color-warning.svg new file mode 100755 index 0000000000..759998942c --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node-color-warning.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/node.svg b/plugins/kiali/src/assets/img/legend-nooptimize/node.svg new file mode 100755 index 0000000000..eaebd1914a --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/node.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/restricted-namespace.svg b/plugins/kiali/src/assets/img/legend-nooptimize/restricted-namespace.svg new file mode 100755 index 0000000000..0a22dfc226 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/restricted-namespace.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/service-entry.svg b/plugins/kiali/src/assets/img/legend-nooptimize/service-entry.svg new file mode 100755 index 0000000000..6ec2c0432b --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/service-entry.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/service.svg b/plugins/kiali/src/assets/img/legend-nooptimize/service.svg new file mode 100755 index 0000000000..b024b386ea --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/service.svg @@ -0,0 +1,65 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/traffic-failed-request.svg b/plugins/kiali/src/assets/img/legend-nooptimize/traffic-failed-request.svg new file mode 100755 index 0000000000..881e4fc5da --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/traffic-failed-request.svg @@ -0,0 +1,78 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/traffic-normal-request.svg b/plugins/kiali/src/assets/img/legend-nooptimize/traffic-normal-request.svg new file mode 100755 index 0000000000..951171e5aa --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/traffic-normal-request.svg @@ -0,0 +1,74 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/traffic-tcp.svg b/plugins/kiali/src/assets/img/legend-nooptimize/traffic-tcp.svg new file mode 100755 index 0000000000..a7fc17472a --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/traffic-tcp.svg @@ -0,0 +1,92 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-nooptimize/virtualservice.svg b/plugins/kiali/src/assets/img/legend-nooptimize/virtualservice.svg new file mode 100755 index 0000000000..0cc7ea7759 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-nooptimize/virtualservice.svg @@ -0,0 +1,66 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-pf/aggregate.svg b/plugins/kiali/src/assets/img/legend-pf/aggregate.svg new file mode 100644 index 0000000000..ff211b6aaa --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/aggregate.svg @@ -0,0 +1,19 @@ + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-pf/app.svg b/plugins/kiali/src/assets/img/legend-pf/app.svg new file mode 100644 index 0000000000..f5ff9a691e --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/app.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/edge-danger.svg b/plugins/kiali/src/assets/img/legend-pf/edge-danger.svg new file mode 100644 index 0000000000..013913b2d6 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/edge-danger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/edge-idle.svg b/plugins/kiali/src/assets/img/legend-pf/edge-idle.svg new file mode 100644 index 0000000000..7c35624d61 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/edge-idle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/edge-success.svg b/plugins/kiali/src/assets/img/legend-pf/edge-success.svg new file mode 100644 index 0000000000..e1467ec020 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/edge-success.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/edge-tcp.svg b/plugins/kiali/src/assets/img/legend-pf/edge-tcp.svg new file mode 100644 index 0000000000..6877978009 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/edge-tcp.svg @@ -0,0 +1,12 @@ + + + + diff --git a/plugins/kiali/src/assets/img/legend-pf/edge-warn.svg b/plugins/kiali/src/assets/img/legend-pf/edge-warn.svg new file mode 100644 index 0000000000..f94a0b46c3 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/edge-warn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/external-namespace.svg b/plugins/kiali/src/assets/img/legend-pf/external-namespace.svg new file mode 100644 index 0000000000..36faf0831e --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/external-namespace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/mtls-badge.svg b/plugins/kiali/src/assets/img/legend-pf/mtls-badge.svg new file mode 100644 index 0000000000..0f2c461565 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/mtls-badge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-badge-circuit-breaker.svg b/plugins/kiali/src/assets/img/legend-pf/node-badge-circuit-breaker.svg new file mode 100644 index 0000000000..c0b994e96e --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-badge-circuit-breaker.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-badge-fault-injection.svg b/plugins/kiali/src/assets/img/legend-pf/node-badge-fault-injection.svg new file mode 100644 index 0000000000..aaee7f2a8d --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-badge-fault-injection.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-badge-gateways.svg b/plugins/kiali/src/assets/img/legend-pf/node-badge-gateways.svg new file mode 100644 index 0000000000..1a68c7528d --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-badge-gateways.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-badge-mirroring.svg b/plugins/kiali/src/assets/img/legend-pf/node-badge-mirroring.svg new file mode 100644 index 0000000000..3d0a35b6ff --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-badge-mirroring.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-badge-missing-sidecar.svg b/plugins/kiali/src/assets/img/legend-pf/node-badge-missing-sidecar.svg new file mode 100644 index 0000000000..920bcd75cd --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-badge-missing-sidecar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-badge-request-timeout.svg b/plugins/kiali/src/assets/img/legend-pf/node-badge-request-timeout.svg new file mode 100644 index 0000000000..2669972377 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-badge-request-timeout.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-badge-traffic-shifting.svg b/plugins/kiali/src/assets/img/legend-pf/node-badge-traffic-shifting.svg new file mode 100644 index 0000000000..ffabc60ced --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-badge-traffic-shifting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-badge-traffic-source.svg b/plugins/kiali/src/assets/img/legend-pf/node-badge-traffic-source.svg new file mode 100644 index 0000000000..c8935e695c --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-badge-traffic-source.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-badge-virtual-services.svg b/plugins/kiali/src/assets/img/legend-pf/node-badge-virtual-services.svg new file mode 100644 index 0000000000..c5f6063317 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-badge-virtual-services.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-badge-workload-entry.svg b/plugins/kiali/src/assets/img/legend-pf/node-badge-workload-entry.svg new file mode 100644 index 0000000000..2274f8843d --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-badge-workload-entry.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-color-danger.svg b/plugins/kiali/src/assets/img/legend-pf/node-color-danger.svg new file mode 100644 index 0000000000..5da21fd0fd --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-color-danger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-color-healthy.svg b/plugins/kiali/src/assets/img/legend-pf/node-color-healthy.svg new file mode 100644 index 0000000000..bfaa1e90de --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-color-healthy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-color-idle.svg b/plugins/kiali/src/assets/img/legend-pf/node-color-idle.svg new file mode 100644 index 0000000000..6ad4a0bae6 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-color-idle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node-color-warning.svg b/plugins/kiali/src/assets/img/legend-pf/node-color-warning.svg new file mode 100644 index 0000000000..d4fcbefa52 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node-color-warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/node.svg b/plugins/kiali/src/assets/img/legend-pf/node.svg new file mode 100644 index 0000000000..be7c352c8e --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/node.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/restricted-namespace.svg b/plugins/kiali/src/assets/img/legend-pf/restricted-namespace.svg new file mode 100644 index 0000000000..682af9d738 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/restricted-namespace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend-pf/service-entry.svg b/plugins/kiali/src/assets/img/legend-pf/service-entry.svg new file mode 100644 index 0000000000..0a0c8d2f94 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/service-entry.svg @@ -0,0 +1,17 @@ + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-pf/service.svg b/plugins/kiali/src/assets/img/legend-pf/service.svg new file mode 100644 index 0000000000..e7925f6b06 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/service.svg @@ -0,0 +1,18 @@ + + + + diff --git a/plugins/kiali/src/assets/img/legend-pf/traffic-failed-request.svg b/plugins/kiali/src/assets/img/legend-pf/traffic-failed-request.svg new file mode 100644 index 0000000000..0629173a38 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/traffic-failed-request.svg @@ -0,0 +1,22 @@ + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-pf/traffic-healthy-request.svg b/plugins/kiali/src/assets/img/legend-pf/traffic-healthy-request.svg new file mode 100644 index 0000000000..2f606a6d34 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/traffic-healthy-request.svg @@ -0,0 +1,21 @@ + + + + + + diff --git a/plugins/kiali/src/assets/img/legend-pf/traffic-tcp.svg b/plugins/kiali/src/assets/img/legend-pf/traffic-tcp.svg new file mode 100644 index 0000000000..0fd634efbb --- /dev/null +++ b/plugins/kiali/src/assets/img/legend-pf/traffic-tcp.svg @@ -0,0 +1,21 @@ + + + + + + diff --git a/plugins/kiali/src/assets/img/legend/aggregate.svg b/plugins/kiali/src/assets/img/legend/aggregate.svg new file mode 100644 index 0000000000..7bf7199af5 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/aggregate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/app.svg b/plugins/kiali/src/assets/img/legend/app.svg new file mode 100644 index 0000000000..f5ff9a691e --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/app.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/edge-danger.svg b/plugins/kiali/src/assets/img/legend/edge-danger.svg new file mode 100644 index 0000000000..013913b2d6 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/edge-danger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/edge-idle.svg b/plugins/kiali/src/assets/img/legend/edge-idle.svg new file mode 100644 index 0000000000..7c35624d61 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/edge-idle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/edge-success.svg b/plugins/kiali/src/assets/img/legend/edge-success.svg new file mode 100644 index 0000000000..e1467ec020 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/edge-success.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/edge-tcp.svg b/plugins/kiali/src/assets/img/legend/edge-tcp.svg new file mode 100644 index 0000000000..ee5bc699cd --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/edge-tcp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/edge-warn.svg b/plugins/kiali/src/assets/img/legend/edge-warn.svg new file mode 100644 index 0000000000..f94a0b46c3 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/edge-warn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/external-namespace.svg b/plugins/kiali/src/assets/img/legend/external-namespace.svg new file mode 100644 index 0000000000..36faf0831e --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/external-namespace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/mtls-badge.svg b/plugins/kiali/src/assets/img/legend/mtls-badge.svg new file mode 100644 index 0000000000..0f2c461565 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/mtls-badge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-badge-circuit-breaker.svg b/plugins/kiali/src/assets/img/legend/node-badge-circuit-breaker.svg new file mode 100644 index 0000000000..794e5ebbd4 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-badge-circuit-breaker.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-badge-fault-injection.svg b/plugins/kiali/src/assets/img/legend/node-badge-fault-injection.svg new file mode 100644 index 0000000000..f9f47dc9e7 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-badge-fault-injection.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-badge-gateways.svg b/plugins/kiali/src/assets/img/legend/node-badge-gateways.svg new file mode 100644 index 0000000000..d83528be78 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-badge-gateways.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-badge-mirroring.svg b/plugins/kiali/src/assets/img/legend/node-badge-mirroring.svg new file mode 100644 index 0000000000..6e3d6623c9 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-badge-mirroring.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-badge-missing-sidecar.svg b/plugins/kiali/src/assets/img/legend/node-badge-missing-sidecar.svg new file mode 100644 index 0000000000..f8977dbb17 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-badge-missing-sidecar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-badge-request-timeout.svg b/plugins/kiali/src/assets/img/legend/node-badge-request-timeout.svg new file mode 100644 index 0000000000..338b8725e2 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-badge-request-timeout.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-badge-traffic-shifting.svg b/plugins/kiali/src/assets/img/legend/node-badge-traffic-shifting.svg new file mode 100644 index 0000000000..d09ff2bba5 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-badge-traffic-shifting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-badge-traffic-source.svg b/plugins/kiali/src/assets/img/legend/node-badge-traffic-source.svg new file mode 100644 index 0000000000..5d2282c32d --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-badge-traffic-source.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-badge-virtual-services.svg b/plugins/kiali/src/assets/img/legend/node-badge-virtual-services.svg new file mode 100644 index 0000000000..4067a3dc12 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-badge-virtual-services.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-badge-workload-entry.svg b/plugins/kiali/src/assets/img/legend/node-badge-workload-entry.svg new file mode 100644 index 0000000000..2c4d532960 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-badge-workload-entry.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-color-danger.svg b/plugins/kiali/src/assets/img/legend/node-color-danger.svg new file mode 100644 index 0000000000..5da21fd0fd --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-color-danger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-color-idle.svg b/plugins/kiali/src/assets/img/legend/node-color-idle.svg new file mode 100644 index 0000000000..b276cdace3 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-color-idle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-color-normal.svg b/plugins/kiali/src/assets/img/legend/node-color-normal.svg new file mode 100644 index 0000000000..6ad4a0bae6 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-color-normal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node-color-warning.svg b/plugins/kiali/src/assets/img/legend/node-color-warning.svg new file mode 100644 index 0000000000..d4fcbefa52 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node-color-warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/node.svg b/plugins/kiali/src/assets/img/legend/node.svg new file mode 100644 index 0000000000..be7c352c8e --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/node.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/restricted-namespace.svg b/plugins/kiali/src/assets/img/legend/restricted-namespace.svg new file mode 100644 index 0000000000..682af9d738 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/restricted-namespace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/service-entry.svg b/plugins/kiali/src/assets/img/legend/service-entry.svg new file mode 100644 index 0000000000..cee2228f11 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/service-entry.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/service.svg b/plugins/kiali/src/assets/img/legend/service.svg new file mode 100644 index 0000000000..12dd4a177a --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/service.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/traffic-failed-request.svg b/plugins/kiali/src/assets/img/legend/traffic-failed-request.svg new file mode 100644 index 0000000000..1eed174bd7 --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/traffic-failed-request.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/traffic-normal-request.svg b/plugins/kiali/src/assets/img/legend/traffic-normal-request.svg new file mode 100644 index 0000000000..631c85d12c --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/traffic-normal-request.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/traffic-tcp.svg b/plugins/kiali/src/assets/img/legend/traffic-tcp.svg new file mode 100644 index 0000000000..0de0e373fc --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/traffic-tcp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/legend/virtualservice.svg b/plugins/kiali/src/assets/img/legend/virtualservice.svg new file mode 100644 index 0000000000..3e5a985eaa --- /dev/null +++ b/plugins/kiali/src/assets/img/legend/virtualservice.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/logo-alt.svg b/plugins/kiali/src/assets/img/logo-alt.svg new file mode 100644 index 0000000000..97465ab35d --- /dev/null +++ b/plugins/kiali/src/assets/img/logo-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/logo-lightbkg.svg b/plugins/kiali/src/assets/img/logo-lightbkg.svg new file mode 100644 index 0000000000..3889ec9224 --- /dev/null +++ b/plugins/kiali/src/assets/img/logo-lightbkg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/microprofile-logo.png b/plugins/kiali/src/assets/img/microprofile-logo.png new file mode 100644 index 0000000000..d3deb1ec7b Binary files /dev/null and b/plugins/kiali/src/assets/img/microprofile-logo.png differ diff --git a/plugins/kiali/src/assets/img/mtls-status-full-dark.svg b/plugins/kiali/src/assets/img/mtls-status-full-dark.svg new file mode 100644 index 0000000000..76285e3cdd --- /dev/null +++ b/plugins/kiali/src/assets/img/mtls-status-full-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/mtls-status-full.svg b/plugins/kiali/src/assets/img/mtls-status-full.svg new file mode 100644 index 0000000000..92cbd24642 --- /dev/null +++ b/plugins/kiali/src/assets/img/mtls-status-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/mtls-status-partial-dark.svg b/plugins/kiali/src/assets/img/mtls-status-partial-dark.svg new file mode 100644 index 0000000000..c0dfa62257 --- /dev/null +++ b/plugins/kiali/src/assets/img/mtls-status-partial-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/mtls-status-partial.svg b/plugins/kiali/src/assets/img/mtls-status-partial.svg new file mode 100644 index 0000000000..95b16d2574 --- /dev/null +++ b/plugins/kiali/src/assets/img/mtls-status-partial.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/node-background-key.png b/plugins/kiali/src/assets/img/node-background-key.png new file mode 100644 index 0000000000..2349638800 Binary files /dev/null and b/plugins/kiali/src/assets/img/node-background-key.png differ diff --git a/plugins/kiali/src/assets/img/node-background-topology.png b/plugins/kiali/src/assets/img/node-background-topology.png new file mode 100644 index 0000000000..557ce49865 Binary files /dev/null and b/plugins/kiali/src/assets/img/node-background-topology.png differ diff --git a/plugins/kiali/src/assets/img/nodejs-logo.png b/plugins/kiali/src/assets/img/nodejs-logo.png new file mode 100644 index 0000000000..f860296565 Binary files /dev/null and b/plugins/kiali/src/assets/img/nodejs-logo.png differ diff --git a/plugins/kiali/src/assets/img/rest-logo.svg b/plugins/kiali/src/assets/img/rest-logo.svg new file mode 100644 index 0000000000..6b04ce7d70 --- /dev/null +++ b/plugins/kiali/src/assets/img/rest-logo.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/kiali/src/assets/img/solid-pin.png b/plugins/kiali/src/assets/img/solid-pin.png new file mode 100644 index 0000000000..57769bdd73 Binary files /dev/null and b/plugins/kiali/src/assets/img/solid-pin.png differ diff --git a/plugins/kiali/src/assets/img/thorntail-logo.png b/plugins/kiali/src/assets/img/thorntail-logo.png new file mode 100644 index 0000000000..fcf3ddc66a Binary files /dev/null and b/plugins/kiali/src/assets/img/thorntail-logo.png differ diff --git a/plugins/kiali/src/assets/img/vertx-logo.png b/plugins/kiali/src/assets/img/vertx-logo.png new file mode 100644 index 0000000000..c438d22778 Binary files /dev/null and b/plugins/kiali/src/assets/img/vertx-logo.png differ diff --git a/plugins/kiali/src/components/About/AboutUIModal.tsx b/plugins/kiali/src/components/About/AboutUIModal.tsx new file mode 100644 index 0000000000..8515d72ad1 --- /dev/null +++ b/plugins/kiali/src/components/About/AboutUIModal.tsx @@ -0,0 +1,219 @@ +import * as React from 'react'; + +import { Link } from '@backstage/core-components'; + +import { + Card, + CardContent, + CardHeader, + Collapse, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Grid, + IconButton, + Typography, +} from '@material-ui/core'; +import CloseIcon from '@material-ui/icons/Close'; +import { Alert } from '@material-ui/lab'; + +import { config, KialiIcon, KialiLogo } from '../../config'; +import { kialiStyle } from '../../styles/StyleUtils'; +import { + ExternalServiceInfo, + Status, + StatusKey, +} from '../../types/StatusState'; + +type AboutUIModalProps = { + status: Status; + externalServices: ExternalServiceInfo[]; + warningMessages: string[]; + showModal: boolean; + setShowModal: React.Dispatch>; +}; + +const iconStyle = kialiStyle({ + marginRight: '10px', +}); + +const textContentStyle = kialiStyle({ + $nest: { + '& dt, & dd': { + lineHeight: 1.667, + }, + }, +}); + +const closeButton = kialiStyle({ + position: 'absolute', + right: 10, + top: 10, +}); + +export const AboutUIModal = (props: AboutUIModalProps) => { + const [showWarnings, setShowWarnings] = React.useState(false); + + const additionalComponentInfoContent = ( + externalService: ExternalServiceInfo, + ) => { + if (!externalService.version && !externalService.url) { + return 'N/A'; + } + const version = externalService.version ? externalService.version : ''; + const url = externalService.url ? ( + + {externalService.url} + + ) : ( + '' + ); + return ( + <> + {version} {url} + + ); + }; + + const renderComponent = (externalService: ExternalServiceInfo) => { + const name = externalService.version + ? externalService.name + : `${externalService.name} URL`; + const additionalInfo = additionalComponentInfoContent(externalService); + return ( +

+ + {name} + + + {additionalInfo} + +
+ ); + }; + + const renderWebsiteLink = () => { + if (config.about?.website) { + return ( + + + {config.about.website.linkText} + + ); + } + + return null; + }; + + const renderProjectLink = () => { + if (config.about?.project) { + return ( + + + {config.about.project.linkText} + + ); + } + + return null; + }; + + const coreVersion = + props.status[StatusKey.KIALI_CORE_COMMIT_HASH] === '' || + props.status[StatusKey.KIALI_CORE_COMMIT_HASH] === 'unknown' + ? props.status[StatusKey.KIALI_CORE_VERSION] + : `${props.status[StatusKey.KIALI_CORE_VERSION]} (${ + props.status[StatusKey.KIALI_CORE_COMMIT_HASH] + })`; + const containerVersion = props.status[StatusKey.KIALI_CONTAINER_VERSION]; + const meshVersion = props.status[StatusKey.MESH_NAME] + ? `${props.status[StatusKey.MESH_NAME]} ${ + props.status[StatusKey.MESH_VERSION] || '' + }` + : 'Unknown'; + + return ( + props.setShowModal(false)} + aria-labelledby="Kiali" + aria-describedby="Kiali" + fullWidth + > + + + props.setShowModal(false)} + className={closeButton} + > + + + + + + Kiali + + + Kiali + + + {coreVersion || 'Unknown'} + + + Kiali Container + + + {containerVersion || 'Unknown'} + + + Service Mesh + + + {meshVersion || 'Unknown'} + + + + {props.warningMessages.length > 0 && ( + + + {props.warningMessages.length} warnings.{' '} + setShowWarnings(!showWarnings)} + style={{ color: '#2b9af3' }} + > + ({showWarnings ? 'Close' : 'See'} them) + + + } + /> + + + {props.warningMessages.map(warn => ( + + {warn} + + ))} + + + + )} + + Components + {props?.externalServices.map(renderComponent)} + + + + {renderWebsiteLink()} + {renderProjectLink()} + + + ); +}; diff --git a/plugins/kiali/src/components/Ambient/AmbientBadge.tsx b/plugins/kiali/src/components/Ambient/AmbientBadge.tsx new file mode 100644 index 0000000000..0dcdc5d6ee --- /dev/null +++ b/plugins/kiali/src/components/Ambient/AmbientBadge.tsx @@ -0,0 +1,25 @@ +import * as React from 'react'; + +import { Chip, Tooltip } from '@material-ui/core'; + +type AmbientLabelProps = { + style?: React.CSSProperties; + tooltip: string; +}; + +export const AmbientBadge = (props: AmbientLabelProps) => { + const iconComponent = ( + + + + ); + return ( + + {iconComponent} + + ); +}; diff --git a/plugins/kiali/src/components/Ambient/AmbientLabel.tsx b/plugins/kiali/src/components/Ambient/AmbientLabel.tsx new file mode 100644 index 0000000000..ee291e8ee6 --- /dev/null +++ b/plugins/kiali/src/components/Ambient/AmbientLabel.tsx @@ -0,0 +1,69 @@ +import * as React from 'react'; + +import { Chip, Tooltip } from '@material-ui/core'; + +type AmbientLabelProps = { + tooltip: boolean; + style?: React.CSSProperties; + waypoint?: boolean; +}; + +const AmbientComponent = 'ztunnel'; + +export class AmbientLabel extends React.Component { + render() { + const msg = 'Component is labeled as part of the Istio Ambient Mesh'; + + const tooltipContent = ( +
+
+ {msg} +
+
+
+ ); + const iconComponent = ( + + + {this.props.waypoint && ( + + )} + {!this.props.tooltip && ( + + {msg} + + + + + )} + + ); + return this.props.tooltip ? ( + + {iconComponent} + + ) : ( + iconComponent + ); + } +} diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/CustomTooltip.tsx b/plugins/kiali/src/components/Charts/CustomTooltip.tsx similarity index 58% rename from plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/CustomTooltip.tsx rename to plugins/kiali/src/components/Charts/CustomTooltip.tsx index b3fcddd004..613af2b925 100644 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/CustomTooltip.tsx +++ b/plugins/kiali/src/components/Charts/CustomTooltip.tsx @@ -4,14 +4,12 @@ import { ChartCursorFlyout, ChartLabel, ChartPoint, + ChartTooltip, + ChartTooltipProps, } from '@patternfly/react-charts'; -import { - toLocaleStringWithConditionalDate, - VCDataPoint, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { HookedChartTooltip, HookedTooltipProps } from './HookedChartTooltip'; +import { VCDataPoint } from '../../types/VictoryChartInfo'; +import { toLocaleStringWithConditionalDate } from '../../utils/Date'; const dy = 15; const headSizeDefault = 2 * dy; @@ -27,7 +25,7 @@ const CustomLabel = (props: any) => { const textsWithHead = props.head ? [props.head, ' '].concat(props.text) : props.text; - const headSize = props.head ? headSizeDefault : 0; + const headSize = props.head ? 2 * dy : 0; const startY = yMargin + props.y - (textsWithHead.length * dy) / 2 + headSize; return ( @@ -38,7 +36,7 @@ const CustomLabel = (props: any) => { const symbol = pt.symbol || 'square'; return ( { return undefined; }; -type Props = HookedTooltipProps<{}> & { - showTime?: boolean; +export type HookedTooltipProps = ChartTooltipProps & { + activePoints?: (VCDataPoint & T)[]; + onOpen?: (items: VCDataPoint[]) => void; + onClose?: () => void; }; -type State = { - texts: string[]; - head?: string; - textWidth: number; - width: number; - height: number; +export class HookedChartTooltip extends React.Component< + HookedTooltipProps +> { + componentDidMount() { + if (this.props.onOpen && this.props.activePoints) { + this.props.onOpen(this.props.activePoints); + } + } + + componentWillUnmount() { + if (this.props.onClose) { + this.props.onClose(); + } + } + + render() { + return ; + } +} + +type Props = HookedTooltipProps<{}> & { + showTime?: boolean; }; -export class CustomTooltip extends React.Component { - static getDerivedStateFromProps(props: Props): State { +export const CustomTooltip = (props: Props) => { + const getDerivedStateFromProps = () => { const head = props.showTime ? getHeader(props.activePoints) : undefined; - const texts: string[] = []; - if (props.text) { - if (Array.isArray(props.text)) { - texts.push(...(props.text as string[])); - } else { - texts.push(props.text as string); - } + let texts: string[] = []; + + if (props.text && Array.isArray(props.text)) { + texts = props.text as string[]; + } else if (props.text) { + texts = [props.text as string]; } + let height = texts.length * dy + 2 * yMargin; if (head) { height += headSizeDefault; @@ -105,30 +121,25 @@ export class CustomTooltip extends React.Component { width: width, height: height, }; - } + }; - constructor(p: Props) { - super(p); - this.state = CustomTooltip.getDerivedStateFromProps(p); - } + const initialState = getDerivedStateFromProps(); - render() { - return ( - - } - labelComponent={ - - } - /> - ); - } -} + return ( + + } + labelComponent={ + + } + /> + ); +}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/SparklineChart.tsx b/plugins/kiali/src/components/Charts/SparklineChart.tsx similarity index 52% rename from plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/SparklineChart.tsx rename to plugins/kiali/src/components/Charts/SparklineChart.tsx index 6450bd65f3..d90f1275a0 100644 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/SparklineChart.tsx +++ b/plugins/kiali/src/components/Charts/SparklineChart.tsx @@ -13,13 +13,12 @@ import { } from '@patternfly/react-charts'; import { - addLegendEvent, RichDataPoint, VCDataPoint, - VCEvent, VCLines, -} from '@janus-idp/backstage-plugin-kiali-common'; - +} from '../../types/VictoryChartInfo'; +import { addLegendEvent, VCEvent } from '../../utils/VictoryEvents'; +import { PFColors } from '../Pf/PfColors'; import { CustomTooltip } from './CustomTooltip'; type Props = ChartProps & { @@ -33,79 +32,72 @@ type Props = ChartProps & { thresholds?: VCLines; }; -type State = { - width: number; - hiddenSeries: Set; +const axisStyle = { + tickLabels: { fill: PFColors.Color100 }, }; export const INTERPOLATION_STRATEGY = 'monotoneX'; -export class SparklineChart extends React.Component { - containerRef?: React.RefObject; - - constructor(props: Props) { - super(props); - if (props.width === undefined) { - this.containerRef = React.createRef(); +export const SparklineChart = (props: Props) => { + const [width, setWidth] = React.useState(props.width || 1); + const [hiddenSeries, setHiddenSeries] = React.useState>( + new Set(), + ); + const containerRef: React.RefObject | undefined = + props.width === undefined ? React.createRef() : undefined; + + const handleResize = () => { + if (containerRef?.current) { + setWidth(containerRef.current.clientWidth); } - this.state = { width: props.width || 1, hiddenSeries: new Set() }; - } + }; - componentDidMount() { - if (this.containerRef) { + React.useEffect(() => { + if (containerRef) { setTimeout(() => { - this.handleResize(); - window.addEventListener('resize', this.handleResize); + handleResize(); + window.addEventListener('resize', handleResize); }); - } - } - componentWillUnmount() { - if (this.containerRef) { - window.removeEventListener('resize', this.handleResize); + return () => { + window.removeEventListener('resize', handleResize); + }; } - } + return () => {}; + }); - private handleResize = () => { - if (this.containerRef?.current) { - this.setState({ width: this.containerRef.current.clientWidth }); - } - }; - - private renderChart() { + const renderChart = () => { const legendHeight = 30; - let height = this.props.height || 300; + let height = props.height || 300; let padding = { top: 0, bottom: 0, left: 0, right: 0 }; - if (this.props.padding) { - const p = this.props.padding as number; + if (props.padding) { + const p = props.padding as number; if (Number.isFinite(p)) { padding = { top: p, bottom: p, left: p, right: p }; } else { - padding = { ...padding, ...(this.props.padding as object) }; + padding = { ...padding, ...(props.padding as object) }; } } const events: VCEvent[] = []; - if (this.props.showLegend) { + if (props.showLegend) { padding.bottom += legendHeight; height += legendHeight; - this.props.series.forEach((_, idx) => { + props.series.forEach((_, idx) => { addLegendEvent(events, { - legendName: `${this.props.name}-legend`, + legendName: `${props.name}-legend`, idx: idx, - serieID: [`${this.props.name}-area-${idx}`], + serieID: [`${props.name}-area-${idx}`], onClick: () => { - if (!this.state.hiddenSeries.delete(idx)) { + if (!hiddenSeries.delete(idx)) { // Was not already hidden => add to set - this.state.hiddenSeries.add(idx); + hiddenSeries.add(idx); } - this.setState(prevState => ({ - hiddenSeries: new Set(prevState.hiddenSeries), - })); + setHiddenSeries(new Set(hiddenSeries)); return null; }, - onMouseOver: props => { + onMouseOver: prs => { return { - style: { ...props.style, strokeWidth: 4, fillOpacity: 0.5 }, + style: { ...prs.style, strokeWidth: 4, fillOpacity: 0.5 }, }; }, }); @@ -115,13 +107,11 @@ export class SparklineChart extends React.Component { const container = ( - this.props.tooltipFormat - ? this.props.tooltipFormat(obj.datum) - : obj.datum.y + props.tooltipFormat ? props.tooltipFormat(obj.datum) : obj.datum.y } labelComponent={} - voronoiBlacklist={this.props.series.map( - (_, idx) => `${this.props.name}-scatter-${idx}`, + voronoiBlacklist={props.series.map( + (_, idx) => `${props.name}-scatter-${idx}`, )} /> ); @@ -133,18 +123,18 @@ export class SparklineChart extends React.Component { return ( - {this.props.showXAxisValues ? ( + {props.showXAxisValues ? ( dp.x)} + tickValues={props.series[0].datapoints.map(dp => dp.x)} tickFormat={x => (x as Date).toLocaleTimeString([], { hour: '2-digit', @@ -152,44 +142,52 @@ export class SparklineChart extends React.Component { }) } tickCount={2} + style={axisStyle} /> ) : ( )} - {this.props.showYAxis ? ( + {props.showYAxis ? ( + } tickCount={2} dependentAxis + style={axisStyle} /> ) : ( )} - {this.props.series.map((serie, idx) => { - if (this.state.hiddenSeries.has(idx)) { + {props.series.map((serie, idx) => { + if (hiddenSeries.has(idx)) { return undefined; } return ( (active ? 5 : 2)} /> ); })} - {this.props.series.map((serie, idx) => { - if (this.state.hiddenSeries.has(idx)) { + {props.series.map((serie, idx) => { + if (hiddenSeries.has(idx)) { return undefined; } return ( { /> ); })} - {this.props.showLegend && ( + {props.showLegend && ( { - if (this.state.hiddenSeries.has(idx)) { - return { ...s.legendItem, symbol: { fill: '#72767b' } }; + name={`${props.name}-legend`} + data={props.series.map((s, idx) => { + if (hiddenSeries.has(idx)) { + return { ...s.legendItem, symbol: { fill: PFColors.Color200 } }; } return s.legendItem; })} y={height - legendHeight} height={legendHeight} - width={this.state.width} + width={width} /> )} - {this.props.thresholds && - this.props.thresholds.map((serie, idx) => { - if (this.state.hiddenSeries.has(idx)) { + {props.thresholds && + props.thresholds.map((serie, idx) => { + if (hiddenSeries.has(idx)) { return undefined; } return ( { })} ); - } + }; - render() { - if (this.containerRef) { - return
{this.renderChart()}
; - } - return this.renderChart(); + if (containerRef) { + return
{renderChart()}
; } -} + return renderChart(); +}; diff --git a/plugins/kiali/src/components/DebugInformation/DebugInformation.tsx b/plugins/kiali/src/components/DebugInformation/DebugInformation.tsx new file mode 100644 index 0000000000..4690d94a40 --- /dev/null +++ b/plugins/kiali/src/components/DebugInformation/DebugInformation.tsx @@ -0,0 +1,296 @@ +// @ts-nocheck +import * as React from 'react'; +import AceEditor from 'react-ace'; +import { CopyToClipboard } from 'react-copy-to-clipboard'; + +import { + CardTab, + TabbedCard, + Table, + TableColumn, +} from '@backstage/core-components'; + +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, +} from '@material-ui/core'; +import { + Alert, + AlertActionCloseButton, + AlertVariant, +} from '@patternfly/react-core'; + +import { serverConfig } from '../../config'; +import { authenticationConfig } from '../../config/AuthenticationConfig'; +import { ComputedServerConfig } from '../../config/ServerConfig'; +import { KialiAppState } from '../../store/Store'; +import { istioAceEditorStyle } from '../../styles/AceEditorStyle'; +import { AuthConfig } from '../../types/Auth'; +import { aceOptions } from '../../types/IstioConfigDetails'; + +const beautify = require('json-beautify'); + +enum CopyStatus { + NOT_COPIED, // We haven't copied the current output + COPIED, // Current output is in the clipboard + OLD_COPY, // We copied the prev output, but there are changes in the KialiAppState +} + +type DebugInformationProps = { + appState: KialiAppState; + showDebug: boolean; + setShowDebug: React.Dispatch>; +}; + +type DebugInformationData = { + backendConfigs: { + authenticationConfig: AuthConfig; + computedServerConfig: ComputedServerConfig; + }; + currentURL: string; + reduxState: KialiAppState; +}; + +const copyToClipboardOptions = { + message: + 'We failed to automatically copy the text, please use: #{key}, Enter\t', +}; + +// Will be shown in Kiali Config and hidden in Additional state +const propsToShow = [ + 'accessibleNamespaces', + 'authStrategy', + 'clusters', + 'gatewayAPIClasses', + 'gatewayAPIEnabled', + 'istioConfigMap', + 'istioIdentityDomain', + 'istioNamespace', + 'istioStatusEnabled', + 'logLevel', + 'istioCanaryRevision', + 'istioAnnotationsAction', + 'istioInjectionAction', +]; + +const propsToPatch = ['cyRef', 'summaryTarget', 'token', 'username']; + +const defaultTab = 'kialiConfig'; + +export const DebugInformation = (props: DebugInformationProps) => { + const aceEditorRef: React.RefObject = React.createRef(); + let kialiConfig: { [key: string]: string } = {}; + + for (const key in serverConfig) { + if (propsToShow.includes(key)) { + // @ts-expect-error + if (typeof serverConfig[key] === 'string') { + // @ts-expect-error + kialiConfig[key] = serverConfig[key]; + } else { + // @ts-expect-error + kialiConfig[key] = JSON.stringify(serverConfig[key]); + } + } + } + + kialiConfig = Object.keys(kialiConfig) + .sort((a, b) => a.localeCompare(b)) + .reduce((obj, key) => { + // @ts-expect-error + obj[key] = kialiConfig[key]; + return obj; + }, {}); + + const [currentTab, setCurrentTab] = React.useState(defaultTab); + const [copyStatus, setCopyStatus] = React.useState( + CopyStatus.NOT_COPIED, + ); + + const close = () => { + props.setShowDebug(false); + }; + + const copyCallback = (_text: string, result: boolean) => { + setCopyStatus(result ? CopyStatus.COPIED : CopyStatus.NOT_COPIED); + }; + + // Properties shown in Kiali Config are not shown again in Additional State + const filterDebugInformation = (info: any) => { + if (info !== null) { + for (const [key] of Object.entries(info)) { + if (propsToShow.includes(key)) { + delete info[key]; + continue; + } + } + } + return info; + }; + + const parseConfig = (key: string, value: any) => { + // We have to patch some runtime properties we don't want to serialize + if (propsToPatch.includes(key)) { + return null; + } + return value; + }; + + const renderDebugInformation = () => { + let debugInformation: DebugInformationData = { + backendConfigs: { + authenticationConfig: authenticationConfig, + computedServerConfig: serverConfig, + }, + currentURL: window.location.href, + reduxState: props.appState, + }; + debugInformation = filterDebugInformation(debugInformation); + return beautify(debugInformation, parseConfig, 2); + }; + + const getCopyText = (): string => { + const text = + currentTab === 'kialiConfig' + ? JSON.stringify(kialiConfig, null, 2) + : renderDebugInformation(); + return text; + }; + + const download = () => { + const element = document.createElement('a'); + const file = new Blob([getCopyText()], { type: 'text/plain' }); + element.href = URL.createObjectURL(file); + element.download = `debug_${ + currentTab === 'kialiConfig' ? 'kiali_config' : 'additional_state' + }.json`; + document.body.appendChild(element); // Required for this to work in FireFox + element.click(); + }; + + const hideAlert = () => { + setCopyStatus(CopyStatus.NOT_COPIED); + }; + + const debugInformation = renderDebugInformation(); + + const columns = (): TableColumn[] => { + return [ + { title: 'Configuration', field: 'configuration' }, + { title: 'Value', field: 'value' }, + ]; + }; + + const getRows = () => { + const conf: Array<{}> = []; + + for (const [k, v] of Object.entries(kialiConfig)) { + if (typeof v !== 'string') { + conf.push({ configuration: k, value: JSON.stringify(v) }); + } else { + conf.push({ configuration: k, value: v }); + } + } + return conf; + }; + + const renderTabs = () => { + const copyClip = ( + + + + ); + + const kialiConfigCard = ( + + {copyClip} + + ); + + const additionalState = ( + + Please include this information when opening a bug: + + + + + ); + // TODO additionalState + const tabsArray: JSX.Element[] = [kialiConfigCard]; + return tabsArray; + }; + + return props.showDebug ? ( + + Debug information + + {copyStatus === CopyStatus.COPIED && ( + } + /> + )} + {copyStatus === CopyStatus.OLD_COPY && ( + } + /> + )} + setCurrentTab(tabName as string)} + > + {renderTabs()} + + + + + + + + + + + ) : null; +}; diff --git a/plugins/kiali/src/components/FilterList/FitlerHelper.ts b/plugins/kiali/src/components/FilterList/FitlerHelper.ts new file mode 100644 index 0000000000..aa4276fc68 --- /dev/null +++ b/plugins/kiali/src/components/FilterList/FitlerHelper.ts @@ -0,0 +1,174 @@ +import { camelCase } from 'lodash'; + +import { history, HistoryManager, URLParam } from '../../app/History'; +import { config } from '../../config'; +import { + ActiveFilter, + ActiveFiltersInfo, + DEFAULT_LABEL_OPERATION, + FilterType, + ID_LABEL_OPERATION, + LabelOperation, + RunnableFilter, +} from '../../types/Filters'; +import { SortField } from '../../types/SortFilters'; + +export const perPageOptions: number[] = [5, 10, 15]; +const defaultDuration = 600; +const defaultRefreshInterval = config.toolbar.defaultRefreshInterval; + +export const getFiltersFromURL = ( + filterTypes: FilterType[], +): ActiveFiltersInfo => { + const urlParams = new URLSearchParams(history.location.search); + const activeFilters: ActiveFilter[] = []; + filterTypes.forEach(filter => { + urlParams.getAll(camelCase(filter.category)).forEach(value => { + activeFilters.push({ + category: filter.category, + value: value, + }); + }); + }); + + return { + filters: activeFilters, + op: + (urlParams.get(ID_LABEL_OPERATION) as LabelOperation) || + DEFAULT_LABEL_OPERATION, + }; +}; + +export const setFiltersToURL = ( + filterTypes: FilterType[], + filters: ActiveFiltersInfo, +): ActiveFiltersInfo => { + const urlParams = new URLSearchParams(history.location.search); + filterTypes.forEach(type => { + urlParams.delete(camelCase(type.category)); + }); + // Remove manually the special Filter opLabel + urlParams.delete('opLabel'); + const cleanFilters: ActiveFilter[] = []; + + filters.filters.forEach(activeFilter => { + const filterType = filterTypes.find( + filter => filter.category === activeFilter.category, + ); + if (!filterType) { + return; + } + cleanFilters.push(activeFilter); + urlParams.append(camelCase(filterType.category), activeFilter.value); + }); + urlParams.append(ID_LABEL_OPERATION, filters.op); + // Resetting pagination when filters change + history.push(`${history.location.pathname}?${urlParams.toString()}`); + return { filters: cleanFilters, op: filters.op || DEFAULT_LABEL_OPERATION }; +}; + +export const filtersMatchURL = ( + filterTypes: FilterType[], + filters: ActiveFiltersInfo, +): boolean => { + // This can probably be improved and/or simplified? + const fromFilters: Map = new Map(); + filters.filters.forEach(activeFilter => { + const existingValue = fromFilters.get(activeFilter.category) || []; + fromFilters.set( + activeFilter.category, + existingValue.concat(activeFilter.value), + ); + }); + + const fromURL: Map = new Map(); + const urlParams = new URLSearchParams(history.location.search); + filterTypes.forEach(filter => { + const values = urlParams.getAll(camelCase(filter.category)); + if (values.length > 0) { + const existing = fromURL.get(camelCase(filter.category)) || []; + fromURL.set(filter.category, existing.concat(values)); + } + }); + + if (fromFilters.size !== fromURL.size) { + return false; + } + let equalFilters = true; + fromFilters.forEach((filterValues, filterName) => { + const aux = fromURL.get(filterName) || []; + equalFilters = + equalFilters && + filterValues.every(value => aux.includes(value)) && + filterValues.length === aux.length; + }); + + return equalFilters; +}; + +export const isCurrentSortAscending = (): boolean => { + return (HistoryManager.getParam(URLParam.DIRECTION) || 'asc') === 'asc'; +}; + +export const currentDuration = (): number => { + return HistoryManager.getDuration() || defaultDuration; +}; + +export const currentRefreshInterval = (): number => { + const refreshInterval = HistoryManager.getNumericParam( + URLParam.REFRESH_INTERVAL, + ); + if (refreshInterval === undefined) { + return defaultRefreshInterval; + } + return refreshInterval; +}; + +export const currentSortField = ( + sortFields: SortField[], +): SortField => { + const queriedSortedField = + HistoryManager.getParam(URLParam.SORT) || sortFields[0].param; + return ( + sortFields.find(sortField => { + return sortField.param === queriedSortedField; + }) || sortFields[0] + ); +}; + +export const compareNullable = ( + a: T | undefined, + b: T | undefined, + safeComp: (a2: T, b2: T) => number, +): number => { + if (!a) { + return !b ? 0 : 1; + } + if (!b) { + return -1; + } + return safeComp(a, b); +}; + +const runOneFilter = ( + items: T[], + filter: RunnableFilter, + active: ActiveFiltersInfo, +) => { + const relatedActive = { + filters: active.filters.filter(af => af.category === filter.category), + op: active.op, + }; + if (relatedActive.filters.length) { + return items.filter(item => filter.run(item, relatedActive)); + } + return items; +}; + +export const runFilters = ( + items: T[], + filters: RunnableFilter[], + active: ActiveFiltersInfo, +) => { + return filters.reduce((i, f) => runOneFilter(i, f, active), items); +}; diff --git a/plugins/kiali/src/components/Filters/CommonFilters.ts b/plugins/kiali/src/components/Filters/CommonFilters.ts new file mode 100644 index 0000000000..611298a3fe --- /dev/null +++ b/plugins/kiali/src/components/Filters/CommonFilters.ts @@ -0,0 +1,96 @@ +import { + ActiveFiltersInfo, + AllFilterTypes, + FILTER_ACTION_APPEND, + FILTER_ACTION_UPDATE, + FilterType, + FilterValue, +} from '../../types/Filters'; +import { DEGRADED, FAILURE, HEALTHY, NA, NOT_READY } from '../../types/Health'; +import { removeDuplicatesArray } from '../../utils/Common'; + +export const presenceValues: FilterValue[] = [ + { + id: 'present', + title: 'Present', + }, + { + id: 'notpresent', + title: 'Not Present', + }, +]; + +export const istioSidecarFilter: FilterType = { + category: 'Istio Sidecar', + placeholder: 'Filter by Istio Sidecar Validation', + filterType: AllFilterTypes.select, + action: FILTER_ACTION_UPDATE, + filterValues: presenceValues, +}; + +export const healthFilter: FilterType = { + category: 'Health', + placeholder: 'Filter by Health', + filterType: AllFilterTypes.select, + action: FILTER_ACTION_APPEND, + filterValues: [ + { + id: HEALTHY.name, + title: HEALTHY.name, + }, + { + id: DEGRADED.name, + title: DEGRADED.name, + }, + { + id: FAILURE.name, + title: FAILURE.name, + }, + { + id: NOT_READY.name, + title: NOT_READY.name, + }, + { + id: 'na', + title: NA.name, + }, + ], +}; + +export const labelFilter: FilterType = { + category: 'Label', + placeholder: 'Filter by Label', + filterType: AllFilterTypes.label, + action: FILTER_ACTION_APPEND, + filterValues: [], +}; + +export const getFilterSelectedValues = ( + filter: FilterType, + activeFilters: ActiveFiltersInfo, +): string[] => { + const selected: string[] = activeFilters.filters + .filter(activeFilter => activeFilter.category === filter.category) + .map(activeFilter => activeFilter.value); + return removeDuplicatesArray(selected); +}; + +export const getPresenceFilterValue = ( + filter: FilterType, + activeFilters: ActiveFiltersInfo, +): boolean | undefined => { + const presenceFilters = activeFilters.filters.filter( + activeFilter => activeFilter.category === filter.category, + ); + + if (presenceFilters.length > 0) { + return presenceFilters[0].value === 'Present'; + } + return undefined; +}; + +export const filterByHealth = (items: any[], filterValues: string[]): any[] => { + return items.filter(itemWithHealth => + filterValues.includes(itemWithHealth.health.getGlobalStatus().name), + ); +}; diff --git a/plugins/kiali/src/components/Filters/LabelFilter.tsx b/plugins/kiali/src/components/Filters/LabelFilter.tsx new file mode 100644 index 0000000000..8ef1d6cbee --- /dev/null +++ b/plugins/kiali/src/components/Filters/LabelFilter.tsx @@ -0,0 +1,77 @@ +import * as React from 'react'; + +import { + Button, + ButtonVariant, + Popover, + PopoverPosition, + TextInput, +} from '@patternfly/react-core'; + +import { KialiIcon } from '../../config/KialiIcon'; +import { kialiStyle } from '../../styles/StyleUtils'; + +interface LabelFiltersProps { + filterAdd: (value: string) => void; + isActive: (value: string) => boolean; + onChange: (value: any) => void; + value: string; +} + +const infoIconStyle = kialiStyle({ + marginLeft: '0.5rem', + alignSelf: 'center', +}); + +export const LabelFilters: React.FC = ( + props: LabelFiltersProps, +) => { + const onkeyPress = (e: any) => { + if (e.key === 'Enter') { + if (props.value?.length > 0) { + props.value + .split(' ') + .forEach(val => !props.isActive(val) && props.filterAdd(val)); + } + } + }; + + return ( + <> + props.onChange(value)} + onKeyPress={e => onkeyPress(e)} + style={{ width: 'auto' }} + /> + Label Filter Help} + position={PopoverPosition.right} + bodyContent={ + <> + To set a label filter you must enter values like. +
+
    +
  • Filter by label presence: label
  • +
  • Filter by label and value: label=value
  • +
  • + Filter by more than one label and one or more values: +
    + label=value label2=value2,value2-2 +
    + (separate with ' ') +
  • +
+ + } + > + +
+ + ); +}; diff --git a/plugins/kiali/src/components/Filters/StatefulFilters.tsx b/plugins/kiali/src/components/Filters/StatefulFilters.tsx new file mode 100644 index 0000000000..ee8f4b0edb --- /dev/null +++ b/plugins/kiali/src/components/Filters/StatefulFilters.tsx @@ -0,0 +1,84 @@ +import { history, HistoryManager } from '../../app/History'; +import { + ActiveFilter, + ActiveFiltersInfo, + ActiveTogglesInfo, + FilterType, + LabelOperation, + ToggleType, +} from '../../types/Filters'; +import * as FilterHelper from '../FilterList/FitlerHelper'; + +export class FilterSelected { + static selectedFilters: ActiveFilter[] | undefined = undefined; + static opSelected: LabelOperation; + + static init = (filterTypes: FilterType[]) => { + let active = FilterSelected.getSelected(); + if (!FilterSelected.isInitialized()) { + active = FilterHelper.getFiltersFromURL(filterTypes); + FilterSelected.setSelected(active); + } else if (!FilterHelper.filtersMatchURL(filterTypes, active)) { + active = FilterHelper.setFiltersToURL(filterTypes, active); + FilterSelected.setSelected(active); + } + return active; + }; + + static resetFilters = () => { + FilterSelected.selectedFilters = undefined; + }; + + static setSelected = (activeFilters: ActiveFiltersInfo) => { + FilterSelected.selectedFilters = activeFilters.filters; + FilterSelected.opSelected = activeFilters.op; + }; + + static getSelected = (): ActiveFiltersInfo => { + return { + filters: FilterSelected.selectedFilters || [], + op: FilterSelected.opSelected || 'or', + }; + }; + + static isInitialized = () => { + return FilterSelected.selectedFilters !== undefined; + }; +} + +// Column toggles +export class Toggles { + static checked: ActiveTogglesInfo = new Map(); + static numChecked = 0; + + static init = (toggles: ToggleType[]): number => { + Toggles.checked.clear(); + Toggles.numChecked = 0; + + // Prefer URL settings + const urlParams = new URLSearchParams(history.location.search); + toggles.forEach(t => { + const urlIsChecked = HistoryManager.getBooleanParam( + `${t.name}Toggle`, + urlParams, + ); + const isChecked = urlIsChecked === undefined ? t.isChecked : urlIsChecked; + Toggles.checked.set(t.name, isChecked); + if (isChecked) { + Toggles.numChecked++; + } + }); + return Toggles.numChecked; + }; + + static setToggle = (name: string, value: boolean): number => { + HistoryManager.setParam(`${name}Toggle`, `${value}`); + Toggles.checked.set(name, value); + Toggles.numChecked = value ? Toggles.numChecked++ : Toggles.numChecked--; + return Toggles.numChecked; + }; + + static getToggles = (): ActiveTogglesInfo => { + return new Map(Toggles.checked); + }; +} diff --git a/plugins/kiali/src/components/Health/HealthStyle.ts b/plugins/kiali/src/components/Health/HealthStyle.ts new file mode 100644 index 0000000000..e69c5bb2ea --- /dev/null +++ b/plugins/kiali/src/components/Health/HealthStyle.ts @@ -0,0 +1,17 @@ +import { kialiStyle } from '../../styles/StyleUtils'; +import { PFColors } from '../Pf/PfColors'; + +export const healthIndicatorStyle = kialiStyle({ + $nest: { + '& .pf-v5-c-tooltip__content': { + borderWidth: '1px', + textAlign: 'left', + }, + + '& .pf-v5-c-content ul': { + marginBottom: 'var(--pf-v5-c-content--ul--MarginTop)', + marginTop: 0, + color: PFColors.Color100, + }, + }, +}); diff --git a/plugins/kiali/src/components/Health/Helper.ts b/plugins/kiali/src/components/Health/Helper.ts new file mode 100644 index 0000000000..96e28a1bb9 --- /dev/null +++ b/plugins/kiali/src/components/Health/Helper.ts @@ -0,0 +1,19 @@ +import * as React from 'react'; + +import { Icon } from '@patternfly/react-core'; + +import { kialiStyle } from '../../styles/StyleUtils'; +import { Status } from '../../types/Health'; + +type Size = 'sm' | 'md' | 'lg' | 'xl'; + +export const createIcon = (status: Status, size?: Size) => { + const classForColor = kialiStyle({ + color: status.color, + }); + return React.createElement( + Icon, + { size: size, className: `${status.class} ${classForColor}` }, + React.createElement(status.icon), + ); +}; diff --git a/plugins/kiali/src/components/Icons/MTLSStatusFull.tsx b/plugins/kiali/src/components/Icons/MTLSStatusFull.tsx deleted file mode 100644 index 0714d8e887..0000000000 --- a/plugins/kiali/src/components/Icons/MTLSStatusFull.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react'; - -export const MTLSStatusFull = (): JSX.Element => ( - - - - - -); - -export const MTLSStatusFullDark = (): JSX.Element => ( - - - - - -); diff --git a/plugins/kiali/src/components/Icons/MTLSStatusPartial.tsx b/plugins/kiali/src/components/Icons/MTLSStatusPartial.tsx deleted file mode 100644 index 3f5cc6d984..0000000000 --- a/plugins/kiali/src/components/Icons/MTLSStatusPartial.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react'; - -export const MTLSStatusPartial = (): JSX.Element => ( - - - - - -); - -export const MTLSStatusPartialDark = (): JSX.Element => ( - - - - - -); diff --git a/plugins/kiali/src/components/Icons/index.ts b/plugins/kiali/src/components/Icons/index.ts deleted file mode 100644 index 7354460be3..0000000000 --- a/plugins/kiali/src/components/Icons/index.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { createElement } from 'react'; - -import SvgIcon from '@material-ui/core/SvgIcon'; -import CheckCircleRounded from '@material-ui/icons/CheckCircleRounded'; -import ErrorRounded from '@material-ui/icons/ErrorRounded'; -import InfoOutlined from '@material-ui/icons/InfoOutlined'; -import RemoveCircleRounded from '@material-ui/icons/RemoveCircleRounded'; -import ReportProblemRounded from '@material-ui/icons/ReportProblemRounded'; -import WarningRounded from '@material-ui/icons/WarningRounded'; - -type SvgIconComponent = typeof SvgIcon; - -export const Colors = { - error: 'error', - info: 'primary', - ok: 'green', - warning: 'rgb(255, 152, 0)', -}; -export type ComponentIcon = { - props: { [key: string]: any }; - icon: SvgIconComponent; -}; - -export const ErrorCoreComponent: ComponentIcon = { - props: { color: Colors.error }, - icon: ErrorRounded, -}; - -export const ErrorAddonComponent: ComponentIcon = { - props: { htmlColor: Colors.warning }, - icon: ReportProblemRounded, -}; - -export const NotReadyComponent: ComponentIcon = { - props: { color: Colors.info }, - icon: RemoveCircleRounded, -}; - -export const WarningIcon: ComponentIcon = { - props: { htmlColor: Colors.warning }, - icon: WarningRounded, -}; - -export const InfoIcon: ComponentIcon = { - props: { color: Colors.info }, - icon: InfoOutlined, -}; - -export const OkIcon: ComponentIcon = { - props: { htmlColor: Colors.ok }, - icon: CheckCircleRounded, -}; - -export const SuccessComponent = OkIcon; -export const ErrorIcon = ErrorCoreComponent; - -export const createIcon = ( - icon: ComponentIcon, - extraProp?: { [key: string]: string }, -) => { - let iconProps = icon.props; - if (extraProp) { - iconProps = { ...iconProps, ...extraProp }; - } - return createElement(icon.icon, iconProps); -}; - -export * from './MTLSStatusFull'; -export * from './MTLSStatusPartial'; diff --git a/plugins/kiali/src/components/IstioStatus/IstioComponentStatus.tsx b/plugins/kiali/src/components/IstioStatus/IstioComponentStatus.tsx new file mode 100644 index 0000000000..05da0e8508 --- /dev/null +++ b/plugins/kiali/src/components/IstioStatus/IstioComponentStatus.tsx @@ -0,0 +1,92 @@ +import * as React from 'react'; + +import { ListItem, ListItemText } from '@material-ui/core'; +import { + CheckCircleIcon, + ExclamationCircleIcon, + ExclamationTriangleIcon, + MinusCircleIcon, +} from '@patternfly/react-icons'; +import { SVGIconProps } from '@patternfly/react-icons/dist/js/createIcon'; + +import { ComponentStatus, Status } from '../../types/IstioStatus'; +import { PFColors } from '../Pf/PfColors'; + +type Props = { + componentStatus: ComponentStatus; +}; + +export type ComponentIcon = { + color: string; + icon: React.ComponentClass; +}; + +const ErrorCoreComponent: ComponentIcon = { + color: PFColors.Danger, + icon: ExclamationCircleIcon, +}; + +const ErrorAddonComponent: ComponentIcon = { + color: PFColors.Warning, + icon: ExclamationTriangleIcon, +}; + +const NotReadyComponent: ComponentIcon = { + color: PFColors.Info, + icon: MinusCircleIcon, +}; + +const SuccessComponent: ComponentIcon = { + color: PFColors.Success, + icon: CheckCircleIcon, +}; + +// Mapping Valid-Core to Icon representation. +const validToIcon: { [valid: string]: ComponentIcon } = { + 'false-false': ErrorAddonComponent, + 'false-true': ErrorCoreComponent, + 'true-false': SuccessComponent, + 'true-true': SuccessComponent, +}; + +const statusMsg = { + [Status.NotFound]: 'Not found', + [Status.NotReady]: 'Not ready', + [Status.Unhealthy]: 'Not healthy', + [Status.Unreachable]: 'Unreachable', + [Status.Healthy]: 'Healthy', +}; + +export const IstioComponentStatus = (props: Props): JSX.Element => { + const renderIcon = (status: Status, isCore: boolean) => { + let compIcon = validToIcon[`${status === Status.Healthy}-${isCore}`]; + if (status === Status.NotReady) { + compIcon = NotReadyComponent; + } + const IconComponent = compIcon.icon; + return ; + }; + + const comp = props.componentStatus; + const state = statusMsg[comp.status]; + return ( + + + + {renderIcon( + props.componentStatus.status, + props.componentStatus.is_core, + )} + + + {comp.name} + + {state && <>{state}} + + } + /> + + ); +}; diff --git a/plugins/kiali/src/components/IstioStatus/IstioStatus.tsx b/plugins/kiali/src/components/IstioStatus/IstioStatus.tsx new file mode 100644 index 0000000000..074cb251bf --- /dev/null +++ b/plugins/kiali/src/components/IstioStatus/IstioStatus.tsx @@ -0,0 +1,111 @@ +import * as React from 'react'; + +import { Tooltip } from '@material-ui/core'; +import { ResourcesFullIcon } from '@patternfly/react-icons'; +import { SVGIconProps } from '@patternfly/react-icons/dist/esm/createIcon'; + +import { ComponentStatus, Status } from '../../types/IstioStatus'; +import { PFColors } from '../Pf/PfColors'; +import { IstioStatusList } from './IstioStatusList'; + +type StatusIcons = { + ErrorIcon?: React.ComponentClass; + WarningIcon?: React.ComponentClass; + InfoIcon?: React.ComponentClass; + HealthyIcon?: React.ComponentClass; +}; + +type Props = { + status: ComponentStatus[]; + icons?: StatusIcons; + cluster?: string; +}; + +const ValidToColor = { + 'true-true-true': PFColors.Danger, + 'true-true-false': PFColors.Danger, + 'true-false-true': PFColors.Danger, + 'true-false-false': PFColors.Danger, + 'false-true-true': PFColors.Warning, + 'false-true-false': PFColors.Warning, + 'false-false-true': PFColors.Info, + 'false-false-false': PFColors.Success, +}; + +const defaultIcons = { + ErrorIcon: ResourcesFullIcon, + WarningIcon: ResourcesFullIcon, + InfoIcon: ResourcesFullIcon, + HealthyIcon: ResourcesFullIcon, +}; + +export const IstioStatus = (props: Props): React.JSX.Element => { + const tooltipContent = () => { + return ; + }; + + const tooltipColor = () => { + let coreUnhealthy: boolean = false; + let addonUnhealthy: boolean = false; + let notReady: boolean = false; + + (props.status || []).forEach(compStatus => { + const { status, is_core } = compStatus; + const isNotReady: boolean = status === Status.NotReady; + const isUnhealthy: boolean = status !== Status.Healthy && !isNotReady; + + if (is_core) { + coreUnhealthy = coreUnhealthy || isUnhealthy; + } else { + addonUnhealthy = addonUnhealthy || isUnhealthy; + } + + notReady = notReady || isNotReady; + }); + + return ValidToColor[`${coreUnhealthy}-${addonUnhealthy}-${notReady}`]; + }; + + const healthyComponents = () => { + return props.status.reduce( + (healthy: boolean, compStatus: ComponentStatus) => { + return healthy && compStatus.status === Status.Healthy; + }, + true, + ); + }; + + if (healthyComponents()) { + return <>; + } + const icons = props.icons + ? { ...defaultIcons, ...props.icons } + : defaultIcons; + const iconColor = tooltipColor(); + let Icon: React.ComponentClass = ResourcesFullIcon; + let dataTestID: string = 'istio-status'; + + if (iconColor === PFColors.Danger) { + Icon = icons.ErrorIcon; + dataTestID += '-danger'; + } else if (iconColor === PFColors.Warning) { + Icon = icons.WarningIcon; + dataTestID += '-warning'; + } else if (iconColor === PFColors.Info) { + Icon = icons.InfoIcon; + dataTestID += '-info'; + } else if (iconColor === PFColors.Success) { + Icon = icons.HealthyIcon; + dataTestID += '-success'; + } + + return ( + + + + ); +}; diff --git a/plugins/kiali/src/components/IstioStatus/IstioStatusInline.tsx b/plugins/kiali/src/components/IstioStatus/IstioStatusInline.tsx new file mode 100644 index 0000000000..3f5962786d --- /dev/null +++ b/plugins/kiali/src/components/IstioStatus/IstioStatusInline.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; + +import { + CheckCircleIcon, + ExclamationCircleIcon, + ExclamationTriangleIcon, + MinusCircleIcon, +} from '@patternfly/react-icons'; + +import { ComponentStatus } from '../../types/IstioStatus'; +import { IstioStatus } from './IstioStatus'; + +type Props = { + status: ComponentStatus[]; + cluster?: string; +}; + +export const IstioStatusInline = (props: Props): React.JSX.Element => { + return ( + + ); +}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/IstioStatusList.tsx b/plugins/kiali/src/components/IstioStatus/IstioStatusList.tsx similarity index 67% rename from plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/IstioStatusList.tsx rename to plugins/kiali/src/components/IstioStatus/IstioStatusList.tsx index 01049ef725..7106d5c272 100644 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/IstioStatusList.tsx +++ b/plugins/kiali/src/components/IstioStatus/IstioStatusList.tsx @@ -1,10 +1,8 @@ import * as React from 'react'; -import { - ComponentStatus, - IStatus, -} from '@janus-idp/backstage-plugin-kiali-common'; +import { List, Typography } from '@material-ui/core'; +import { ComponentStatus, Status } from '../../types/IstioStatus'; import { IstioComponentStatus } from './IstioComponentStatus'; type Props = { @@ -14,7 +12,7 @@ type Props = { export const IstioStatusList = (props: Props) => { const nonhealthyComponents = () => { return props.status.filter( - (c: ComponentStatus) => c.status !== IStatus.Healthy, + (c: ComponentStatus) => c.status !== Status.Healthy, ); }; @@ -34,8 +32,7 @@ export const IstioStatusList = (props: Props) => { return ['core', 'addon'].map((group: string) => // @ts-expect-error - groups[group]().map(status => ( - // @ts-expect-error + groups[group]().map((status: ComponentStatus) => ( { }; return ( -
-

Istio Components Status

-
    +
    + Istio Components Status + {renderComponentList()} -
+
); }; diff --git a/plugins/kiali-common/src/types/IstioWizards.ts b/plugins/kiali/src/components/IstioWizards/WizardActions.ts similarity index 100% rename from plugins/kiali-common/src/types/IstioWizards.ts rename to plugins/kiali/src/components/IstioWizards/WizardActions.ts diff --git a/plugins/kiali/src/components/KialiComponent/Header/Header.tsx b/plugins/kiali/src/components/KialiComponent/Header/Header.tsx deleted file mode 100644 index 7ceb499b4d..0000000000 --- a/plugins/kiali/src/components/KialiComponent/Header/Header.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import React from 'react'; - -import { ContentHeader, Select } from '@backstage/core-components'; - -import { Chip, Drawer, IconButton, Tooltip } from '@material-ui/core'; -import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; -import Info from '@material-ui/icons/Info'; -import StorageRounded from '@material-ui/icons/StorageRounded'; - -import { - KialiConfigT, - KialiInfo, - Namespace, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { getHomeCluster } from '../../../helper'; -import { StatusContent } from './StatusContent'; - -const useDrawerStyles = makeStyles((theme: Theme) => - createStyles({ - paper: { - width: '50%', - justifyContent: 'space-between', - padding: theme.spacing(2.5), - }, - }), -); - -export const KialiHeader = (props: { - title: string; - kialiStatus: KialiInfo; - config: KialiConfigT; - namespaces: Namespace[]; - namespacesFiltered: string[]; - setNamespaceFilter: (ns: string[]) => void; -}) => { - const [isOpen, toggleDrawer] = React.useState(false); - const kialiHomeCluster = getHomeCluster(props.config.server); - const classes = useDrawerStyles(); - - return ( - <> - - {props.config.username && ( -
- - User : - {props.config.username} - -
- )} - {kialiHomeCluster && ( - Kiali home cluster: {kialiHomeCluster?.name}} - > - } label={kialiHomeCluster?.name} /> - - )} - - toggleDrawer(true)} - style={{ marginTop: '-10px' }} - > - - - - toggleDrawer(false)} - > - - -
-
- - - - Strategy - - {props.kialiStatus.auth.strategy} - - - - Kiali status - - - {getStatusIcon( - props.kialiStatus.status.status['Kiali state'], - )} - - - - Kiali - {kialiVersion} - - - - Kiali Container - - {kialiContainer} - - - - Service Mesh - - {MeshVersion} - - -
- - - - - - Components - - - - - - {props.kialiStatus.status.externalServices.map(comp => ( - - - {comp.name} - - {comp.version || 'N/A'} - - ))} - -
-
-
-
- - - Configuration - - - - - - - - Configuration - - Value - - - - {getRows().map(row => ( - - {row[0]} - {row[1]} - - ))} - -
-
-
-
- - - ); -}; diff --git a/plugins/kiali/src/components/KialiComponent/Header/index.ts b/plugins/kiali/src/components/KialiComponent/Header/index.ts deleted file mode 100644 index 8a0a0dfef6..0000000000 --- a/plugins/kiali/src/components/KialiComponent/Header/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './Header'; -export * from './StatusContent'; diff --git a/plugins/kiali/src/components/KialiComponent/KialiComponent.tsx b/plugins/kiali/src/components/KialiComponent/KialiComponent.tsx deleted file mode 100644 index 982fde41a6..0000000000 --- a/plugins/kiali/src/components/KialiComponent/KialiComponent.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import React from 'react'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; -import useDebounce from 'react-use/lib/useDebounce'; - -import { - CardTab, - CodeSnippet, - Content, - Page, - TabbedCard, - WarningPanel, -} from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { useEntity } from '@backstage/plugin-catalog-react'; - -import { CircularProgress } from '@material-ui/core'; - -import { - AuthStrategy, - DefaultKialiConfig, - INITIAL_STATUS_STATE, - KialiConfigT, - KialiFetchError, - KialiInfo, - Namespace, - setServerConfig, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { kialiApiRef } from '../../api'; -import { handleMultipleMessage } from '../../helper'; -import { Overview } from '../Overview'; -import { KialiHeader } from './Header'; - -const getPathPage = () => { - const pathname = window.location.pathname.split('/').pop() || 'overview'; - return pathname === 'kiali' ? 'overview' : pathname; -}; - -export const KialiComponent = () => { - const kialiClient = useApi(kialiApiRef); - kialiClient.setEntity(useEntity().entity); - const [kialiTab, setKialiTab] = React.useState(getPathPage()); - const [kialiConfig, setKialiConfig] = - React.useState(DefaultKialiConfig); - const [kialiStatus, setKialiStatus] = React.useState({ - status: INITIAL_STATUS_STATE, - auth: { sessionInfo: {}, strategy: AuthStrategy.anonymous }, - }); - const [namespacesFiltered, setNamespacesFiltered] = React.useState( - [], - ); - const [namespaces, setNamespaces] = React.useState([]); - const [errors, setErrors] = React.useState([]); - - const fetchConfig = async () => { - let config = kialiConfig; - if (config.kialiConsole === '') { - await kialiClient.getConfig().then(resp => { - if (resp.errors.length > 0) { - setErrors(resp.errors); - } - config = resp.response as KialiConfigT; - config.server = setServerConfig(kialiConfig?.server, config.server); - setKialiConfig(config); - }); - } - }; - - const fetchNamespaces = async () => { - await kialiClient.getNamespaces().then(resp => { - if (resp.errors.length > 0) { - setErrors(resp.errors); - } - setNamespaces(resp.response as Namespace[]); - setNamespacesFiltered((resp.response as Namespace[]).map(ns => ns.name)); - }); - }; - - const [{ loading }, refresh] = useAsyncFn( - async () => { - await kialiClient.getInfo().then(response => { - if (response.errors.length > 0) { - setErrors(response.errors); - } else { - setKialiStatus(response.response as KialiInfo); - fetchConfig(); - fetchNamespaces(); - } - }); // Check if the config is loaded - }, - [], - { loading: true }, - ); - - useDebounce(refresh, 10); - - return loading ? ( - - ) : ( - - - - {errors.length > 0 && ( - - - - )} - {kialiConfig.kialiConsole !== '' && ( - <> - setKialiTab(v as string)} - > - {/* - // @ts-ignore */} - - - - - - )} - - - ); -}; diff --git a/plugins/kiali/src/components/KialiComponent/KialiNoPath.tsx b/plugins/kiali/src/components/KialiComponent/KialiNoPath.tsx deleted file mode 100644 index e6aa227a54..0000000000 --- a/plugins/kiali/src/components/KialiComponent/KialiNoPath.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; - -import { Content, Page, WarningPanel } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { useEntity } from '@backstage/plugin-catalog-react'; - -import { kialiApiRef } from '../../api'; - -export const KialiNoPath = () => { - const kialiClient = useApi(kialiApiRef); - kialiClient.setEntity(useEntity().entity); - - return ( - - - - Path {window.location.pathname} not exist in Kiali Plugin - - - - ); -}; diff --git a/plugins/kiali/src/components/KialiComponent/index.ts b/plugins/kiali/src/components/KialiComponent/index.ts deleted file mode 100644 index 55f491571c..0000000000 --- a/plugins/kiali/src/components/KialiComponent/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { KialiComponent } from './KialiComponent'; -export { KialiNoPath } from './KialiNoPath'; diff --git a/plugins/kiali/src/components/Link/IstioConfigListLink.tsx b/plugins/kiali/src/components/Link/IstioConfigListLink.tsx new file mode 100644 index 0000000000..7a5efd5040 --- /dev/null +++ b/plugins/kiali/src/components/Link/IstioConfigListLink.tsx @@ -0,0 +1,61 @@ +import * as React from 'react'; +import { Link } from 'react-router-dom'; + +import { Paths } from '../../config'; +import { FilterSelected } from '../Filters/StatefulFilters'; + +interface Props { + namespaces: string[]; + errors?: boolean; + warnings?: boolean; +} + +export class IstioConfigListLink extends React.Component { + namespacesToParams = () => { + let param: string = ''; + if (this.props.namespaces.length > 0) { + param = `namespaces=${this.props.namespaces.join(',')}`; + } + return param; + }; + + validationToParams = () => { + let params: string = ''; + + if (this.props.warnings) { + params += 'configvalidation=Warning'; + } + + let errorParams: string = ''; + if (this.props.errors) { + errorParams += 'configvalidation=Not+Valid'; + } + + if (params !== '' && errorParams !== '') { + params += '&'; + } + + params += errorParams; + + return params; + }; + + cleanFilters = () => { + FilterSelected.resetFilters(); + }; + + render() { + let params: string = this.namespacesToParams(); + const validationParams: string = this.validationToParams(); + if (params !== '' && validationParams !== '') { + params += '&'; + } + params += validationParams; + + return ( + + {this.props.children} + + ); + } +} diff --git a/plugins/kiali/src/components/Link/ValidationSummaryLink.tsx b/plugins/kiali/src/components/Link/ValidationSummaryLink.tsx new file mode 100644 index 0000000000..a64fe47f5e --- /dev/null +++ b/plugins/kiali/src/components/Link/ValidationSummaryLink.tsx @@ -0,0 +1,39 @@ +import * as React from 'react'; + +import { IstioConfigListLink } from './IstioConfigListLink'; + +type Props = { + namespace: string; + errors: number; + warnings: number; + objectCount?: number; + children: React.ReactNode; +}; + +export class ValidationSummaryLink extends React.Component { + hasIstioObjects = () => { + return this.props.objectCount && this.props.objectCount > 0; + }; + + render() { + let link: any = ( +
N/A
+ ); + + if (this.hasIstioObjects()) { + // Kiosk actions are used when the kiosk specifies a parent, + // otherwise the kiosk=true will keep the links inside Kiali + link = ( + 0} + errors={this.props.errors > 0} + > + {this.props.children} + + ); + } + + return link; + } +} diff --git a/plugins/kiali/src/components/MTls/MTLSIcon.tsx b/plugins/kiali/src/components/MTls/MTLSIcon.tsx new file mode 100644 index 0000000000..69bcd9d2ad --- /dev/null +++ b/plugins/kiali/src/components/MTls/MTLSIcon.tsx @@ -0,0 +1,53 @@ +import * as React from 'react'; + +import { Tooltip, TooltipPosition } from '@patternfly/react-core'; + +const fullIcon = require('../../assets/img/mtls-status-full.svg') as string; +const hollowIcon = + require('../../assets/img/mtls-status-partial.svg') as string; +const fullIconDark = + require('../../assets/img/mtls-status-full-dark.svg') as string; +const hollowIconDark = + require('../../assets/img/mtls-status-partial-dark.svg') as string; + +export { fullIcon, hollowIcon, fullIconDark, hollowIconDark }; + +type Props = { + icon: string; + iconClassName: string; + tooltipText: string; + tooltipPosition: TooltipPosition; +}; + +export enum MTLSIconTypes { + LOCK_FULL = 'LOCK_FULL', + LOCK_HOLLOW = 'LOCK_HOLLOW', + LOCK_FULL_DARK = 'LOCK_FULL_DARK', + LOCK_HOLLOW_DARK = 'LOCK_HOLLOW_DARK', +} + +const nameToSource = new Map([ + [MTLSIconTypes.LOCK_FULL, fullIcon], + [MTLSIconTypes.LOCK_FULL_DARK, fullIconDark], + [MTLSIconTypes.LOCK_HOLLOW, hollowIcon], + [MTLSIconTypes.LOCK_HOLLOW_DARK, hollowIconDark], +]); + +export class MTLSIcon extends React.Component { + render() { + return ( + + {this.props.tooltipPosition} + + ); + } +} diff --git a/plugins/kiali/src/components/MTls/MTLSStatus.tsx b/plugins/kiali/src/components/MTls/MTLSStatus.tsx new file mode 100644 index 0000000000..ff0e916826 --- /dev/null +++ b/plugins/kiali/src/components/MTls/MTLSStatus.tsx @@ -0,0 +1,67 @@ +import * as React from 'react'; + +import { TooltipPosition } from '@patternfly/react-core'; + +import { MTLSIcon } from './MTLSIcon'; + +type Props = { + status: string; + statusDescriptors: Map; + className?: string; + overlayPosition?: TooltipPosition; +}; + +export type StatusDescriptor = { + message: string; + icon: string; + showStatus: boolean; +}; + +export const emptyDescriptor = { + message: '', + icon: '', + showStatus: false, +}; + +export class MTLSStatus extends React.Component { + statusDescriptor() { + return ( + this.props.statusDescriptors.get(this.props.status) || emptyDescriptor + ); + } + + icon() { + return this.statusDescriptor().icon; + } + + message() { + return this.statusDescriptor().message; + } + + showStatus() { + return this.statusDescriptor().showStatus; + } + + overlayPosition() { + return this.props.overlayPosition || TooltipPosition.left; + } + + iconClassName() { + return this.props.className || ''; + } + + render() { + if (this.showStatus()) { + return ( + + ); + } + + return null; + } +} diff --git a/plugins/kiali/src/components/MTls/NamespaceMTLSStatus.tsx b/plugins/kiali/src/components/MTls/NamespaceMTLSStatus.tsx new file mode 100644 index 0000000000..72aa2a04a4 --- /dev/null +++ b/plugins/kiali/src/components/MTls/NamespaceMTLSStatus.tsx @@ -0,0 +1,60 @@ +import * as React from 'react'; + +import { kialiStyle } from '../../styles/StyleUtils'; +import { MTLSStatuses } from '../../types/TLSStatus'; +import { MTLSIconTypes } from './MTLSIcon'; +import { emptyDescriptor, MTLSStatus, StatusDescriptor } from './MTLSStatus'; + +type Props = { + status: string; +}; + +const statusDescriptors = new Map([ + [ + MTLSStatuses.ENABLED, + { + message: 'mTLS is enabled for this namespace', + icon: MTLSIconTypes.LOCK_FULL_DARK, + showStatus: true, + }, + ], + [ + MTLSStatuses.ENABLED_EXTENDED, + { + message: + 'mTLS is enabled for this namespace, extended from Mesh-wide config', + icon: MTLSIconTypes.LOCK_FULL_DARK, + showStatus: true, + }, + ], + [ + MTLSStatuses.PARTIALLY, + { + message: 'mTLS is partially enabled for this namespace', + icon: MTLSIconTypes.LOCK_HOLLOW_DARK, + showStatus: true, + }, + ], + [MTLSStatuses.DISABLED, emptyDescriptor], + [MTLSStatuses.NOT_ENABLED, emptyDescriptor], +]); + +// Magic style to align Istio Config icons on top of status overview +const iconStyle = kialiStyle({ + marginTop: -3, + marginRight: 18, + marginLeft: 2, + width: 10, +}); + +export class NamespaceMTLSStatus extends React.Component { + render() { + return ( + + ); + } +} diff --git a/plugins/kiali/src/components/MessageCenter/AlertDrawer.tsx b/plugins/kiali/src/components/MessageCenter/AlertDrawer.tsx new file mode 100644 index 0000000000..2b5d3b19fa --- /dev/null +++ b/plugins/kiali/src/components/MessageCenter/AlertDrawer.tsx @@ -0,0 +1,91 @@ +import * as React from 'react'; + +import { ItemCardHeader } from '@backstage/core-components'; + +import { + Accordion, + AccordionDetails, + AccordionSummary, + Card, + CardContent, + CardMedia, + Typography, +} from '@material-ui/core'; +import ExpandMoreRounded from '@material-ui/icons/ExpandMoreRounded'; +import { InfoIcon } from '@patternfly/react-icons'; + +import { KialiAppAction } from '../../actions/KialiAppAction'; +import { MessageCenterState } from '../../store'; +import { kialiStyle } from '../../styles/StyleUtils'; +import { + NotificationGroup, + NotificationMessage, +} from '../../types/MessageCenter'; +import { AlertDrawerGroup } from './AlertDrawerGroup'; + +type AlertDrawerProps = { + toggleDrawer: (isOpen: boolean) => void; + messages: MessageCenterState; + messageDispatch: React.Dispatch; +}; + +const hideGroup = (group: NotificationGroup): boolean => { + return group.hideIfEmpty && group.messages.length === 0; +}; + +const getUnreadCount = (messages: NotificationMessage[]) => { + return messages.reduce((count, message) => { + return message.seen ? count : count + 1; + }, 0); +}; + +const getUnreadMessageLabel = (messages: NotificationMessage[]) => { + const unreadCount = getUnreadCount(messages); + return unreadCount === 1 + ? '1 Unread Message' + : `${getUnreadCount(messages)} Unread Messages`; +}; + +const drawer = kialiStyle({ + display: 'flex', + width: '500px', + justifyContent: 'space-between', +}); + +const noNotificationsMessage = ( + <> + + No Messages Available + +); + +export const AlertDrawer = (props: AlertDrawerProps) => { + return ( + + + + + + {props.messages.groups.length === 0 + ? noNotificationsMessage + : props.messages.groups.map(group => + hideGroup(group) ? null : ( + + } + > + + {group.title} {getUnreadMessageLabel(group.messages)} + + + + + + + ), + )} + + + ); +}; diff --git a/plugins/kiali/src/components/MessageCenter/AlertDrawerGroup.tsx b/plugins/kiali/src/components/MessageCenter/AlertDrawerGroup.tsx new file mode 100644 index 0000000000..839be0834f --- /dev/null +++ b/plugins/kiali/src/components/MessageCenter/AlertDrawerGroup.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; + +import { Button, Card, CardActions, CardContent } from '@material-ui/core'; +import { InfoIcon } from '@patternfly/react-icons'; + +import { MessageCenterActions } from '../../actions'; +import { KialiAppState, KialiContext } from '../../store'; +import { NotificationGroup } from '../../types/MessageCenter'; +import { AlertDrawerMessage } from './AlertDrawerMessage'; + +type AlertDrawerGroupProps = { + group: NotificationGroup; + reverseMessageOrder?: boolean; +}; + +const noNotificationsMessage = ( + <> + + No Messages Available + +); + +export const AlertDrawerGroup = (props: AlertDrawerGroupProps) => { + const kialiState = React.useContext(KialiContext) as KialiAppState; + + const markGroupAsRead = (groupId: string) => { + const foundGroup = kialiState.messageCenter.groups.find( + group => group.id === groupId, + ); + if (foundGroup) { + kialiState.dispatch.messageDispatch( + MessageCenterActions.markAsRead( + foundGroup.messages.map(message => message.id), + ), + ); + } + }; + + const clearGroup = (groupId: string) => { + const foundGroup = kialiState.messageCenter.groups.find( + group => group.id === groupId, + ); + if (foundGroup) { + kialiState.dispatch.messageDispatch( + MessageCenterActions.removeMessage( + foundGroup.messages.map(message => message.id), + ), + ); + } + }; + + const getMessages = () => { + return props.reverseMessageOrder + ? [...props.group.messages].reverse() + : props.group.messages; + }; + + const group: NotificationGroup = props.group; + + return ( + + + {group.messages.length === 0 && noNotificationsMessage} + {getMessages().map(message => ( + + ))} + + {group.showActions && group.messages.length > 0 && ( + + + + + )} + + ); +}; diff --git a/plugins/kiali/src/components/MessageCenter/AlertDrawerMessage.tsx b/plugins/kiali/src/components/MessageCenter/AlertDrawerMessage.tsx new file mode 100644 index 0000000000..6861cbf894 --- /dev/null +++ b/plugins/kiali/src/components/MessageCenter/AlertDrawerMessage.tsx @@ -0,0 +1,90 @@ +import * as React from 'react'; + +import { + Accordion, + AccordionDetails, + AccordionSummary, + Card, + CardContent, + Typography, +} from '@material-ui/core'; +import ExpandMoreRounded from '@material-ui/icons/ExpandMoreRounded'; +import moment from 'moment'; + +import { MessageCenterActions } from '../../actions/MessageCenterActions'; +import { KialiIcon } from '../../config/KialiIcon'; +import { KialiAppState, KialiContext } from '../../store'; +import { MessageType, NotificationMessage } from '../../types/MessageCenter'; + +const getIcon = (type: MessageType) => { + switch (type) { + case MessageType.ERROR: + return ; + case MessageType.INFO: + return ; + case MessageType.SUCCESS: + return ; + case MessageType.WARNING: + return ; + default: + throw Error('Unexpected type'); + } +}; + +type AlertDrawerMessageProps = { + message: NotificationMessage; +}; + +export const AlertDrawerMessage = (props: AlertDrawerMessageProps) => { + const kialiState = React.useContext(KialiContext) as KialiAppState; + + // const markAsRead = (message: NotificationMessage) => kialiState.dispatch.messageDispatch(MessageCenterActions.markAsRead(message.id)); + const toggleMessageDetail = (message: NotificationMessage) => + kialiState.dispatch.messageDispatch( + MessageCenterActions.toggleMessageDetail(message.id), + ); + + return ( + + + {getIcon(props.message.type)}{' '} + {props.message.seen ? ( + props.message.content + ) : ( + {props.message.content} + )} + {props.message.detail && ( + + toggleMessageDetail(props.message)} + expandIcon={} + > + + {props.message.showDetail ? 'Hide Detail' : 'Show Detail'} + + + +
+                {props.message.detail}
+              
+
+
+ )} + {props.message.count > 1 && ( +
+ {props.message.count} {moment().from(props.message.firstTriggered)} +
+ )} +
+ + {props.message.created.toLocaleDateString()} + + + {props.message.created.toLocaleTimeString()} + +
+
+
+ ); +}; diff --git a/plugins/kiali/src/components/MessageCenter/MessageCenter.tsx b/plugins/kiali/src/components/MessageCenter/MessageCenter.tsx new file mode 100644 index 0000000000..6a66f8072a --- /dev/null +++ b/plugins/kiali/src/components/MessageCenter/MessageCenter.tsx @@ -0,0 +1,114 @@ +import * as React from 'react'; + +import { Badge, Button, Drawer } from '@material-ui/core'; + +import { KialiIcon } from '../../config/KialiIcon'; +import { KialiAppState, KialiContext } from '../../store'; +import { kialiStyle } from '../../styles/StyleUtils'; +import { + MessageType, + NotificationGroup, + NotificationMessage, +} from '../../types/MessageCenter'; +import { AlertDrawer } from './AlertDrawer'; + +const bell = kialiStyle({ + position: 'relative', + right: '5px', + top: '5px', +}); + +const calculateMessageStatus = (state: KialiAppState) => { + type MessageCenterTriggerPropsToMap = { + newMessagesCount: number; + badgeDanger: boolean; + systemErrorsCount: number; + }; + + const dangerousMessageTypes = [MessageType.ERROR, MessageType.WARNING]; + let systemErrorsCount = 0; + + const systemErrorsGroup = state.messageCenter.groups.find( + item => item.id === 'systemErrors', + ); + if (systemErrorsGroup) { + systemErrorsCount = systemErrorsGroup.messages.length; + } + + return state.messageCenter.groups + .reduce( + (unreadMessages: NotificationMessage[], group: NotificationGroup) => { + return unreadMessages.concat( + group.messages.reduce( + ( + unreadMessagesInGroup: NotificationMessage[], + message: NotificationMessage, + ) => { + if (!message.seen) { + unreadMessagesInGroup.push(message); + } + return unreadMessagesInGroup; + }, + [], + ), + ); + }, + [], + ) + .reduce( + ( + propsToMap: MessageCenterTriggerPropsToMap, + message: NotificationMessage, + ) => { + propsToMap.newMessagesCount++; + propsToMap.badgeDanger = + propsToMap.badgeDanger || + dangerousMessageTypes.includes(message.type); + return propsToMap; + }, + { + newMessagesCount: 0, + systemErrorsCount: systemErrorsCount, + badgeDanger: false, + }, + ); +}; + +export const MessageCenter = () => { + const kialiState = React.useContext(KialiContext) as KialiAppState; + const [isOpen, toggleDrawer] = React.useState(false); + const messageCenterStatus = calculateMessageStatus(kialiState); + /* + const onDismiss = (message: NotificationMessage, userDismissed: boolean) => { + if (userDismissed) { + kialiState.messageDispatch(MessageCenterActions.markAsRead(message.id)); + } else { + kialiState.messageDispatch(MessageCenterActions.hideNotification(message.id)); + } + } + */ + return ( + <> + + toggleDrawer(false)}> + + + + ); +}; diff --git a/plugins/kiali/src/components/MissingSidecar/MissingSidecar.tsx b/plugins/kiali/src/components/MissingSidecar/MissingSidecar.tsx new file mode 100644 index 0000000000..b73104da84 --- /dev/null +++ b/plugins/kiali/src/components/MissingSidecar/MissingSidecar.tsx @@ -0,0 +1,103 @@ +import * as React from 'react'; + +import { Tooltip, TooltipPosition } from '@patternfly/react-core'; +import { SVGIconProps } from '@patternfly/react-icons/dist/js/createIcon'; + +import { icons } from '../../config/Icons'; +import { KialiIcon } from '../../config/KialiIcon'; +import { isIstioNamespace, serverConfig } from '../../config/ServerConfig'; +import { kialiStyle } from '../../styles/StyleUtils'; + +type MissingSidecarProps = { + 'data-test'?: string; + text: string; + textmesh?: string; + texttooltip: string; + tooltip: boolean; + meshtooltip: string; + icon: React.ComponentClass; + color: string; + namespace: string; + style?: React.CSSProperties; + isGateway?: boolean; +}; + +const infoStyle = kialiStyle({ + margin: '0px 5px 2px 4px', + verticalAlign: '-5px !important', +}); + +export class MissingSidecar extends React.Component { + static defaultProps = { + textmesh: 'Out of mesh', + text: 'Missing Sidecar', + meshtooltip: + 'Out of mesh. Istio sidecar container or Ambient labels not found in Pod(s). Check if the istio-injection label/annotation is correctly set on the namespace/workload.', + texttooltip: + 'Istio sidecar container not found in Pod(s). Check if the istio-injection label/annotation is correctly set on the namespace/workload.', + tooltip: false, + icon: icons.istio.missingSidecar.icon, + color: icons.istio.missingSidecar.color, + }; + + render() { + const { + text, + texttooltip, + icon, + namespace, + color, + tooltip, + style, + ...otherProps + } = this.props; + const iconComponent = ( + + {React.createElement(icon, { + style: { color: color, verticalAlign: '-2px' }, + })} + {!tooltip && ( + + {serverConfig.ambientEnabled + ? this.props.textmesh + : this.props.text} + + {serverConfig.ambientEnabled + ? this.props.meshtooltip + : this.props.texttooltip} + + } + > + + + + )} + + ); + + if (isIstioNamespace(namespace) || this.props.isGateway) { + return <>; + } + + return tooltip ? ( + + {serverConfig.ambientEnabled + ? this.props.meshtooltip + : this.props.texttooltip} + + } + position={TooltipPosition.right} + > + {iconComponent} + + ) : ( + iconComponent + ); + } +} diff --git a/plugins/kiali/src/components/Overview/Overview.tsx b/plugins/kiali/src/components/Overview/Overview.tsx deleted file mode 100644 index a811dc9669..0000000000 --- a/plugins/kiali/src/components/Overview/Overview.tsx +++ /dev/null @@ -1,224 +0,0 @@ -import React, { useState } from 'react'; -import useAsyncFn from 'react-use/lib/useAsyncFn'; -import useDebounce from 'react-use/lib/useDebounce'; - -import { CodeSnippet, WarningPanel } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; -import { useEntity } from '@backstage/plugin-catalog-react'; - -import { CircularProgress, Grid } from '@material-ui/core'; - -import { - CanaryUpgradeStatus, - ComponentStatus, - IstiodResourceThresholds, - KialiConfigT, - KialiFetchError, - KialiInfo, - NamespaceInfo, - OutboundTrafficPolicy, - OverviewData, - OverviewType, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { kialiApiRef } from '../../api'; -import { calculateHealth } from './health'; -import { OverviewCard } from './OverviewCard'; -import { OverviewToolbar } from './OverviewToolbar'; - -export declare enum OverviewDisplayMode { - COMPACT = 0, - EXPAND = 1, - LIST = 2, -} - -declare const directionTypes: { - inbound: string; - outbound: string; -}; -export type DirectionType = keyof typeof directionTypes; - -type OverviewProps = { - kialiConfig: KialiConfigT; - kialiStatus: KialiInfo; - namespacesFiltered: string[]; -}; - -export const Overview = (props: OverviewProps) => { - const kialiClient = useApi(kialiApiRef); - kialiClient.setEntity(useEntity().entity); - const [namespaces, setNamespaces] = useState([]); - const [canaryStatus, setCanaryStatus] = React.useState< - CanaryUpgradeStatus | undefined - >(undefined); - const [canaryUpgrade, setCanaryUpgrade] = React.useState(false); - const [componentStatus, setComponentStatus] = React.useState< - ComponentStatus[] - >([]); - const [direction, setDirection] = React.useState('inbound'); - const [duration, setDuration] = React.useState(600); - const [overviewType, setOverviewType] = React.useState('app'); - const [outboundTrafficPolicy, setoutboundTrafficPolicy] = - React.useState({ mode: '' }); - const [istiodResourceThresholds, setIstiodResourceThresholds] = - React.useState(undefined); - const [errors, setErrors] = React.useState([]); - const [warnings, setWarnings] = React.useState([]); - - const fetchInfo = async ( - config: KialiConfigT = props.kialiConfig, - dur: number = duration, - ovType: OverviewType = overviewType, - dir: DirectionType = direction, - ) => { - await kialiClient - .getOverview(ovType, dur, dir) - .then(response => { - if (response.errors.length > 0) { - setErrors(response.errors); - } else { - setWarnings(response.warnings); - const ovData = response.response as OverviewData; - const ns = ovData.namespaces; - try { - if (ns.length > 0) { - ns.forEach((n, i) => { - ns[i] = calculateHealth(config.server, ovType, n, dur); - }); - } else { - const newWarnings = warnings; - newWarnings.push({ - errorType: 'SYSTEM_ERROR', - message: `No namespaces for Health`, - }); - setWarnings(newWarnings); - } - } catch (e) { - const newWarnings = warnings; - newWarnings.push({ - errorType: 'SYSTEM_ERROR', - message: `Error calculating Health : ${e}`, - }); - setWarnings(newWarnings); - } - setNamespaces(ns); - setIstiodResourceThresholds(ovData.istiodResourceThresholds); - setoutboundTrafficPolicy(ovData.outboundTraffic || { mode: '' }); - setComponentStatus(ovData.istioStatus || []); - setCanaryStatus(ovData.canaryUpgrade); - setCanaryUpgrade( - ovData.canaryUpgrade!.pendingNamespaces.length > 0 || - ovData.canaryUpgrade!.migratedNamespaces.length > 0, - ); - } - }) - .catch(e => { - const newWarnings = warnings; - newWarnings.push({ - errorType: 'SYSTEM_ERROR', - message: `Error calculating Health : ${e}`, - }); - setWarnings(newWarnings); - }); - }; - - const [{ loading }, refresh] = useAsyncFn( - async () => { - // Check if the config is loaded - await fetchInfo(); - }, - [duration, overviewType, direction], - { loading: true }, - ); - useDebounce(refresh, 10); - - if (errors.length > 0) { - const message = errors - .map( - e => - `Error ${e.errorType.toString()}, Code: ${e.statusCode} fetching ${ - e.resourcePath - } : ${e.message}`, - ) - .join('\n'); - return ( - - - - ); - } - - if (loading) { - return ; - } - - const handleToolbar = ( - dur: number = duration, - ovType: OverviewType = overviewType, - dir: DirectionType = direction, - ) => { - setWarnings([]); - fetchInfo(props.kialiConfig, dur, ovType, dir); - setDuration(dur); - setOverviewType(ovType); - setDirection(dir); - }; - - return ( - <> - {warnings.length > 0 && ( - - - `Error ${e.errorType.toString()},${ - e.statusCode ? `Code: ${e.statusCode}` : '' - } ${e.resourcePath ? ` fetching ${e.resourcePath}` : ''} : ${ - e.message - }`, - ) - .join('\n')} - /> - - )} - {namespaces.length > 0 && ( - <> - handleToolbar(duration, overviewType, direction)} - duration={duration} - setDuration={e => handleToolbar(e, overviewType, direction)} - overviewType={overviewType} - setOverviewType={e => handleToolbar(duration, e, direction)} - direction={direction} - setDirection={e => handleToolbar(duration, overviewType, e)} - /> - - {namespaces.map( - (ns, _) => - props.namespacesFiltered.indexOf(ns.name) > -1 && ( - - ), - )} - - - )} - - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCard.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCard.tsx deleted file mode 100644 index 34011bb2be..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCard.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import React from 'react'; - -import { Link } from '@backstage/core-components'; - -import { Card, CardActions, CardContent, Grid } from '@material-ui/core'; - -import { - CanaryUpgradeStatus, - ComponentStatus, - IstiodResourceThresholds, - KialiConfigT, - NamespaceInfo, - OutboundTrafficPolicy, - OverviewType, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { OverviewCardBody } from './OverviewCardBody'; -import { OverviewCardHeader } from './OverviewCardHeader'; -import { OverviewMetrics } from './OverviewMetrics'; - -declare const directionTypes: { - inbound: string; - outbound: string; -}; -export type DirectionType = keyof typeof directionTypes; - -export type DirectionTypeOptions = 'inbound' | 'outbound'; - -type OverviewCardProps = { - canaryStatus?: CanaryUpgradeStatus; - canaryUpgrade?: boolean; - direction: DirectionTypeOptions; - duration: number; - ns: NamespaceInfo; - outboundTrafficPolicy: OutboundTrafficPolicy; - istioAPIEnabled?: boolean; - istiodResourceThresholds?: IstiodResourceThresholds; - istioStatus?: ComponentStatus[]; - kialiConfig: KialiConfigT; - type: OverviewType; -}; - -const getLinks = ( - ns: NamespaceInfo, - graphtype: string, - duration: number, - link: string, -): { [key: string]: string } => { - // graph Params - - const graphTypeQ = `graphType=${graphtype}`; - const durationQ = `duration=${duration}`; - const namespaces = `namespaces=${ns.name}`; - const graph = `${ - new URL('/console/graph/namespaces', link).href - }?${graphTypeQ}&${durationQ}&${namespaces}`; - - // Istio Config List Params - const validations = ns.validations; - let validationP = ''; - if (validations) { - if (validations.warnings) { - validationP += 'configvalidation=Warning'; - } - if (validationP !== '') { - validationP += '&'; - } - if (validations.errors) { - validationP += 'configvalidation=Not+Valid'; - } - } - - const istioValidations = `${ - new URL('/console/istio', link).href - }?${namespaces}&${validationP}`; - - return { - graph, - istioValidations, - }; -}; - -export const OverviewCard = (props: OverviewCardProps) => { - const links = getLinks( - props.ns, - props.type, - props.duration, - props.kialiConfig.kialiConsole, - ); - const isIstioNs = props.ns.name === props.kialiConfig.server.istioNamespace; - return ( - - - - - - - - - - - - - - - Go To Kiali Graph - - - - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/ControlPlaneNamespaceStatus.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/ControlPlaneNamespaceStatus.tsx deleted file mode 100644 index 37bec4ede5..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/ControlPlaneNamespaceStatus.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import React from 'react'; - -import { Chip, Tooltip } from '@material-ui/core'; -import InfoOutlined from '@material-ui/icons/InfoOutlined'; - -import { - NamespaceInfo, - OutboundTrafficPolicy, -} from '@janus-idp/backstage-plugin-kiali-common'; - -type ControlPlaneNamespaceStatusProps = { - namespace: NamespaceInfo; - outboundTrafficPolicy?: OutboundTrafficPolicy; -}; - -const getContentLabel = (mode?: string) => { - return ( -
- {mode} -
- ); -}; -export const ControlPlaneNamespaceStatus = ( - props: ControlPlaneNamespaceStatusProps, -) => { - let maxProxyPushTime: number | undefined = undefined; - if (props.namespace.controlPlaneMetrics?.istiod_proxy_time) { - maxProxyPushTime = - props.namespace.controlPlaneMetrics?.istiod_proxy_time[0].datapoints.reduce( - (a, b) => (a[1] < b[1] ? a : b), - )[1] * 1000; - } - let showProxyPushTime = false; - if (maxProxyPushTime && !isNaN(maxProxyPushTime)) { - showProxyPushTime = true; - } - - return ( -
- {props.outboundTrafficPolicy && ( -
-
- Outbound policy -
- - This value represents the meshConfig.outboundTrafficPolicy.mode, - that configures the sidecar handling of external services, that - is, those services that are not defined in Istio’s internal - service registry. If this option is set to ALLOW_ANY, the Istio - proxy lets calls to unknown services pass through. If the option - is set to REGISTRY_ONLY, then the Istio proxy blocks any host - without an HTTP service or service entry defined within the mesh -
- } - placement="right" - > - - -
- )} - {showProxyPushTime && ( -
-
- Proxy push time -
- - This value represents the delay in seconds between config change - and a proxy receiving all required configuration. -
- } - > - } - style={{ color: '#002952', backgroundColor: '#e7f1fa' }} - /> - - - )} - - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/IstioConfigStatus.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/IstioConfigStatus.tsx deleted file mode 100644 index e3197a83b9..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/IstioConfigStatus.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import React from 'react'; - -import { Link } from '@backstage/core-components'; - -import { Tooltip } from '@material-ui/core'; - -import { - NamespaceInfo, - ValidationStatus, - ValidationTypes, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { - createIcon, - ErrorIcon, - InfoIcon, - OkIcon, - WarningIcon, -} from '../../../Icons'; - -declare const directionTypes: { - inbound: string; - outbound: string; -}; -export type DirectionType = keyof typeof directionTypes; - -type IstioConfigStatusProps = { - ns: NamespaceInfo; - kialiConsole: string; -}; - -const getIcon = (severity: ValidationTypes, props?: any) => { - switch (severity) { - case ValidationTypes.Error: - return createIcon(ErrorIcon, props); - case ValidationTypes.Warning: - return createIcon(WarningIcon, props); - case ValidationTypes.Info: - return createIcon(InfoIcon, props); - default: - return createIcon(OkIcon, props); - } -}; - -const getTypeMessage = (count: number, type: ValidationTypes): string => { - return count > 1 ? `${count} ${type}s found` : `${count} ${type} found`; -}; - -const severitySummary = (warnings: number, errors: number) => { - const issuesMessages: string[] = []; - - if (errors > 0) { - issuesMessages.push(getTypeMessage(errors, ValidationTypes.Error)); - } - - if (warnings > 0) { - issuesMessages.push(getTypeMessage(warnings, ValidationTypes.Warning)); - } - - if (issuesMessages.length === 0) { - issuesMessages.push('No issues found'); - } - - return issuesMessages; -}; - -const tooltipContent = (validations: ValidationStatus) => { - if (validations.objectCount) { - if (validations.objectCount === 0) { - return <>No Istio config objects found; - } - - return ( - <> - Istio config objects analyzed: {validations.objectCount} -
-
    - {severitySummary(validations.warnings, validations.errors).map( - cat => ( -
  • {cat}
  • - ), - )} -
- - ); - } - return <>No Istio config validation available; -}; - -export const IstioConfigStatus = (props: IstioConfigStatusProps) => { - let validations: ValidationStatus = { - objectCount: 0, - errors: 0, - warnings: 0, - }; - let validationP = ''; - let severity = ValidationTypes.Correct; - if (props.ns.validations) { - validations = props.ns.validations; - if (validations.warnings) { - validationP += 'configvalidation=Warning'; - } - if (validationP !== '') { - validationP += '&'; - } - if (validations.errors) { - validationP += 'configvalidation=Not+Valid'; - } - if (validations.errors > 0) { - severity = ValidationTypes.Error; - } else if (validations.warnings > 0) { - severity = ValidationTypes.Warning; - } - } - const namespaces = `namespaces=${props.ns.name}`; - const linkIstioValidations = `${ - new URL('/console/istio', props.kialiConsole).href - }?${namespaces}&${validationP}`; - - return validations.objectCount && validations.objectCount > 0 ? ( - - - {validations.objectCount > 0 ? ( - getIcon(severity, { fontSize: 'inherit' }) - ) : ( -
N/A
- )} -
- - ) : ( -
N/A
- ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/NamespaceMTLSStatus.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/NamespaceMTLSStatus.tsx deleted file mode 100644 index 0bcbcf8e60..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/NamespaceMTLSStatus.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; - -import { Tooltip } from '@material-ui/core'; - -import { MTLSStatuses } from '@janus-idp/backstage-plugin-kiali-common'; - -import { - MTLSStatusFull, - MTLSStatusFullDark, - MTLSStatusPartial, - MTLSStatusPartialDark, -} from '../../../Icons'; - -type NamespaceMTLSStatusProps = { - status: string; -}; - -enum MTLSIconTypes { - LOCK_FULL = 'LOCK_FULL', - LOCK_HOLLOW = 'LOCK_HOLLOW', - LOCK_FULL_DARK = 'LOCK_FULL_DARK', - LOCK_HOLLOW_DARK = 'LOCK_HOLLOW_DARK', -} - -const emptyDescriptor = { - message: '', - icon: '', - showStatus: false, -}; - -type StatusDescriptor = { - message: string; - icon: string; - showStatus: boolean; -}; - -const statusDescriptors = new Map([ - [ - MTLSStatuses.ENABLED, - { - message: 'mTLS is enabled for this namespace', - icon: MTLSIconTypes.LOCK_FULL_DARK, - showStatus: true, - }, - ], - [ - MTLSStatuses.ENABLED_EXTENDED, - { - message: - 'mTLS is enabled for this namespace, extended from Mesh-wide config', - icon: MTLSIconTypes.LOCK_FULL_DARK, - showStatus: true, - }, - ], - [ - MTLSStatuses.PARTIALLY, - { - message: 'mTLS is partially enabled for this namespace', - icon: MTLSIconTypes.LOCK_HOLLOW_DARK, - showStatus: true, - }, - ], - [MTLSStatuses.DISABLED, emptyDescriptor], - [MTLSStatuses.NOT_ENABLED, emptyDescriptor], -]); - -const nameToSource: { [key: string]: JSX.Element } = { - LOCK_FULL: , - LOCK_HOLLOW: , - LOCK_FULL_DARK: , - LOCK_HOLLOW_DARK: , -}; - -export const NamespaceMTLSStatus = (props: NamespaceMTLSStatusProps) => { - const stat = statusDescriptors.get(props.status) || emptyDescriptor; - - return ( - - <>{nameToSource[stat.icon]} - - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/NamespaceStatuses.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/NamespaceStatuses.tsx deleted file mode 100644 index 30f486bae7..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/NamespaceStatuses.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React from 'react'; - -import { Grid } from '@material-ui/core'; - -import { - DEGRADED, - FAILURE, - HEALTHY, - NamespaceInfo, - NOT_READY, - OverviewType, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { switchType } from '../../../../helper'; -import { OverviewStatus } from './OverviewStatus'; - -type NamespaceStatusesProps = { - ns: NamespaceInfo; - type: OverviewType; -}; -export const NamespaceStatuses = (props: NamespaceStatusesProps) => { - const name = props.ns.name; - const status = props.ns.status; - const nbItems = status - ? Object.values(status).reduce((acc, val) => acc + val.length, 0) - : 0; - const text = - nbItems === 1 - ? switchType(props.type, '1 application', '1 service', '1 workload') - : nbItems + - switchType(props.type, ' applications', ' services', ' workloads'); - - const link = ( -
- {text} -
- ); - - return nbItems === props.ns.status?.notAvailable.length ? ( -
- {text} -
- ) : ( - <> - - {link} - - {status && status.inNotReady.length > 0 && ( - - )} - {status && status.inError.length > 0 && ( - - )} - {status && status.inWarning.length > 0 && ( - - )} - {status && status.inSuccess.length > 0 && ( - - )} - - - - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/OverviewCardBody.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/OverviewCardBody.tsx deleted file mode 100644 index 3f6c6aa2f8..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/OverviewCardBody.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import React from 'react'; - -import { Grid, Tooltip } from '@material-ui/core'; - -import { - CanaryUpgradeStatus, - ComponentStatus, - IstiodResourceThresholds, - KialiConfigT, - NamespaceInfo, - OutboundTrafficPolicy, - OverviewType, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { DirectionTypeOptions } from '../OverviewCard'; -import { ControlPlaneNamespaceStatus } from './ControlPlaneNamespaceStatus'; -import { IstioConfigStatus } from './IstioConfigStatus'; -import { NamespaceMTLSStatus } from './NamespaceMTLSStatus'; -import { NamespaceStatuses } from './NamespaceStatuses'; -import { TLSInfo } from './TLSInfo'; - -type OverviewCardBodyProps = { - canaryStatus?: CanaryUpgradeStatus; - canaryUpgrade?: boolean; - direction: DirectionTypeOptions; - duration: number; - ns: NamespaceInfo; - outboundTrafficPolicy: OutboundTrafficPolicy; - istioAPIEnabled?: boolean; - istiodResourceThresholds?: IstiodResourceThresholds; - istioStatus?: ComponentStatus[]; - kialiConfig: KialiConfigT; - type: OverviewType; -}; - -const render_labels = (labels: { [key: string]: string } | undefined) => { - const labelsLength = labels ? `${Object.entries(labels).length}` : 'No'; - const labelContent = labels ? ( - - {Object.entries(labels || []).map(([key, value]) => ( -
  • - {key}={value} -
  • - ))} - - } - > -
    - {labelsLength} label{labelsLength !== '1' ? 's' : ''} -
    -
    - ) : ( -
    No labels
    - ); - - return labelContent; -}; - -export const OverviewCardBody = (props: OverviewCardBodyProps) => { - const isIstioNs = props.kialiConfig.server.istioNamespace === props.ns.name; - return ( - - - {render_labels(props.ns.labels)} -
    -
    - Istio config -
    - {props.ns.tlsStatus && ( - - - - )} - {props.istioAPIEnabled && ( - - )} -
    - {props.ns.status && ( - - )} - {isIstioNs && ( - <> - - - - )} -
    -
    - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/OverviewStatus.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/OverviewStatus.tsx deleted file mode 100644 index bbfd3b1697..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/OverviewStatus.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react'; - -import { Tooltip } from '@material-ui/core'; - -import { Status } from '@janus-idp/backstage-plugin-kiali-common'; - -import { createHealthIcon } from '../../../../helper'; - -type OverviewStatusProps = { - id: string; - namespace: string; - status: Status; - items: string[]; -}; -export const OverviewStatus = (props: OverviewStatusProps) => { - const length = props.items.length; - let items = props.items; - if (items.length > 6) { - items = items.slice(0, 5); - items.push(`and ${length - items.length} more...`); - } - const tooltipContent = ( - <> - {props.status.name} - {items.map((app, idx) => { - return ( -
    - - {createHealthIcon(props.status)} - {' '} - {app} -
    - ); - })} - - ); - return ( - -
    - {createHealthIcon(props.status)} - {` ${length}`} -
    -
    - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/TLSInfo.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/TLSInfo.tsx deleted file mode 100644 index 76fba881f2..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/TLSInfo.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import * as React from 'react'; - -import { Chip, Grid, Tooltip } from '@material-ui/core'; -import InfoOutlined from '@material-ui/icons/InfoOutlined'; -import LockRounded from '@material-ui/icons/LockRounded'; - -import { CertsInfo } from '@janus-idp/backstage-plugin-kiali-common'; - -type Props = { - certificatesInformationIndicators?: boolean; - version?: string; - certsInfo?: CertsInfo[]; -}; - -const generateRow = (item: CertsInfo) => { - return ( -
    -
    - From {item.issuer} -
    -
    -
    Issuer:
    -
    {item.secretName}
    -
    -
    -
    Valid From:
    -
    {item.notAfter}
    -
    -
    -
    Valid To:
    -
    {item.notBefore}
    -
    -
    - ); -}; - -const showCerts = (certs: CertsInfo[] | undefined) => { - if (certs) { - const rows = certs.map(item => generateRow(item)); - return
    {rows}
    ; - } - - return 'No cert info'; -}; - -const LockIcon = (props: Props) => { - return props.certificatesInformationIndicators === true ? ( - -
    - -
    -
    - ) : ( - - ); -}; - -const chipContent = (props: Props) => { - return ( - - - {props.version} - - - - - - - The meshConfig.meshMTLS.minProtocolVersion field specifies the - minimum TLS version for the TLS connections among Istio workloads. - N/A if it was not set. - - } - > - - - - - ); -}; - -export const TLSInfo = (props: Props) => { - return ( -
    -
    -
    - Min TLS version -
    - -
    -
    - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/index.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/index.tsx deleted file mode 100644 index f2be882458..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardBody/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './OverviewCardBody'; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/ControlPlaneVersionBadge.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/ControlPlaneVersionBadge.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/IstioComponentStatus.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/IstioComponentStatus.tsx deleted file mode 100644 index 3cf8c625d8..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/IstioComponentStatus.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import * as React from 'react'; - -import { Grid } from '@material-ui/core'; - -import { - ComponentStatus, - IStatus, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { - ComponentIcon, - createIcon, - ErrorAddonComponent, - ErrorCoreComponent, - NotReadyComponent, - SuccessComponent, -} from '../../../../Icons'; - -type Props = { - componentStatus: ComponentStatus; -}; - -// Mapping Valid-Core to Icon representation. -const validToIcon: { [valid: string]: ComponentIcon } = { - 'false-false': ErrorAddonComponent, - 'false-true': ErrorCoreComponent, - 'true-false': SuccessComponent, - 'true-true': SuccessComponent, -}; - -const statusMsg = { - [IStatus.Healthy]: 'Healthy', - [IStatus.NotFound]: 'Not found', - [IStatus.NotReady]: 'Not ready', - [IStatus.Unhealthy]: 'Not healthy', - [IStatus.Unreachable]: 'Unreachable', -}; - -export const IstioComponentStatus = (props: Props) => { - const renderIcon = (status: IStatus, isCore: boolean) => { - let compIcon = validToIcon[`${status === IStatus.Healthy}-${isCore}`]; - if (status === IStatus.NotReady) { - compIcon = NotReadyComponent; - } - return createIcon(compIcon, { fontSize: 'small' }); - }; - - const renderCells = () => { - const comp = props.componentStatus; - - return [ -
  • - - - {renderIcon( - props.componentStatus.status, - props.componentStatus.is_core, - )} - - {comp.name} - {statusMsg[comp.status]} - -
  • , - ]; - }; - - return renderCells(); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/IstioStatus.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/IstioStatus.tsx deleted file mode 100644 index 79ff6c9604..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/IstioStatus.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import * as React from 'react'; - -import { Tooltip } from '@material-ui/core'; -import WarningRounded from '@material-ui/icons/WarningRounded'; - -import { - ComponentStatus, - IStatus, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { Colors } from '../../../../Icons'; -import { IstioStatusList } from './IstioStatusList'; - -type Props = { - istioStatus: ComponentStatus[]; -}; - -const ValidToColor = { - 'true-true-true': { color: Colors.error }, - 'true-true-false': { color: Colors.error }, - 'true-false-true': { color: Colors.error }, - 'true-false-false': { color: Colors.error }, - 'false-true-true': { htmlColor: Colors.warning }, - 'false-true-false': { htmlColor: Colors.warning }, - 'false-false-true': { color: Colors.info }, - 'false-false-false': { htmlColor: Colors.ok }, -}; - -export const IstioStatus = (props: Props) => { - const tooltipContent = () => { - return ; - }; - - const tooltipColor = (): { [key: string]: string } => { - let coreUnhealthy: boolean = false; - let addonUnhealthy: boolean = false; - let notReady: boolean = false; - - Object.keys(props.istioStatus || {}).forEach((compKey: string) => { - const { status, is_core } = props.istioStatus[compKey as any]; - const isNotReady: boolean = status === IStatus.NotReady; - const isUnhealthy: boolean = status !== IStatus.Healthy && !isNotReady; - - if (is_core) { - coreUnhealthy = coreUnhealthy || isUnhealthy; - } else { - addonUnhealthy = addonUnhealthy || isUnhealthy; - } - - notReady = notReady || isNotReady; - }); - - return ValidToColor[`${coreUnhealthy}-${addonUnhealthy}-${notReady}`]; - }; - - const healthyComponents = () => { - return props.istioStatus.reduce( - (healthy: boolean, compStatus: ComponentStatus) => { - return healthy && compStatus.status === IStatus.Healthy; - }, - true, - ); - }; - - return !healthyComponents() ? ( - -
    - -
    -
    - ) : null; -}; - -export default IstioStatus; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/index.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/index.tsx deleted file mode 100644 index 8e6e7027b9..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/IstioStatus/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './IstioStatus'; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/OverviewCardHeader.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/OverviewCardHeader.tsx deleted file mode 100644 index c9862669c6..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/OverviewCardHeader.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React from 'react'; - -import { CardHeader, Chip, Grid } from '@material-ui/core'; - -import { - CanaryUpgradeStatus, - ComponentStatus, - KialiConfigT, - NamespaceInfo, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { IstioStatus } from './IstioStatus'; - -type OverviewCardHeaderProps = { - ns: NamespaceInfo; - canaryUpgrade?: boolean; - canaryStatus?: CanaryUpgradeStatus; - istioStatus?: ComponentStatus[]; - istioAPIEnabled?: boolean; - kialiConfig: KialiConfigT; -}; - -const getTitleHeader = ( - ns: NamespaceInfo, - istioNamespace: boolean, - istioStatus?: ComponentStatus[], - istioAPIEnabled?: boolean, - hasCanaryUpgradeConfigured?: boolean, - canaryStatus?: CanaryUpgradeStatus, -) => { - return ( - - - - {ns.name} - - - {istioNamespace && istioStatus && ( - <> - - - - - - - - )} - {istioNamespace && - hasCanaryUpgradeConfigured && - canaryStatus?.migratedNamespaces.includes(ns.name) && ( - - - - )} - {istioNamespace && !istioAPIEnabled && ( - - - - )} - - ); -}; - -export const OverviewCardHeader = (props: OverviewCardHeaderProps) => { - return ( - - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/index.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/index.tsx deleted file mode 100644 index bfb4fed958..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewCardHeader/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './OverviewCardHeader'; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/Charts.css b/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/Charts.css deleted file mode 100644 index 6f9792c1b2..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/Charts.css +++ /dev/null @@ -1,3 +0,0 @@ -.pf-v5-c-chart svg { - overflow: visible !important; -} diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/ControlPlaneChart.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/ControlPlaneChart.tsx deleted file mode 100644 index 84fac8a5a5..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/ControlPlaneChart.tsx +++ /dev/null @@ -1,211 +0,0 @@ -import React from 'react'; - -import { Card, CardContent, Grid, Tooltip } from '@material-ui/core'; - -import { - ComputedServerConfig, - Datapoint, - getName, - IstiodResourceThresholds, - Metric, - RichDataPoint, - toLocaleStringWithConditionalDate, - toVCLine, - VCLine, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { createIcon, InfoIcon } from '../../../../Icons'; -import { SparklineChart } from './SparklineChart'; - -import './Charts.css'; - -type ControlPlaneCharts = { - pilotLatency?: Metric[]; - istiodMemory?: Metric[]; - istiodCpu?: Metric[]; - duration: number; - istiodResourceThresholds?: IstiodResourceThresholds; - config: ComputedServerConfig; -}; - -const showMetrics = (metrics: Metric[] | undefined): boolean => { - // show metrics if metrics exists and some values at least are not zero - if ( - metrics && - metrics.length > 0 && - metrics[0].datapoints.length > 0 && - metrics[0].datapoints.some(dp => Number(dp[1]) !== 0) - ) { - return true; - } - - return false; -}; - -export const ControlPlaneChart = (props: ControlPlaneCharts) => { - const memorySeries: VCLine[] = []; - const cpuSeries: VCLine[] = []; - const memoryThresholds: VCLine[] = []; - const cpuThresholds: VCLine[] = []; - if (showMetrics(props.istiodMemory)) { - if (props.istiodMemory && props.istiodMemory?.length > 0) { - const data = toVCLine(props.istiodMemory[0].datapoints, 'Mb', '#38812F'); - - if (props.istiodResourceThresholds?.memory) { - const datapoint0: Datapoint = [ - props.istiodMemory[0].datapoints[0][0], - props.istiodMemory[0].datapoints[0][1], - ]; - datapoint0[1] = props.istiodResourceThresholds?.memory; - const datapointn: Datapoint = [ - props.istiodMemory[0].datapoints[ - props.istiodMemory[0].datapoints.length - 1 - ][0], - props.istiodMemory[0].datapoints[ - props.istiodMemory[0].datapoints.length - 1 - ][0], - ]; - datapointn[1] = props.istiodResourceThresholds?.memory; - const dataThre = toVCLine( - [datapoint0, datapointn], - 'Mb (Threshold)', - '#4CB140', - ); - memoryThresholds.push(dataThre); - } - - memorySeries.push(data); - } - } - - if (showMetrics(props.istiodCpu)) { - if (props.istiodCpu && props.istiodCpu?.length > 0) { - const data = toVCLine(props.istiodCpu[0].datapoints, 'cores', '#38812F'); - - if (props.istiodResourceThresholds?.cpu) { - const datapoint0: Datapoint = [ - props.istiodCpu[0].datapoints[0][0], - props.istiodCpu[0].datapoints[0][1], - ]; - datapoint0[1] = props.istiodResourceThresholds?.cpu; - const datapointn: Datapoint = [ - props.istiodCpu[0].datapoints[ - props.istiodCpu[0].datapoints.length - 1 - ][0], - props.istiodCpu[0].datapoints[ - props.istiodCpu[0].datapoints.length - 1 - ][0], - ]; - datapointn[1] = props.istiodResourceThresholds?.cpu; - const dataThre = toVCLine([datapoint0, datapointn], 'cores', '#4CB140'); - cpuThresholds.push(dataThre); - } - - cpuSeries.push(data); - } - } - return ( -
    -
    -
    - Control plane metrics -
    -
    -
    - - - - {showMetrics(props.istiodMemory) && ( - <> - - - - Memory - - - {getName(props.config, props.duration).toLowerCase()} - - {createIcon(InfoIcon, { fontSize: 'small' })} - - - - - - - `${toLocaleStringWithConditionalDate( - dp.x as Date, - )}\n${dp.y.toFixed(2)} ${dp.name}` - } - series={memorySeries} - labelName="mb" - thresholds={memoryThresholds} - /> - - - )} - {showMetrics(props.istiodCpu) && ( - <> - - - - CPU - - - {getName(props.config, props.duration).toLowerCase()} - - {createIcon(InfoIcon, { fontSize: 'small' })} - - - - - - - `${toLocaleStringWithConditionalDate( - dp.x as Date, - )}\n${dp.y.toFixed(2)} ${dp.name}` - } - series={cpuSeries} - labelName="cores" - thresholds={cpuThresholds} - /> - - - )} - - - -
    -
    - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/DataPlaneChart.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/DataPlaneChart.tsx deleted file mode 100644 index 97502806fb..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/DataPlaneChart.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import React from 'react'; - -import { - ComputedServerConfig, - DirectionType, - getName, - Metric, - RichDataPoint, - toLocaleStringWithConditionalDate, - toVCLine, - VCLine, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { SparklineChart } from './SparklineChart'; - -import './Charts.css'; - -type DataPlaneChartProps = { - metrics?: Metric[]; - errorMetrics?: Metric[]; - duration: number; - direction: DirectionType; - config: ComputedServerConfig; - width?: string; -}; - -const showMetrics = (metrics: Metric[] | undefined): boolean => { - // show metrics if metrics exists and some values at least are not zero - if ( - metrics && - metrics.length > 0 && - metrics[0].datapoints.some(dp => Number(dp[1]) !== 0) - ) { - return true; - } - - return false; -}; - -export const DataPlaneChart = (props: DataPlaneChartProps) => { - const series: VCLine[] = []; - - if (showMetrics(props.metrics)) { - if (props.metrics && props.metrics.length > 0) { - const data = toVCLine(props.metrics[0].datapoints, 'ops (Total)', '#06c'); - series.push(data); - } - - if (props.errorMetrics && props.errorMetrics.length > 0) { - const dataErrors = toVCLine( - props.errorMetrics[0].datapoints, - 'ops (4xx+5xx)', - '#c9190b', - ); - series.push(dataErrors); - } - } - return ( -
    - {series.length > 0 && ( - <> -
    - {`${props.direction} traffic, ${getName( - props.config, - props.duration, - ).toLowerCase()}`} -
    - - `${toLocaleStringWithConditionalDate( - dp.x as Date, - )}\n${dp.y.toFixed(2)} ${dp.name}` - } - series={series} - labelName="ops" - /> - - )} - {series.length === 0 && ( -
    - No {props.direction.toLowerCase()} traffic -
    - )} -
    - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/HookedChartTooltip.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/HookedChartTooltip.tsx deleted file mode 100644 index f5ef3944a1..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/HookedChartTooltip.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; - -import { ChartTooltip, ChartTooltipProps } from '@patternfly/react-charts'; - -import { VCDataPoint } from '@janus-idp/backstage-plugin-kiali-common'; - -export type HookedTooltipProps = ChartTooltipProps & { - activePoints?: (VCDataPoint & T)[]; - onOpen?: (items: VCDataPoint[]) => void; - onClose?: () => void; -}; - -export class HookedChartTooltip extends React.Component< - HookedTooltipProps -> { - componentDidMount() { - if (this.props.onOpen && this.props.activePoints) { - this.props.onOpen(this.props.activePoints); - } - } - - componentWillUnmount() { - if (this.props.onClose) { - this.props.onClose(); - } - } - - render() { - return ; - } -} diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/OverviewChart.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/OverviewChart.tsx deleted file mode 100644 index 109578a61a..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/OverviewChart.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react'; - -import { - ComputedServerConfig, - ControlPlaneMetricsMap, - DirectionType, - IstiodResourceThresholds, - Metric, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { ControlPlaneChart } from './ControlPlaneChart'; -import { DataPlaneChart } from './DataPlaneChart'; - -type OverviewChartProps = { - metrics?: Metric[]; - errorMetrics?: Metric[]; - controlPlaneMetrics?: ControlPlaneMetricsMap; - istiodResourceThresholds?: IstiodResourceThresholds; - duration: number; - direction: DirectionType; - config: ComputedServerConfig; - isIstioNamespace?: boolean; - istioAPIEnabled?: boolean; -}; - -export const OverviewChart = (props: OverviewChartProps) => { - return ( - <> - {(!props.isIstioNamespace || !props.istioAPIEnabled) && ( - - )} - {props.isIstioNamespace && props.istioAPIEnabled && ( - - )} - - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/index.ts b/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/index.ts deleted file mode 100644 index ec9fe9f373..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewChart/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './OverviewChart'; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewMetrics.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewMetrics.tsx deleted file mode 100644 index 5084ba0100..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/OverviewMetrics.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React from 'react'; - -import { Grid } from '@material-ui/core'; - -import { - CanaryUpgradeStatus, - ComponentStatus, - IstiodResourceThresholds, - KialiConfigT, - NamespaceInfo, - OutboundTrafficPolicy, - OverviewType, -} from '@janus-idp/backstage-plugin-kiali-common'; - -import { DirectionTypeOptions } from '../OverviewCard'; -import { CanaryUpgradeProgress } from './CanaryUpgradeProgress'; -import { OverviewChart } from './OverviewChart'; - -type OverviewMetricsProps = { - canaryStatus?: CanaryUpgradeStatus; - canaryUpgrade?: boolean; - direction: DirectionTypeOptions; - duration: number; - ns: NamespaceInfo; - outboundTrafficPolicy: OutboundTrafficPolicy; - isIstioNs?: boolean; - istioAPIEnabled?: boolean; - istiodResourceThresholds?: IstiodResourceThresholds; - istioStatus?: ComponentStatus[]; - kialiConfig: KialiConfigT; - type: OverviewType; -}; - -export const OverviewMetrics = (props: OverviewMetricsProps) => { - return ( - - {props.isIstioNs && props.istioAPIEnabled ? ( - - - {props.canaryUpgrade && props.canaryStatus && ( - - - - )} - - - - - - ) : ( - - - - )} - - ); -}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/index.tsx b/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/index.tsx deleted file mode 100644 index c2fd07c885..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export * from './OverviewMetrics'; diff --git a/plugins/kiali/src/components/Overview/OverviewToolbar.tsx b/plugins/kiali/src/components/Overview/OverviewToolbar.tsx deleted file mode 100644 index 1a526a7d09..0000000000 --- a/plugins/kiali/src/components/Overview/OverviewToolbar.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import React from 'react'; - -import { Select, SelectItem } from '@backstage/core-components'; - -import { Grid, IconButton, Tooltip } from '@material-ui/core'; -import Refresh from '@material-ui/icons/Refresh'; - -import { - durationsTuples, - OverviewType, -} from '@janus-idp/backstage-plugin-kiali-common'; - -declare const directionTypes: { - inbound: string; - outbound: string; -}; -export type DirectionType = keyof typeof directionTypes; - -type OverviewTypeOptions = 'app' | 'workload' | 'service'; -type DirectionTypeOptions = 'inbound' | 'outbound'; - -type OverviewToolbarProps = { - direction: DirectionType; - setDirection: (e: DirectionTypeOptions) => void; - duration: number; - setDuration: (e: number) => void; - overviewType: OverviewType; - setOverviewType: (e: OverviewTypeOptions) => void; - refresh: () => void; -}; - -const healthType = [ - { - label: 'Apps', - value: 'app', - }, - { - label: 'Workloads', - value: 'workload', - }, - { - label: 'Services', - value: 'service', - }, -]; - -const directionType = [ - { - label: 'Inbound', - value: 'inbound', - }, - { - label: 'Outbound', - value: 'outbound', - }, -]; - -const getDurationType = (): SelectItem[] => { - const items: SelectItem[] = []; - durationsTuples.forEach((value, _) => - items.push({ - label: `Last ${value[1]}`, - value: value[0], - }), - ); - return items; -}; - -export const OverviewToolbar = (props: OverviewToolbarProps) => { - return ( - - - props.setDirection(e as DirectionTypeOptions)} - label="Traffic" - items={directionType} - selected={props.direction} - /> - - - ({ + label: ns.name, + value: ns.name, + }))} + selected={kialiState.namespaces.activeNamespaces.map(ns => ns.name)} + multiple + onChange={values => { + kialiState.dispatch.namespaceDispatch( + NamespaceActions.setActiveNamespaces( + kialiState.namespaces.items!.filter(ns => + (values as string[]).includes(ns.name), + ), + ), + ); + }} + /> + + + + {homeCluster && ( + + Kiali home cluster: {homeCluster?.name}} + > + } + label={homeCluster?.name} + /> + + + )} + + + + + + + + + + View Debug Info + + About + + + + {kialiState.authentication.session && ( +
    + + User : + {kialiState.authentication.session.username} + +
    + )} +
    +
    +
    + + + + ); +}; diff --git a/plugins/kiali/src/pages/Kiali/KialiHelper.tsx b/plugins/kiali/src/pages/Kiali/KialiHelper.tsx new file mode 100644 index 0000000000..2818ea52b0 --- /dev/null +++ b/plugins/kiali/src/pages/Kiali/KialiHelper.tsx @@ -0,0 +1,74 @@ +import React from 'react'; + +import { + CodeSnippet, + Content, + InfoCard, + Link, + Page, + WarningPanel, +} from '@backstage/core-components'; + +import HelpRounded from '@material-ui/icons/HelpRounded'; + +import { KialiChecker } from '../../store/KialiProvider'; + +export const KialiHelper = (props: { check: KialiChecker }) => { + const pretty = () => { + if (props.check.message) { + const helper = props.check.helper; + const attributes = + props.check.missingAttributes && + `Missing attributes: ${props.check.missingAttributes.join(',')}.`; + return ( + <> +
    +
    + + + + {attributes && ( + <> +
    {attributes} + + )} + {helper && ( + <> +
    + {helper} + + )} + + ); + } + return <>; + }; + + const printAuthentication = ( + <> + The authentication provided by Kiali is{' '} + {props.check.authData?.strategy}.
    + You need to install the kiali backend to be able to use this kiali. +
    Follow the steps in{' '} + + Kiali Plugin + + {pretty()} + + ); + + const getTitle = () => { + if (!props.check.verify) { + return 'Authentication failed.'; + } + + return 'Unexpected Check'; + }; + return ( + + + {printAuthentication} + + + ); +}; diff --git a/plugins/kiali/src/pages/Kiali/KialiPage.tsx b/plugins/kiali/src/pages/Kiali/KialiPage.tsx new file mode 100644 index 0000000000..bb5a93fc8a --- /dev/null +++ b/plugins/kiali/src/pages/Kiali/KialiPage.tsx @@ -0,0 +1,40 @@ +import React from 'react'; + +import { Content, Page } from '@backstage/core-components'; + +import { OverviewPage } from '../Overview/OverviewPage'; +import { KialiHeader } from './Header/Header'; +import { KialiNoPath } from './NoPath'; + +const noPath = 'noPath'; +const getPathPage = () => { + const pathname = window.location.pathname.split('/').pop(); + if (pathname && pathname === 'kiali') { + return 'overview'; + } else if (pathname) { + return pathname; + } + return noPath; +}; + +export const KialiPage = () => { + const [kialiTab, _] = React.useState(getPathPage()); + + const renderPath = () => { + switch (kialiTab) { + case 'overview': + return ; + default: + return ; + } + }; + + return ( + + + + {renderPath()} + + + ); +}; diff --git a/plugins/kiali/src/pages/Kiali/NoPath.tsx b/plugins/kiali/src/pages/Kiali/NoPath.tsx new file mode 100644 index 0000000000..0898bf88e2 --- /dev/null +++ b/plugins/kiali/src/pages/Kiali/NoPath.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { useLocation } from 'react-router-dom'; + +import { Content, Link, Page, WarningPanel } from '@backstage/core-components'; +import { useRouteRef } from '@backstage/core-plugin-api'; + +import { rootRouteRef } from '../../routes'; + +export const KialiNoPath = () => { + const location = useLocation().pathname; + const link = useRouteRef(rootRouteRef); + return ( + + + + Path {location} not exist in Kiali Plugin.{' '} + Go to Kiali Plugin + + + + ); +}; diff --git a/plugins/kiali/src/pages/Kiali/index.ts b/plugins/kiali/src/pages/Kiali/index.ts new file mode 100644 index 0000000000..4f19dd7d5d --- /dev/null +++ b/plugins/kiali/src/pages/Kiali/index.ts @@ -0,0 +1,2 @@ +export * from './KialiPage'; +export * from './NoPath'; diff --git a/plugins/kiali/src/pages/Overview/NamespaceInfo.ts b/plugins/kiali/src/pages/Overview/NamespaceInfo.ts new file mode 100644 index 0000000000..98d83950ad --- /dev/null +++ b/plugins/kiali/src/pages/Overview/NamespaceInfo.ts @@ -0,0 +1,28 @@ +import { IstioConfigList } from '../../types/IstioConfigList'; +import { ValidationStatus } from '../../types/IstioObjects'; +import { ControlPlaneMetricsMap, Metric } from '../../types/Metrics'; +import { TLSStatus } from '../../types/TLSStatus'; + +export type NamespaceInfo = { + name: string; + cluster?: string; + outboundPolicyMode?: string; + status?: NamespaceStatus; + tlsStatus?: TLSStatus; + istioConfig?: IstioConfigList; + validations?: ValidationStatus; + metrics?: Metric[]; + errorMetrics?: Metric[]; + labels?: { [key: string]: string }; + annotations?: { [key: string]: string }; + controlPlaneMetrics?: ControlPlaneMetricsMap; + isAmbient?: boolean; +}; + +export type NamespaceStatus = { + inNotReady: string[]; + inError: string[]; + inWarning: string[]; + inSuccess: string[]; + notAvailable: string[]; +}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/CanaryUpgradeProgress.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/CanaryUpgradeProgress.tsx similarity index 68% rename from plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/CanaryUpgradeProgress.tsx rename to plugins/kiali/src/pages/Overview/OverviewCard/CanaryUpgradeProgress.tsx index 01cb27924d..c0a58c2aa7 100644 --- a/plugins/kiali/src/components/Overview/OverviewCard/OverviewMetrics/CanaryUpgradeProgress.tsx +++ b/plugins/kiali/src/pages/Overview/OverviewCard/CanaryUpgradeProgress.tsx @@ -1,18 +1,24 @@ -import React from 'react'; +import * as React from 'react'; import { Tooltip } from '@material-ui/core'; -import InfoRounded from '@material-ui/icons/InfoRounded'; import { ChartDonutUtilization, ChartThemeColor, } from '@patternfly/react-charts'; -import { CanaryUpgradeStatus } from '@janus-idp/backstage-plugin-kiali-common'; +import { KialiIcon } from '../../../config/KialiIcon'; +import { kialiStyle } from '../../../styles/StyleUtils'; +import { CanaryUpgradeStatus } from '../../../types/IstioObjects'; -type CanaryUpgradeProgressProps = { +type Props = { canaryUpgradeStatus: CanaryUpgradeStatus; }; -export const CanaryUpgradeProgress = (props: CanaryUpgradeProgressProps) => { + +export const infoStyle = kialiStyle({ + margin: '0px 0px -1px 4px', +}); + +export const CanaryUpgradeProgress = (props: Props) => { const total = props.canaryUpgradeStatus.migratedNamespaces.length + props.canaryUpgradeStatus.pendingNamespaces.length; @@ -20,20 +26,23 @@ export const CanaryUpgradeProgress = (props: CanaryUpgradeProgressProps) => { total > 0 ? (props.canaryUpgradeStatus.migratedNamespaces.length * 100) / total : 0; - return ( -
    - <> - <> +
    +
    +
    Canary upgrade status - + + + - +
    { themeColor={ChartThemeColor.green} />
    - <> +

    {`${props.canaryUpgradeStatus.migratedNamespaces.length} of ${total} namespaces migrated`}

    - - +
    +
    ); }; diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/ControlPlaneBadge.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/ControlPlaneBadge.tsx new file mode 100644 index 0000000000..183b5e78e1 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/ControlPlaneBadge.tsx @@ -0,0 +1,44 @@ +import * as React from 'react'; + +import { Chip, makeStyles } from '@material-ui/core'; + +import { AmbientBadge } from '../../../components/Ambient/AmbientBadge'; +import { IstioStatusInline } from '../../../components/IstioStatus/IstioStatusInline'; +import { serverConfig } from '../../../config'; +import { ComponentStatus } from '../../../types/IstioStatus'; +import { isRemoteCluster } from './OverviewCardControlPlaneNamespace'; +import { RemoteClusterBadge } from './RemoteClusterBadge'; + +type Props = { + cluster?: string; + annotations?: { [key: string]: string }; + status: ComponentStatus[]; +}; + +const useStyles = makeStyles(() => ({ + controlPlane: { + backgroundColor: '#f3faf2', + color: '#1e4f18', + marginLeft: '5px', + }, +})); + +export const ControlPlaneBadge = (props: Props): React.JSX.Element => { + const classes = useStyles(); + return ( + <> + + {isRemoteCluster(props.annotations) && } + {serverConfig.ambientEnabled && ( + + )}{' '} + + + ); +}; diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/ControlPlaneNamespaceStatus.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/ControlPlaneNamespaceStatus.tsx new file mode 100644 index 0000000000..adc40a3b7e --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/ControlPlaneNamespaceStatus.tsx @@ -0,0 +1,109 @@ +import * as React from 'react'; + +import { Chip, Tooltip } from '@material-ui/core'; + +import { KialiIcon } from '../../../config/KialiIcon'; +import { OutboundTrafficPolicy } from '../../../types/IstioObjects'; +import { NamespaceInfo } from '../NamespaceInfo'; +import { infoStyle } from './OverviewCardControlPlaneNamespace'; + +type Props = { + namespace: NamespaceInfo; + outboundTrafficPolicy?: OutboundTrafficPolicy; +}; + +export class ControlPlaneNamespaceStatus extends React.Component { + render() { + let maxProxyPushTime: number | undefined = undefined; + if ( + this.props.namespace.controlPlaneMetrics && + this.props.namespace.controlPlaneMetrics.istiod_proxy_time + ) { + maxProxyPushTime = + this.props.namespace.controlPlaneMetrics?.istiod_proxy_time[0].datapoints.reduce( + (a, b) => (a[1] < b[1] ? a : b), + )[1] * 1000; + } + let showProxyPushTime = false; + if (maxProxyPushTime && !isNaN(maxProxyPushTime)) { + showProxyPushTime = true; + } + + return ( +
    + {this.props.outboundTrafficPolicy && ( +
    +
    + Outbound policy +
    + + This value represents the + meshConfig.outboundTrafficPolicy.mode, that configures the + sidecar handling of external services, that is, those services + that are not defined in Istio’s internal service registry. If + this option is set to ALLOW_ANY, the Istio proxy lets calls to + unknown services pass through. If the option is set to + REGISTRY_ONLY, then the Istio proxy blocks any host without an + HTTP service or service entry defined within the mesh +
    + } + > + + {this.props.outboundTrafficPolicy.mode} + + + } + /> + +
    + )} + {showProxyPushTime && ( +
    +
    + Proxy push time +
    + + This value represents the delay in seconds between config + change and a proxy receiving all required configuration. +
    + } + > + + {maxProxyPushTime?.toFixed(2)} ms + + + } + /> + +
    + )} + + ); + } +} diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/ControlPlaneVersionBadge.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/ControlPlaneVersionBadge.tsx new file mode 100644 index 0000000000..5069782ab5 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/ControlPlaneVersionBadge.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; + +import { Chip } from '@material-ui/core'; + +type Props = { + version: string; + isCanary: boolean; +}; + +export class ControlPlaneVersionBadge extends React.Component { + render() { + return ( + + ); + } +} diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/NamespaceHeader.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/NamespaceHeader.tsx new file mode 100644 index 0000000000..68687552a9 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/NamespaceHeader.tsx @@ -0,0 +1,83 @@ +import React from 'react'; + +import { CardHeader, Chip } from '@material-ui/core'; + +import { serverConfig } from '../../../config'; +import { CanaryUpgradeStatus } from '../../../types/IstioObjects'; +import { ComponentStatus } from '../../../types/IstioStatus'; +import { NamespaceInfo } from '../NamespaceInfo'; +import { ControlPlaneBadge } from './ControlPlaneBadge'; +import { ControlPlaneVersionBadge } from './ControlPlaneVersionBadge'; + +type NamespaceHeaderProps = { + namespace: NamespaceInfo; + istioAPIEnabled?: boolean; + canaryUpgradeStatus?: CanaryUpgradeStatus; + istioStatus: ComponentStatus[]; +}; + +export const NamespaceHeader = (props: NamespaceHeaderProps) => { + const isIstioSystem = serverConfig.istioNamespace === props.namespace.name; + + const hasCanaryUpgradeConfigured = (): boolean => { + return props.canaryUpgradeStatus + ? props.canaryUpgradeStatus.pendingNamespaces.length > 0 || + props.canaryUpgradeStatus.migratedNamespaces.length > 0 + : false; + }; + return ( + + {props.namespace.name} + {isIstioSystem && ( + + )} + {!props.istioAPIEnabled && ( + + )} + + } + subheader={ + <> + {props.namespace.name !== serverConfig.istioNamespace && + hasCanaryUpgradeConfigured() && + props.canaryUpgradeStatus?.migratedNamespaces.includes( + props.namespace.name, + ) && ( + + )} + {props.namespace.name !== serverConfig.istioNamespace && + hasCanaryUpgradeConfigured() && + props.canaryUpgradeStatus?.pendingNamespaces.includes( + props.namespace.name, + ) && ( + + )} + {props.namespace.name === serverConfig.istioNamespace && + !props.istioAPIEnabled && ( + + )} + + } + /> + ); +}; diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/NamespaceLabels.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/NamespaceLabels.tsx new file mode 100644 index 0000000000..2375bd6c7c --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/NamespaceLabels.tsx @@ -0,0 +1,32 @@ +import React from 'react'; + +import { Tooltip } from '@material-ui/core'; + +import { PFColors } from '../../../components/Pf/PfColors'; + +type NamespaceLabelsprops = { + labels?: { [key: string]: string }; +}; +export const NamespaceLabels = (props: NamespaceLabelsprops) => { + const labelsLength = props.labels + ? `${Object.entries(props.labels).length}` + : 'No'; + const tooltipTitle = ( +
      + {Object.entries(props.labels || []).map(([key, value]) => ( +
    • + {key}={value} +
    • + ))} +
    + ); + return props.labels ? ( + +
    + {labelsLength} label{labelsLength !== '1' ? 's' : ''} +
    +
    + ) : ( +
    No labels
    + ); +}; diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/NamespaceStatus.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/NamespaceStatus.tsx new file mode 100644 index 0000000000..94a1736444 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/NamespaceStatus.tsx @@ -0,0 +1,124 @@ +import React from 'react'; + +import { Paths } from '../../../config'; +import { + DurationInSeconds, + IntervalInMilliseconds, +} from '../../../types/Common'; +import { DEGRADED, FAILURE, HEALTHY, NOT_READY } from '../../../types/Health'; +import { NamespaceInfo } from '../NamespaceInfo'; +import { switchType } from '../OverviewHelper'; +import { OverviewStatus } from '../OverviewStatus'; +import { OverviewType } from '../OverviewToolbar'; + +type NamespaceStatusProps = { + namespace: NamespaceInfo; + type: OverviewType; + duration: DurationInSeconds; + refreshInterval: IntervalInMilliseconds; +}; + +export const NamespaceStatus = (props: NamespaceStatusProps) => { + const ns = props.namespace; + const targetPage = switchType( + props.type, + Paths.APPLICATIONS, + Paths.SERVICES, + Paths.WORKLOADS, + ); + const name = ns.name; + let nbItems = 0; + if (ns.status) { + nbItems = + ns.status.inError.length + + ns.status.inWarning.length + + ns.status.inSuccess.length + + ns.status.notAvailable.length + + ns.status.inNotReady.length; + } + let text: string; + if (nbItems === 1) { + text = switchType(props.type, '1 application', '1 service', '1 workload'); + } else { + text = `${nbItems}${switchType( + props.type, + ' applications', + ' services', + ' workloads', + )}`; + } + const mainLink = ( +
    + {text} +
    + ); + if (nbItems === ns.status?.notAvailable.length) { + return ( +
    + + {mainLink} +
    N/A
    +
    +
    + ); + } + return ( +
    + + {mainLink} +
    + {ns.status && ns.status.inNotReady.length > 0 && ( + + )} + {ns.status && ns.status.inError.length > 0 && ( + + )} + {ns.status && ns.status.inWarning.length > 0 && ( + + )} + {ns.status && ns.status.inSuccess.length > 0 && ( + + )} +
    +
    +
    + ); +}; diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCard.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCard.tsx new file mode 100644 index 0000000000..bf632d0664 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCard.tsx @@ -0,0 +1,165 @@ +import React from 'react'; + +import { Card, CardContent, Grid } from '@material-ui/core'; + +import * as FilterHelper from '../../../components/FilterList/FitlerHelper'; +import { NamespaceMTLSStatus } from '../../../components/MTls/NamespaceMTLSStatus'; +import { TLSInfo } from '../../../components/Overview/TLSInfo'; +import { PFBadge, PFBadges } from '../../../components/Pf/PfBadges'; +import { ValidationSummary } from '../../../components/Validations/ValidationSummary'; +import { isMultiCluster, serverConfig } from '../../../config'; +import { CertsInfo } from '../../../types/CertsInfo'; +import { + DurationInSeconds, + IntervalInMilliseconds, +} from '../../../types/Common'; +import { + CanaryUpgradeStatus, + OutboundTrafficPolicy, + ValidationStatus, +} from '../../../types/IstioObjects'; +import { + ComponentStatus, + IstiodResourceThresholds, +} from '../../../types/IstioStatus'; +import { NamespaceInfo } from '../NamespaceInfo'; +import { DirectionType, OverviewType } from '../OverviewToolbar'; +import { CanaryUpgradeProgress } from './CanaryUpgradeProgress'; +import { ControlPlaneNamespaceStatus } from './ControlPlaneNamespaceStatus'; +import { NamespaceHeader } from './NamespaceHeader'; +import { NamespaceLabels } from './NamespaceLabels'; +import { NamespaceStatus } from './NamespaceStatus'; +import { OverviewCardSparklineCharts } from './OverviewCardSparklineCharts'; + +type OverviewCardProps = { + namespace: NamespaceInfo; + canaryUpgradeStatus?: CanaryUpgradeStatus; + duration: DurationInSeconds; + refreshInterval: IntervalInMilliseconds; + istioAPIEnabled?: boolean; + type: OverviewType; + direction: DirectionType; + certsInfo: CertsInfo[]; + minTLS: string; + outboundTrafficPolicy: OutboundTrafficPolicy; + istiodResourceThresholds?: IstiodResourceThresholds; + istioStatus: ComponentStatus[]; +}; + +export const OverviewCard = (props: OverviewCardProps) => { + const isIstioSystem = serverConfig.istioNamespace === props.namespace.name; + const hasCanaryUpgradeConfigured = (): boolean => { + return props.canaryUpgradeStatus + ? props.canaryUpgradeStatus.pendingNamespaces.length > 0 || + props.canaryUpgradeStatus.migratedNamespaces.length > 0 + : false; + }; + + const renderCharts = (): React.JSX.Element => { + const chart = ( + + ); + const canaryConfigured = hasCanaryUpgradeConfigured(); + return isIstioSystem ? ( + + {canaryConfigured && ( + + + + )} + + {chart} + + + ) : ( + chart + ); + }; + + const renderIstioConfigStatus = (ns: NamespaceInfo): React.JSX.Element => { + let validations: ValidationStatus = { + objectCount: 0, + errors: 0, + warnings: 0, + }; + if (!!ns.validations) { + validations = ns.validations; + } + + return ( + + ); + }; + + return ( + + + + {isMultiCluster && props.namespace.cluster && ( + <> + + {props.namespace.cluster} + + )} + + + +
    +
    + Istio config +
    + {props.namespace.tlsStatus && ( + + + + )} + {props.istioAPIEnabled + ? renderIstioConfigStatus(props.namespace) + : 'N/A'} +
    + + {isIstioSystem && ( + <> + + + + )} +
    + + {renderCharts()} + +
    +
    +
    + ); +}; diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCardControlPlaneNamespace.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCardControlPlaneNamespace.tsx new file mode 100644 index 0000000000..46a6cc6bc8 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCardControlPlaneNamespace.tsx @@ -0,0 +1,263 @@ +import * as React from 'react'; + +import { Card, CardContent, Grid, Tooltip } from '@material-ui/core'; + +import { SparklineChart } from '../../../components/Charts/SparklineChart'; +import { PFColors } from '../../../components/Pf/PfColors'; +import { KialiIcon } from '../../../config/KialiIcon'; +import { kialiStyle } from '../../../styles/StyleUtils'; +import { DurationInSeconds } from '../../../types/Common'; +import { IstiodResourceThresholds } from '../../../types/IstioStatus'; +import { Datapoint, Metric } from '../../../types/Metrics'; +import { RichDataPoint, VCLine } from '../../../types/VictoryChartInfo'; +import { toLocaleStringWithConditionalDate } from '../../../utils/Date'; +import { getName } from '../../../utils/RateIntervals'; +import { toVCLine } from '../../../utils/VictoryChartsUtils'; + +export const infoStyle = kialiStyle({ + margin: '0px 0px -1px 4px', +}); + +const controlPlaneAnnotation = 'topology.istio.io/controlPlaneClusters'; + +type ControlPlaneProps = { + pilotLatency?: Metric[]; + istiodContainerMemory?: Metric[]; + istiodContainerCpu?: Metric[]; + istiodProcessMemory?: Metric[]; + istiodProcessCpu?: Metric[]; + duration: DurationInSeconds; + istiodResourceThresholds?: IstiodResourceThresholds; +}; + +export function isRemoteCluster(annotations?: { + [key: string]: string; +}): boolean { + if (annotations && annotations[controlPlaneAnnotation]) { + return true; + } + return false; +} + +function showMetrics(metrics: Metric[] | undefined): boolean { + // show metrics if metrics exists and some values at least are not zero + if ( + metrics && + metrics.length > 0 && + metrics[0].datapoints.length > 0 && + metrics[0].datapoints.some(dp => Number(dp[1]) !== 0) + ) { + return true; + } + + return false; +} + +export class OverviewCardControlPlaneNamespace extends React.Component< + ControlPlaneProps, + {} +> { + render() { + const memorySeries: VCLine[] = []; + const cpuSeries: VCLine[] = []; + const memoryThresholds: VCLine[] = []; + const cpuThresholds: VCLine[] = []; + + // The CPU metric can be respresented by a container or a process metric. We need to check which one to use + let cpuMetricSource = 'container'; + let cpu = this.props.istiodContainerCpu; + if (!showMetrics(this.props.istiodContainerCpu)) { + cpu = this.props.istiodProcessCpu; + cpuMetricSource = 'process'; + } + + // The memory metric can be respresented by a container or a process metric. We need to check which one to use + let memoryMetricSource = 'process'; + let memory = this.props.istiodContainerMemory; + if (!showMetrics(this.props.istiodContainerMemory)) { + memory = this.props.istiodProcessMemory; + memoryMetricSource = 'container'; + } + + if (showMetrics(memory)) { + if (memory && memory?.length > 0) { + const data = toVCLine(memory[0].datapoints, 'Mb', PFColors.Green400); + + if (this.props.istiodResourceThresholds?.memory) { + const datapoint0: Datapoint = [ + memory[0].datapoints[0][0], + memory[0].datapoints[0][1], + ]; + datapoint0[1] = this.props.istiodResourceThresholds?.memory; + const datapointn: Datapoint = [ + memory[0].datapoints[memory[0].datapoints.length - 1][0], + memory[0].datapoints[memory[0].datapoints.length - 1][0], + ]; + datapointn[1] = this.props.istiodResourceThresholds?.memory; + const dataThre = toVCLine( + [datapoint0, datapointn], + 'Mb (Threshold)', + PFColors.Green300, + ); + memoryThresholds.push(dataThre); + } + + memorySeries.push(data); + } + } + + if (showMetrics(cpu)) { + if (cpu && cpu?.length > 0) { + const data = toVCLine(cpu[0].datapoints, 'cores', PFColors.Green400); + + if (this.props.istiodResourceThresholds?.cpu) { + const datapoint0: Datapoint = [ + cpu[0].datapoints[0][0], + cpu[0].datapoints[0][1], + ]; + datapoint0[1] = this.props.istiodResourceThresholds?.cpu; + const datapointn: Datapoint = [ + cpu[0].datapoints[cpu[0].datapoints.length - 1][0], + cpu[0].datapoints[cpu[0].datapoints.length - 1][0], + ]; + datapointn[1] = this.props.istiodResourceThresholds?.cpu; + const dataThre = toVCLine( + [datapoint0, datapointn], + 'cores', + PFColors.Green300, + ); + cpuThresholds.push(dataThre); + } + + cpuSeries.push(data); + } + } + return ( +
    +
    +
    + Control plane metrics +
    +
    +
    + + + {showMetrics(memory) && ( + + + + + Memory + + + {getName(this.props.duration).toLowerCase()} + + This values represents the memory of the istiod{' '} + {memoryMetricSource} +
    + } + > + + + + + + + + `${toLocaleStringWithConditionalDate( + dp.x as Date, + )}\n${dp.y.toFixed(2)} ${dp.name}` + } + series={memorySeries} + labelName="mb" + thresholds={memoryThresholds} + /> + + + )} + {showMetrics(cpu) && ( + + + + + CPU + + + {getName(this.props.duration).toLowerCase()} + + This values represents cpu of the istiod{' '} + {cpuMetricSource} +
    + } + > + + +
    +
    + + + + `${toLocaleStringWithConditionalDate( + dp.x as Date, + )}\n${dp.y.toFixed(2)} ${dp.name}` + } + series={cpuSeries} + labelName="cores" + thresholds={cpuThresholds} + /> + + + )} + + + + + ); + } +} diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCardDataPlaneNamespace.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCardDataPlaneNamespace.tsx new file mode 100644 index 0000000000..680384663a --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCardDataPlaneNamespace.tsx @@ -0,0 +1,105 @@ +import * as React from 'react'; + +import { SparklineChart } from '../../../components/Charts/SparklineChart'; +import { PFColors } from '../../../components/Pf/PfColors'; +import { DurationInSeconds } from '../../../types/Common'; +import { Metric } from '../../../types/Metrics'; +import { RichDataPoint, VCLine } from '../../../types/VictoryChartInfo'; +import { toLocaleStringWithConditionalDate } from '../../../utils/Date'; +import { getName } from '../../../utils/RateIntervals'; +import { toVCLine } from '../../../utils/VictoryChartsUtils'; +import { DirectionType } from '../OverviewToolbar'; + +type Props = { + metrics?: Metric[]; + errorMetrics?: Metric[]; + duration: DurationInSeconds; + direction: DirectionType; +}; + +function showMetrics(metrics: Metric[] | undefined): boolean { + // show metrics if metrics exists and some values at least are not zero + if ( + metrics && + metrics.length > 0 && + metrics[0].datapoints.some(dp => Number(dp[1]) !== 0) + ) { + return true; + } + + return false; +} + +export class OverviewCardDataPlaneNamespace extends React.Component { + render() { + const series: VCLine[] = []; + + if (showMetrics(this.props.metrics)) { + if (this.props.metrics && this.props.metrics.length > 0) { + const data = toVCLine( + this.props.metrics[0].datapoints, + 'ops (Total)', + PFColors.Info, + ); + series.push(data); + } + + if (this.props.errorMetrics && this.props.errorMetrics.length > 0) { + const dataErrors = toVCLine( + this.props.errorMetrics[0].datapoints, + 'ops (4xx+5xx)', + PFColors.Danger, + ); + series.push(dataErrors); + } + } + + return ( +
    +
    + <> +
    + {series.length > 0 && ( + <> +
    + {`${this.props.direction} traffic, ${getName( + this.props.duration, + ).toLowerCase()}`} +
    + + `${toLocaleStringWithConditionalDate( + dp.x as Date, + )}\n${dp.y.toFixed(2)} ${dp.name}` + } + series={series} + labelName="ops" + /> + + )} + {series.length === 0 && ( +
    + No {this.props.direction.toLowerCase()} traffic +
    + )} +
    + ); + } +} diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCardSparklineCharts.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCardSparklineCharts.tsx new file mode 100644 index 0000000000..df9d9c1fd3 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/OverviewCardSparklineCharts.tsx @@ -0,0 +1,54 @@ +import * as React from 'react'; + +import { serverConfig } from '../../../config'; +import { DurationInSeconds } from '../../../types/Common'; +import { IstiodResourceThresholds } from '../../../types/IstioStatus'; +import { ControlPlaneMetricsMap, Metric } from '../../../types/Metrics'; +import { DirectionType } from '../OverviewToolbar'; +import { + isRemoteCluster, + OverviewCardControlPlaneNamespace, +} from './OverviewCardControlPlaneNamespace'; +import { OverviewCardDataPlaneNamespace } from './OverviewCardDataPlaneNamespace'; + +type Props = { + name: string; + annotations?: { [key: string]: string }; + duration: DurationInSeconds; + direction: DirectionType; + metrics?: Metric[]; + istioAPIEnabled: boolean; + errorMetrics?: Metric[]; + controlPlaneMetrics?: ControlPlaneMetricsMap; + istiodResourceThresholds?: IstiodResourceThresholds; +}; + +export const OverviewCardSparklineCharts = (props: Props) => { + return ( + <> + {props.name !== serverConfig.istioNamespace && ( + + )} + {props.name === serverConfig.istioNamespace && + props.istioAPIEnabled && + !isRemoteCluster(props.annotations) && ( + + )} + + ); +}; diff --git a/plugins/kiali/src/pages/Overview/OverviewCard/RemoteClusterBadge.tsx b/plugins/kiali/src/pages/Overview/OverviewCard/RemoteClusterBadge.tsx new file mode 100644 index 0000000000..896d1ad123 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewCard/RemoteClusterBadge.tsx @@ -0,0 +1,15 @@ +import * as React from 'react'; + +import { Chip } from '@material-ui/core'; + +export const RemoteClusterBadge = (): React.JSX.Element => { + return ( + + ); +}; diff --git a/plugins/kiali/src/components/Overview/OverviewCard/index.ts b/plugins/kiali/src/pages/Overview/OverviewCard/index.ts similarity index 100% rename from plugins/kiali/src/components/Overview/OverviewCard/index.ts rename to plugins/kiali/src/pages/Overview/OverviewCard/index.ts diff --git a/plugins/kiali/src/pages/Overview/OverviewHelper.ts b/plugins/kiali/src/pages/Overview/OverviewHelper.ts new file mode 100644 index 0000000000..ece5c56d85 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewHelper.ts @@ -0,0 +1,15 @@ +import { OverviewType } from './OverviewToolbar'; + +export const switchType = ( + type: OverviewType, + caseApp: T, + caseService: U, + caseWorkload: V, +): T | U | V => { + if (type === 'app') { + return caseApp; + } else if (type === 'service') { + return caseService; + } + return caseWorkload; +}; diff --git a/plugins/kiali/src/pages/Overview/OverviewPage.tsx b/plugins/kiali/src/pages/Overview/OverviewPage.tsx new file mode 100644 index 0000000000..babde8e7f4 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewPage.tsx @@ -0,0 +1,473 @@ +import React from 'react'; +import { useAsyncFn, useDebounce } from 'react-use'; + +import { Content, Page } from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; +import { useEntity } from '@backstage/plugin-catalog-react'; + +import { CircularProgress, Grid } from '@material-ui/core'; +import _ from 'lodash'; + +import * as FilterHelper from '../../components/FilterList/FitlerHelper'; +import { isMultiCluster, serverConfig } from '../../config'; +import { getErrorString, kialiApiRef } from '../../services/Api'; +import { computePrometheusRateParams } from '../../services/Prometheus'; +import { KialiContext } from '../../store/Context'; +import { KialiAppState } from '../../store/Store'; +import { + DEGRADED, + FAILURE, + Health, + HEALTHY, + NamespaceAppHealth, + NamespaceServiceHealth, + NamespaceWorkloadHealth, + NOT_READY, +} from '../../types/Health'; +import { + CanaryUpgradeStatus, + OutboundTrafficPolicy, +} from '../../types/IstioObjects'; +import { IstiodResourceThresholds } from '../../types/IstioStatus'; +import { MessageType } from '../../types/MessageCenter'; +import { IstioMetricsOptions } from '../../types/MetricsOptions'; +import { SortField } from '../../types/SortFilters'; +import { nsWideMTLSStatus } from '../../types/TLSStatus'; +import { PromisesRegistry } from '../../utils/CancelablePromises'; +import { NamespaceInfo, NamespaceStatus } from './NamespaceInfo'; +import { OverviewCard } from './OverviewCard'; +import { switchType } from './OverviewHelper'; +import { + currentDirectionType, + currentOverviewType, + DirectionType, + OverviewToolbar, + OverviewType, +} from './OverviewToolbar'; +import * as Sorts from './Sorts'; + +export const OverviewPage = () => { + const kialiClient = useApi(kialiApiRef); + kialiClient.setEntity(useEntity().entity); + const kialiState = React.useContext(KialiContext) as KialiAppState; + const promises = new PromisesRegistry(); + const [namespaces, setNamespaces] = React.useState([]); + const [outboundTrafficPolicy, setOutboundTrafficPolicy] = + React.useState({}); + const [canaryUpgradeStatus, setCanaryUpgradeStatus] = React.useState< + CanaryUpgradeStatus | undefined + >(undefined); + const [istiodResourceThresholds, setIstiodResourceThresholds] = + React.useState({ memory: 0, cpu: 0 }); + const [duration, setDuration] = React.useState( + FilterHelper.currentDuration(), + ); + const [overviewType, setOverviewType] = React.useState( + currentOverviewType(), + ); + const [directionType, setDirectionType] = React.useState( + currentDirectionType(), + ); + + const sortedNamespaces = (nss: NamespaceInfo[]) => { + nss.sort((a, b) => { + if (a.name === serverConfig.istioNamespace) return -1; + if (b.name === serverConfig.istioNamespace) return 1; + return a.name.localeCompare(b.name); + }); + return nss; + }; + + const fetchHealthChunk = (chunk: NamespaceInfo[]): Promise => { + const apiFunc = switchType( + overviewType, + kialiClient.getNamespaceAppHealth, + kialiClient.getNamespaceServiceHealth, + kialiClient.getNamespaceWorkloadHealth, + ); + + return Promise.all( + chunk.map(nsInfo => { + const healthPromise: Promise< + NamespaceAppHealth | NamespaceWorkloadHealth | NamespaceServiceHealth + > = apiFunc(nsInfo.name, duration, nsInfo.cluster); + return healthPromise.then(rs => ({ health: rs, nsInfo: nsInfo })); + }), + ) + .then(results => { + results.forEach(result => { + const nsStatus: NamespaceStatus = { + inNotReady: [], + inError: [], + inWarning: [], + inSuccess: [], + notAvailable: [], + }; + Object.keys(result.health).forEach(item => { + const health: Health = result.health[item]; + const status = health.getGlobalStatus(); + if (status === FAILURE) { + nsStatus.inError.push(item); + } else if (status === DEGRADED) { + nsStatus.inWarning.push(item); + } else if (status === HEALTHY) { + nsStatus.inSuccess.push(item); + } else if (status === NOT_READY) { + nsStatus.inNotReady.push(item); + } else { + nsStatus.notAvailable.push(item); + } + }); + result.nsInfo.status = nsStatus; + }); + }) + .catch(err => + kialiState.alertUtils!.add( + `Could not fetch health: ${getErrorString(err)}`, + ), + ); + }; + + const fetchHealth = ( + nss: NamespaceInfo[], + isAscending: boolean, + sortField: SortField, + ): void => { + _.chunk(nss, 10).forEach(chunk => { + promises + .registerChained('healthchunks', undefined, () => + fetchHealthChunk(chunk), + ) + .then(() => { + let newNamespaces = nss.slice(); + if (sortField.id === 'health') { + newNamespaces = Sorts.sortFunc( + newNamespaces, + sortField, + isAscending, + ); + } + return nss; + }) + .catch(error => { + kialiState.alertUtils!.add( + `Could not fetch health: ${getErrorString(error)}`, + ); + if (error.isCanceled) { + return []; + } + return error; + }); + }); + }; + + const fetchTLSChunk = (chunk: NamespaceInfo[]): Promise => { + return Promise.all( + chunk.map(nsInfo => { + return kialiClient + .getNamespaceTls(nsInfo.name, nsInfo.cluster) + .then(rs => ({ status: rs, nsInfo: nsInfo })); + }), + ) + .then(results => { + results.forEach(result => { + result.nsInfo.tlsStatus = { + status: nsWideMTLSStatus( + result.status.status, + kialiState.meshTLSStatus.status, + ), + autoMTLSEnabled: result.status.autoMTLSEnabled, + minTLS: result.status.minTLS, + }; + }); + }) + .catch(err => + kialiState.alertUtils!.add( + `Could not fetch TLS status: ${getErrorString(err)}`, + ), + ); + }; + + const fetchTLS = ( + nss: NamespaceInfo[], + isAscending: boolean, + sortField: SortField, + ): void => { + _.chunk(nss, 10).forEach(chunk => { + promises + .registerChained('tlschunks', undefined, () => fetchTLSChunk(chunk)) + .then(() => { + let newNamespaces = nss.slice(); + if (sortField.id === 'mtls') { + newNamespaces = Sorts.sortFunc( + newNamespaces, + sortField, + isAscending, + ); + } + return newNamespaces; + }); + }); + }; + + const fetchOutboundTrafficPolicyMode = () => { + kialiClient + .getOutboundTrafficPolicyMode() + .then(response => { + setOutboundTrafficPolicy({ mode: response.mode }); + }) + .catch(error => { + kialiState.alertUtils!.addError( + 'Error fetching Mesh OutboundTrafficPolicy.Mode.', + error, + 'default', + MessageType.ERROR, + ); + }); + }; + + const fetchCanariesStatus = async () => + kialiClient + .getCanaryUpgradeStatus() + .then(response => { + setCanaryUpgradeStatus({ + currentVersion: response.currentVersion, + upgradeVersion: response.upgradeVersion, + migratedNamespaces: response.migratedNamespaces, + pendingNamespaces: response.pendingNamespaces, + }); + }) + .catch(error => { + kialiState.alertUtils!.addError( + 'Error fetching canary upgrade status.', + error, + 'default', + MessageType.ERROR, + ); + }); + + const fetchIstiodResourceThresholds = () => { + kialiClient + .getIstiodResourceThresholds() + .then(response => setIstiodResourceThresholds(response)) + .catch(error => { + kialiState.alertUtils!.addError( + 'Error fetching Istiod resource thresholds.', + error, + 'default', + MessageType.ERROR, + ); + }); + }; + + const fetchValidationResultForCluster = ( + nss: NamespaceInfo[], + cluster: string, + ) => { + return Promise.all([ + kialiClient.getConfigValidations(cluster), + kialiClient.getAllIstioConfigs([], [], false, '', '', cluster), + ]) + .then(results => { + nss.forEach(nsInfo => { + if ( + nsInfo.cluster && + nsInfo.cluster === cluster && + (results[0] as any)[nsInfo.cluster] + ) { + // @ts-expect-error + nsInfo.validations = results[0][nsInfo.cluster][nsInfo.name]; + } + if (nsInfo.cluster && nsInfo.cluster === cluster) { + nsInfo.istioConfig = results[1][nsInfo.name]; + } + }); + }) + .catch(err => + kialiState.alertUtils!.add( + `Could not fetch validations status: ${getErrorString(err)}`, + ), + ); + }; + + const fetchValidations = ( + nss: NamespaceInfo[], + isAscending: boolean, + sortField: SortField, + ) => { + const uniqueClusters = new Set(); + nss.forEach(namespace => { + if (namespace.cluster) { + uniqueClusters.add(namespace.cluster); + } + }); + + uniqueClusters.forEach(cluster => { + promises + .registerChained('validation', undefined, () => + fetchValidationResultForCluster(nss, cluster), + ) + .then(() => { + let newNamespaces = nss.slice(); + if (sortField.id === 'validations') { + newNamespaces = Sorts.sortFunc( + newNamespaces, + sortField, + isAscending, + ); + } + return newNamespaces; + }); + }); + }; + + const fetchMetricsChunk = (chunk: NamespaceInfo[]) => { + const rateParams = computePrometheusRateParams(duration, 10); + const options: IstioMetricsOptions = { + filters: ['request_count', 'request_error_count'], + duration: duration, + step: rateParams.step, + rateInterval: rateParams.rateInterval, + direction: directionType, + reporter: directionType === 'inbound' ? 'destination' : 'source', + }; + return Promise.all( + chunk.map(nsInfo => { + if (nsInfo.cluster && isMultiCluster) { + options.clusterName = nsInfo.cluster; + } + return kialiClient + .getNamespaceMetrics(nsInfo.name, options) + .then(rs => { + nsInfo.metrics = rs.request_count; + nsInfo.errorMetrics = rs.request_error_count; + if (nsInfo.name === serverConfig.istioNamespace) { + nsInfo.controlPlaneMetrics = { + istiod_proxy_time: rs.pilot_proxy_convergence_time, + istiod_container_cpu: rs.container_cpu_usage_seconds_total, + istiod_container_mem: rs.container_memory_working_set_bytes, + istiod_process_cpu: rs.process_cpu_seconds_total, + istiod_process_mem: rs.process_resident_memory_bytes, + }; + } + return nsInfo; + }); + }), + ).catch(err => + kialiState.alertUtils!.add( + `Could not fetch metrics: ${getErrorString(err)}`, + ), + ); + }; + + const fetchMetrics = (nss: NamespaceInfo[]) => { + // debounce async for back-pressure, ten by ten + _.chunk(nss, 10).forEach(chunk => { + promises + .registerChained('metricschunks', undefined, () => + fetchMetricsChunk(chunk), + ) + .then(() => nss.slice()); + }); + }; + + const filterActiveNamespaces = () => { + const activeNs = kialiState.namespaces.activeNamespaces.map(ns => ns.name); + return namespaces.filter(ns => activeNs.includes(ns.name)); + }; + + const load = async () => { + kialiClient.getNamespaces().then(namespacesResponse => { + const allNamespaces: NamespaceInfo[] = namespacesResponse.map(ns => { + const previous = namespaces.find(prev => prev.name === ns.name); + return { + name: ns.name, + cluster: ns.cluster, + isAmbient: ns.isAmbient, + status: previous ? previous.status : undefined, + tlsStatus: previous ? previous.tlsStatus : undefined, + metrics: previous ? previous.metrics : undefined, + errorMetrics: previous ? previous.errorMetrics : undefined, + validations: previous ? previous.validations : undefined, + labels: ns.labels, + annotations: ns.annotations, + controlPlaneMetrics: previous + ? previous.controlPlaneMetrics + : undefined, + }; + }); + + // Calculate information + const isAscending = FilterHelper.isCurrentSortAscending(); + const sortField = FilterHelper.currentSortField(Sorts.sortFields); + const sortNs = sortedNamespaces(allNamespaces); + fetchHealth(sortNs, isAscending, sortField); + fetchTLS(sortNs, isAscending, sortField); + fetchValidations(sortNs, isAscending, sortField); + fetchMetrics(sortNs); + + fetchOutboundTrafficPolicyMode(); + fetchCanariesStatus(); + fetchIstiodResourceThresholds(); + + setNamespaces(sortNs); + }); + }; + + const [{ loading }, refresh] = useAsyncFn( + async () => { + // Check if the config is loaded + await load(); + }, + [], + { loading: true }, + ); + useDebounce(refresh, 10); + + React.useEffect(() => { + load(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [duration, overviewType, directionType]); + + if (loading) { + return ; + } + + return ( + + + load()} + overviewType={overviewType} + setOverviewType={setOverviewType} + directionType={directionType} + setDirectionType={setDirectionType} + duration={duration} + setDuration={setDuration} + /> + + {filterActiveNamespaces().map((ns, i) => ( + + + + ))} + + + + ); +}; diff --git a/plugins/kiali/src/pages/Overview/OverviewStatus.tsx b/plugins/kiali/src/pages/Overview/OverviewStatus.tsx new file mode 100644 index 0000000000..30218ad873 --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewStatus.tsx @@ -0,0 +1,80 @@ +import * as React from 'react'; + +import { Tooltip } from '@material-ui/core'; + +import { healthFilter } from '../../components/Filters/CommonFilters'; +import { FilterSelected } from '../../components/Filters/StatefulFilters'; +import { healthIndicatorStyle } from '../../components/Health/HealthStyle'; +import { createIcon } from '../../components/Health/Helper'; +import { Paths } from '../../config'; +import { DurationInSeconds, IntervalInMilliseconds } from '../../types/Common'; +import { ActiveFilter, DEFAULT_LABEL_OPERATION } from '../../types/Filters'; +import { Status } from '../../types/Health'; + +type Props = { + id: string; + namespace: string; + status: Status; + items: string[]; + targetPage: Paths; + duration: DurationInSeconds; + refreshInterval: IntervalInMilliseconds; +}; + +export class OverviewStatus extends React.Component { + setFilters = () => { + const filters: ActiveFilter[] = [ + { + category: healthFilter.category, + value: this.props.status.name, + }, + ]; + FilterSelected.setSelected({ + filters: filters, + op: DEFAULT_LABEL_OPERATION, + }); + }; + + render() { + const length = this.props.items.length; + let items = this.props.items; + if (items.length > 6) { + items = items.slice(0, 5); + items.push(`and ${length - items.length} more...`); + } + const tooltipContent = ( +
    + {this.props.status.name} + {items.map((app, idx) => { + return ( +
    + + {createIcon(this.props.status, 'sm')} + {' '} + {app} +
    + ); + })} +
    + ); + + return ( + <> + +
    + {createIcon(this.props.status)} + {` ${length}`} +
    +
    + + ); + } +} diff --git a/plugins/kiali/src/pages/Overview/OverviewToolbar.tsx b/plugins/kiali/src/pages/Overview/OverviewToolbar.tsx new file mode 100644 index 0000000000..ec198fa06b --- /dev/null +++ b/plugins/kiali/src/pages/Overview/OverviewToolbar.tsx @@ -0,0 +1,143 @@ +import React from 'react'; + +import { Select, SelectItem } from '@backstage/core-components'; + +import { Grid, IconButton, Tooltip } from '@material-ui/core'; +import Refresh from '@material-ui/icons/Refresh'; + +import { HistoryManager, URLParam } from '../../app/History'; +import { serverConfig } from '../../config'; + +export enum OverviewDisplayMode { + COMPACT, + EXPAND, + LIST, +} + +const overviewTypes = { + app: 'Apps', + workload: 'Workloads', + service: 'Services', +}; + +const directionTypes = { + inbound: 'Inbound', + outbound: 'Outbound', +}; + +export type OverviewType = keyof typeof overviewTypes; +export type DirectionType = keyof typeof directionTypes; + +type OverviewToolbarProps = { + onRefresh: () => void; + overviewType: OverviewType; + setOverviewType: React.Dispatch>; + directionType: DirectionType; + setDirectionType: React.Dispatch>; + duration: number; + setDuration: React.Dispatch>; +}; + +const healthTypeItems = Object.keys(overviewTypes).map(k => ({ + label: (overviewTypes as any)[k], + value: k, +})); + +const directionTypeItems = Object.keys(directionTypes).map(k => ({ + label: (directionTypes as any)[k], + value: k, +})); + +export const currentOverviewType = (): OverviewType => { + const otype = HistoryManager.getParam(URLParam.OVERVIEW_TYPE); + return (otype as OverviewType) || 'app'; +}; + +export const currentDirectionType = (): DirectionType => { + const drtype = HistoryManager.getParam(URLParam.DIRECTION_TYPE); + return (drtype as DirectionType) || 'inbound'; +}; + +const getDurationType = (): SelectItem[] => { + const items: SelectItem[] = []; + Object.entries(serverConfig.durations).forEach(([key, value]) => + items.push({ + label: `Last ${value}`, + value: key, + }), + ); + return items; +}; + +export const OverviewToolbar = (props: OverviewToolbarProps) => { + const updateOverviewType = (otype: String) => { + const isOverviewType = (val: String): val is OverviewType => + val === 'app' || val === 'workload' || val === 'service'; + + if (isOverviewType(otype)) { + HistoryManager.setParam(URLParam.OVERVIEW_TYPE, otype); + props.setOverviewType(otype); + } else { + throw new Error('Overview type is not valid.'); + } + }; + + const updateDirectionType = (dtype: String) => { + const isDirectionType = (val: String): val is DirectionType => + val === 'inbound' || val === 'outbound'; + + if (isDirectionType(dtype)) { + HistoryManager.setParam(URLParam.DIRECTION_TYPE, dtype); + props.setDirectionType(dtype); + } else { + throw new Error('Direction type is not valid.'); + } + }; + + const updateDurationType = (duration: number) => { + HistoryManager.setParam(URLParam.DURATION, duration.toString()); + props.setDuration(duration); + }; + + return ( + + + updateDirectionType(e as String)} + label="Traffic" + items={directionTypeItems} + selected={props.directionType} + /> + + +