mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-08-25 20:09:00 +00:00
[TRA-3659] Fix rules (#271)
* Fix rules * Not reay, error on running * Empty dissector Rules() * almost working * Finally, fixed * undo changes on agent/pkg/utils/har.go * fix not showing service on rules detail * Update tap/api/api.go Co-authored-by: gadotroee <55343099+gadotroee@users.noreply.github.com> * Update agent/pkg/controllers/entries_controller.go Co-authored-by: gadotroee <55343099+gadotroee@users.noreply.github.com> * Update agent/pkg/controllers/entries_controller.go Co-authored-by: gadotroee <55343099+gadotroee@users.noreply.github.com> * unwrap Data * Fix bug off using more than one latency rule that always get the first. * fix json type, decoding base64 before unmarshal * Run `go mod tidy` on `cli/go.sum` * Fix the linting issues * Remove a `FIXME` comment * Remove a CSS rule * Adapt `ruleNumberText` CSS class to the design language of the UI * Fix an issue in the UI related to `rule.Latency` slipping out * Removed unecessary codes. Co-authored-by: gadotroee <55343099+gadotroee@users.noreply.github.com> Co-authored-by: M. Mert Yildiran <mehmet@up9.com>
This commit is contained in:
parent
b9d2e671c7
commit
6337b75f0e
@ -116,6 +116,15 @@ func startReadingChannel(outputItems <-chan *tapApi.OutputChannelItem, extension
|
|||||||
baseEntry := extension.Dissector.Summarize(mizuEntry)
|
baseEntry := extension.Dissector.Summarize(mizuEntry)
|
||||||
mizuEntry.EstimatedSizeBytes = getEstimatedEntrySizeBytes(mizuEntry)
|
mizuEntry.EstimatedSizeBytes = getEstimatedEntrySizeBytes(mizuEntry)
|
||||||
database.CreateEntry(mizuEntry)
|
database.CreateEntry(mizuEntry)
|
||||||
|
if extension.Protocol.Name == "http" {
|
||||||
|
var pair tapApi.RequestResponsePair
|
||||||
|
json.Unmarshal([]byte(mizuEntry.Entry), &pair)
|
||||||
|
harEntry, _ := utils.NewEntry(&pair)
|
||||||
|
rules, _ := models.RunValidationRulesState(*harEntry, mizuEntry.Service)
|
||||||
|
baseEntry.Rules = rules
|
||||||
|
baseEntry.Latency = mizuEntry.ElapsedTime
|
||||||
|
}
|
||||||
|
|
||||||
baseEntryBytes, _ := models.CreateBaseEntryWebSocketMessage(baseEntry)
|
baseEntryBytes, _ := models.CreateBaseEntryWebSocketMessage(baseEntry)
|
||||||
BroadcastToBrowserClients(baseEntryBytes)
|
BroadcastToBrowserClients(baseEntryBytes)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/google/martian/har"
|
|
||||||
"mizuserver/pkg/database"
|
"mizuserver/pkg/database"
|
||||||
"mizuserver/pkg/models"
|
"mizuserver/pkg/models"
|
||||||
"mizuserver/pkg/providers"
|
"mizuserver/pkg/providers"
|
||||||
@ -13,6 +12,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/martian/har"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/romana/rlog"
|
"github.com/romana/rlog"
|
||||||
|
|
||||||
@ -140,11 +141,23 @@ func GetEntry(c *gin.Context) {
|
|||||||
|
|
||||||
extension := extensionsMap[entryData.ProtocolName]
|
extension := extensionsMap[entryData.ProtocolName]
|
||||||
protocol, representation, bodySize, _ := extension.Dissector.Represent(&entryData)
|
protocol, representation, bodySize, _ := extension.Dissector.Represent(&entryData)
|
||||||
|
|
||||||
|
var rules []map[string]interface{}
|
||||||
|
if entryData.ProtocolName == "http" {
|
||||||
|
var pair tapApi.RequestResponsePair
|
||||||
|
json.Unmarshal([]byte(entryData.Entry), &pair)
|
||||||
|
harEntry, _ := utils.NewEntry(&pair)
|
||||||
|
_, rulesMatched := models.RunValidationRulesState(*harEntry, entryData.Service)
|
||||||
|
inrec, _ := json.Marshal(rulesMatched)
|
||||||
|
json.Unmarshal(inrec, &rules)
|
||||||
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, tapApi.MizuEntryWrapper{
|
c.JSON(http.StatusOK, tapApi.MizuEntryWrapper{
|
||||||
Protocol: protocol,
|
Protocol: protocol,
|
||||||
Representation: string(representation),
|
Representation: string(representation),
|
||||||
BodySize: bodySize,
|
BodySize: bodySize,
|
||||||
Data: entryData,
|
Data: entryData,
|
||||||
|
Rules: rules,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,9 +2,10 @@ package models
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
tapApi "github.com/up9inc/mizu/tap/api"
|
tapApi "github.com/up9inc/mizu/tap/api"
|
||||||
|
|
||||||
"mizuserver/pkg/rules"
|
"mizuserver/pkg/rules"
|
||||||
"mizuserver/pkg/utils"
|
|
||||||
|
|
||||||
"github.com/google/martian/har"
|
"github.com/google/martian/har"
|
||||||
"github.com/up9inc/mizu/shared"
|
"github.com/up9inc/mizu/shared"
|
||||||
@ -15,15 +16,6 @@ func GetEntry(r *tapApi.MizuEntry, v tapApi.DataUnmarshaler) error {
|
|||||||
return v.UnmarshalData(r)
|
return v.UnmarshalData(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: until we fixed the Rules feature
|
|
||||||
//func NewApplicableRules(status bool, latency int64, number int) tapApi.ApplicableRules {
|
|
||||||
// ar := tapApi.ApplicableRules{}
|
|
||||||
// ar.Status = status
|
|
||||||
// ar.Latency = latency
|
|
||||||
// ar.NumberOfRules = number
|
|
||||||
// return ar
|
|
||||||
//}
|
|
||||||
|
|
||||||
type EntriesFilter struct {
|
type EntriesFilter struct {
|
||||||
Limit int `form:"limit" validate:"required,min=1,max=200"`
|
Limit int `form:"limit" validate:"required,min=1,max=200"`
|
||||||
Operator string `form:"operator" validate:"required,oneof='lt' 'gt'"`
|
Operator string `form:"operator" validate:"required,oneof='lt' 'gt'"`
|
||||||
@ -105,33 +97,8 @@ type ExtendedCreator struct {
|
|||||||
Source *string `json:"_source"`
|
Source *string `json:"_source"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FullEntryWithPolicy struct {
|
func RunValidationRulesState(harEntry har.Entry, service string) (tapApi.ApplicableRules, []rules.RulesMatched) {
|
||||||
RulesMatched []rules.RulesMatched `json:"rulesMatched,omitempty"`
|
resultPolicyToSend := rules.MatchRequestPolicy(harEntry, service)
|
||||||
Entry har.Entry `json:"entry"`
|
statusPolicyToSend, latency, numberOfRules := rules.PassedValidationRules(resultPolicyToSend)
|
||||||
Service string `json:"service"`
|
return tapApi.ApplicableRules{Status: statusPolicyToSend, Latency: latency, NumberOfRules: numberOfRules}, resultPolicyToSend
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fewp *FullEntryWithPolicy) UnmarshalData(entry *tapApi.MizuEntry) error {
|
|
||||||
var pair tapApi.RequestResponsePair
|
|
||||||
if err := json.Unmarshal([]byte(entry.Entry), &pair); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
harEntry, err := utils.NewEntry(&pair)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fewp.Entry = *harEntry
|
|
||||||
|
|
||||||
_, resultPolicyToSend := rules.MatchRequestPolicy(fewp.Entry, entry.Service)
|
|
||||||
fewp.RulesMatched = resultPolicyToSend
|
|
||||||
fewp.Service = entry.Service
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: until we fixed the Rules feature
|
|
||||||
//func RunValidationRulesState(harEntry har.Entry, service string) tapApi.ApplicableRules {
|
|
||||||
// numberOfRules, resultPolicyToSend := rules.MatchRequestPolicy(harEntry, service)
|
|
||||||
// statusPolicyToSend, latency, numberOfRules := rules.PassedValidationRules(resultPolicyToSend, numberOfRules)
|
|
||||||
// ar := NewApplicableRules(statusPolicyToSend, latency, numberOfRules)
|
|
||||||
// return ar
|
|
||||||
//}
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package rules
|
package rules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -41,7 +42,7 @@ func ValidateService(serviceFromRule string, service string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func MatchRequestPolicy(harEntry har.Entry, service string) (int, []RulesMatched) {
|
func MatchRequestPolicy(harEntry har.Entry, service string) []RulesMatched {
|
||||||
enforcePolicy, _ := shared.DecodeEnforcePolicy(fmt.Sprintf("%s/%s", shared.RulePolicyPath, shared.RulePolicyFileName))
|
enforcePolicy, _ := shared.DecodeEnforcePolicy(fmt.Sprintf("%s/%s", shared.RulePolicyPath, shared.RulePolicyFileName))
|
||||||
var resultPolicyToSend []RulesMatched
|
var resultPolicyToSend []RulesMatched
|
||||||
for _, rule := range enforcePolicy.Rules {
|
for _, rule := range enforcePolicy.Rules {
|
||||||
@ -50,7 +51,8 @@ func MatchRequestPolicy(harEntry har.Entry, service string) (int, []RulesMatched
|
|||||||
}
|
}
|
||||||
if rule.Type == "json" {
|
if rule.Type == "json" {
|
||||||
var bodyJsonMap interface{}
|
var bodyJsonMap interface{}
|
||||||
if err := json.Unmarshal(harEntry.Response.Content.Text, &bodyJsonMap); err != nil {
|
contentTextDecoded, _ := base64.StdEncoding.DecodeString(string(harEntry.Response.Content.Text))
|
||||||
|
if err := json.Unmarshal(contentTextDecoded, &bodyJsonMap); err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
out, err := jsonpath.Read(bodyJsonMap, rule.Key)
|
out, err := jsonpath.Read(bodyJsonMap, rule.Key)
|
||||||
@ -63,6 +65,7 @@ func MatchRequestPolicy(harEntry har.Entry, service string) (int, []RulesMatched
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
fmt.Println(matchValue, rule.Value)
|
||||||
} else {
|
} else {
|
||||||
val := fmt.Sprint(out)
|
val := fmt.Sprint(out)
|
||||||
matchValue, err = regexp.MatchString(rule.Value, val)
|
matchValue, err = regexp.MatchString(rule.Value, val)
|
||||||
@ -89,22 +92,28 @@ func MatchRequestPolicy(harEntry har.Entry, service string) (int, []RulesMatched
|
|||||||
resultPolicyToSend = appendRulesMatched(resultPolicyToSend, true, rule)
|
resultPolicyToSend = appendRulesMatched(resultPolicyToSend, true, rule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len(enforcePolicy.Rules), resultPolicyToSend
|
return resultPolicyToSend
|
||||||
}
|
}
|
||||||
|
|
||||||
func PassedValidationRules(rulesMatched []RulesMatched, numberOfRules int) (bool, int64, int) {
|
func PassedValidationRules(rulesMatched []RulesMatched) (bool, int64, int) {
|
||||||
if len(rulesMatched) == 0 {
|
var numberOfRulesMatched = len(rulesMatched)
|
||||||
return false, 0, 0
|
var latency int64 = -1
|
||||||
|
|
||||||
|
if numberOfRulesMatched == 0 {
|
||||||
|
return false, 0, numberOfRulesMatched
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rule := range rulesMatched {
|
for _, rule := range rulesMatched {
|
||||||
if rule.Matched == false {
|
if rule.Matched == false {
|
||||||
return false, -1, len(rulesMatched)
|
return false, latency, numberOfRulesMatched
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
for _, rule := range rulesMatched {
|
|
||||||
if strings.ToLower(rule.Rule.Type) == "latency" {
|
if strings.ToLower(rule.Rule.Type) == "latency" {
|
||||||
return true, rule.Rule.Latency, len(rulesMatched)
|
if rule.Rule.Latency < latency || latency == -1 {
|
||||||
|
latency = rule.Rule.Latency
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true, -1, len(rulesMatched)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, latency, numberOfRulesMatched
|
||||||
}
|
}
|
@ -99,6 +99,11 @@ type RulePolicy struct {
|
|||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RulesMatched struct {
|
||||||
|
Matched bool `json:"matched"`
|
||||||
|
Rule RulePolicy `json:"rule"`
|
||||||
|
}
|
||||||
|
|
||||||
func (r *RulePolicy) validateType() bool {
|
func (r *RulePolicy) validateType() bool {
|
||||||
permitedTypes := []string{"json", "header", "latency"}
|
permitedTypes := []string{"json", "header", "latency"}
|
||||||
_, found := Find(permitedTypes, r.Type)
|
_, found := Find(permitedTypes, r.Type)
|
||||||
|
@ -137,6 +137,7 @@ type MizuEntryWrapper struct {
|
|||||||
Representation string `json:"representation"`
|
Representation string `json:"representation"`
|
||||||
BodySize int64 `json:"bodySize"`
|
BodySize int64 `json:"bodySize"`
|
||||||
Data MizuEntry `json:"data"`
|
Data MizuEntry `json:"data"`
|
||||||
|
Rules []map[string]interface{} `json:"rulesMatched,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BaseEntryDetails struct {
|
type BaseEntryDetails struct {
|
||||||
|
@ -42,7 +42,6 @@ const EntryTitle: React.FC<any> = ({protocol, data, bodySize, elapsedTime}) => {
|
|||||||
<div style={{right: "30px", position: "absolute", display: "flex"}}>
|
<div style={{right: "30px", position: "absolute", display: "flex"}}>
|
||||||
{response.payload && <div style={{margin: "0 18px", opacity: 0.5}}>{formatSize(bodySize)}</div>}
|
{response.payload && <div style={{margin: "0 18px", opacity: 0.5}}>{formatSize(bodySize)}</div>}
|
||||||
<div style={{marginRight: 18, opacity: 0.5}}>{Math.round(elapsedTime)}ms</div>
|
<div style={{marginRight: 18, opacity: 0.5}}>{Math.round(elapsedTime)}ms</div>
|
||||||
<div style={{opacity: 0.5}}>{'rulesMatched' in data ? data.rulesMatched?.length : '0'} Rules Applied</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
@ -72,7 +71,7 @@ export const EntryDetailed: React.FC<EntryDetailedProps> = ({entryData}) => {
|
|||||||
/>
|
/>
|
||||||
{entryData.data && <EntrySummary data={entryData.data}/>}
|
{entryData.data && <EntrySummary data={entryData.data}/>}
|
||||||
<>
|
<>
|
||||||
{entryData.data && <EntryViewer representation={entryData.representation} color={entryData.protocol.backgroundColor}/>}
|
{entryData.data && <EntryViewer representation={entryData.representation} rulesMatched={entryData.rulesMatched} elapsedTime={entryData.data.elapsedTime} color={entryData.protocol.backgroundColor}/>}
|
||||||
</>
|
</>
|
||||||
</>
|
</>
|
||||||
};
|
};
|
||||||
|
@ -215,10 +215,10 @@ export const EntryTablePolicySection: React.FC<EntryPolicySectionProps> = ({serv
|
|||||||
<>
|
<>
|
||||||
{
|
{
|
||||||
rule.Key &&
|
rule.Key &&
|
||||||
<tr className={styles.dataValue}><td><b>Key</b>:</td><td>{rule.Key}</td></tr>
|
<tr className={styles.dataValue}><td><b>Key:</b></td> <td>{rule.Key}</td></tr>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
rule.Latency &&
|
rule.Latency !== 0 &&
|
||||||
<tr className={styles.dataValue}><td><b>Latency:</b></td> <td>{rule.Latency}</td></tr>
|
<tr className={styles.dataValue}><td><b>Latency:</b></td> <td>{rule.Latency}</td></tr>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -231,7 +231,7 @@ export const EntryTablePolicySection: React.FC<EntryPolicySectionProps> = ({serv
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
rule.Service &&
|
rule.Service &&
|
||||||
<tr className={styles.dataValue}><td><b>Service:</b></td> <td>{service}</td></tr>
|
<tr className={styles.dataValue}><td><b>Service:</b></td> <td>{rule.Service}</td></tr>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
rule.Type &&
|
rule.Type &&
|
||||||
@ -251,7 +251,7 @@ export const EntryTablePolicySection: React.FC<EntryPolicySectionProps> = ({serv
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</EntrySectionContainer>
|
</EntrySectionContainer>
|
||||||
</> : <span/>
|
</> : <span className={styles.noRules}>No rules could be applied to this request.</span>
|
||||||
}
|
}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,7 @@ const SectionsRepresentation: React.FC<any> = ({data, color}) => {
|
|||||||
return <>{sections}</>;
|
return <>{sections}</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AutoRepresentation: React.FC<any> = ({representation, color}) => {
|
const AutoRepresentation: React.FC<any> = ({representation, rulesMatched, elapsedTime, color}) => {
|
||||||
const rulesMatched = []
|
|
||||||
const TABS = [
|
const TABS = [
|
||||||
{
|
{
|
||||||
tab: 'request'
|
tab: 'request'
|
||||||
@ -68,8 +67,7 @@ const AutoRepresentation: React.FC<any> = ({representation, color}) => {
|
|||||||
<SectionsRepresentation data={response} color={color}/>
|
<SectionsRepresentation data={response} color={color}/>
|
||||||
</React.Fragment>}
|
</React.Fragment>}
|
||||||
{currentTab === TABS[2].tab && <React.Fragment>
|
{currentTab === TABS[2].tab && <React.Fragment>
|
||||||
{// FIXME: Fix here
|
<EntryTablePolicySection service={representation.service} title={'Rule'} color={color} latency={elapsedTime} response={response} arrayToIterate={rulesMatched ? rulesMatched : []}/>
|
||||||
<EntryTablePolicySection service={representation.service} title={'Rule'} color={color} latency={0} response={response} arrayToIterate={rulesMatched ? rulesMatched : []}/>}
|
|
||||||
</React.Fragment>}
|
</React.Fragment>}
|
||||||
</div>}
|
</div>}
|
||||||
</div>;
|
</div>;
|
||||||
@ -77,11 +75,13 @@ const AutoRepresentation: React.FC<any> = ({representation, color}) => {
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
representation: any;
|
representation: any;
|
||||||
color: string,
|
rulesMatched: any;
|
||||||
|
color: string;
|
||||||
|
elapsedTime: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EntryViewer: React.FC<Props> = ({representation, color}) => {
|
const EntryViewer: React.FC<Props> = ({representation, rulesMatched, elapsedTime, color}) => {
|
||||||
return <AutoRepresentation representation={representation} color={color}/>
|
return <AutoRepresentation representation={representation} rulesMatched={rulesMatched} elapsedTime={elapsedTime} color={color}/>
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EntryViewer;
|
export default EntryViewer;
|
||||||
|
@ -19,20 +19,31 @@
|
|||||||
|
|
||||||
.rowSelected
|
.rowSelected
|
||||||
border: 1px $blue-color solid
|
border: 1px $blue-color solid
|
||||||
// border-left: 5px $blue-color solid
|
|
||||||
margin-left: 10px
|
|
||||||
margin-right: 3px
|
margin-right: 3px
|
||||||
|
|
||||||
.ruleSuccessRow
|
.ruleSuccessRow
|
||||||
border: 1px $success-color solid
|
background: #E8FFF1
|
||||||
// border-left: 5px $success-color solid
|
|
||||||
|
.ruleSuccessRowSelected
|
||||||
|
border: 1px #6FCF97 solid
|
||||||
|
border-left: 5px #6FCF97 solid
|
||||||
|
|
||||||
.ruleFailureRow
|
.ruleFailureRow
|
||||||
background: #FFE9EF
|
background: #FFE9EF
|
||||||
|
|
||||||
.ruleFailureRowSelected
|
.ruleFailureRowSelected
|
||||||
border: 1px $failure-color solid
|
border: 1px $failure-color solid
|
||||||
// border-left: 5px $failure-color solid
|
border-left: 5px $failure-color solid
|
||||||
|
|
||||||
|
.ruleNumberText
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: italic;
|
||||||
|
|
||||||
|
.ruleNumberTextFailure
|
||||||
|
color: #DB2156
|
||||||
|
|
||||||
|
.ruleNumberTextSuccess
|
||||||
|
color: #219653
|
||||||
|
|
||||||
.service
|
.service
|
||||||
text-overflow: ellipsis
|
text-overflow: ellipsis
|
||||||
|
@ -43,6 +43,7 @@ interface EntryProps {
|
|||||||
|
|
||||||
export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSelected, style}) => {
|
export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSelected, style}) => {
|
||||||
const classification = getClassification(entry.statusCode)
|
const classification = getClassification(entry.statusCode)
|
||||||
|
const numberOfRules = entry.rules.numberOfRules
|
||||||
let ingoingIcon;
|
let ingoingIcon;
|
||||||
let outgoingIcon;
|
let outgoingIcon;
|
||||||
switch(classification) {
|
switch(classification) {
|
||||||
@ -62,47 +63,39 @@ export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSel
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// let additionalRulesProperties = "";
|
let additionalRulesProperties = "";
|
||||||
// let ruleSuccess: boolean;
|
let ruleSuccess: boolean;
|
||||||
let rule = 'latency' in entry.rules
|
let rule = 'latency' in entry.rules
|
||||||
if (rule) {
|
if (rule) {
|
||||||
if (entry.rules.latency !== -1) {
|
if (entry.rules.latency !== -1) {
|
||||||
if (entry.rules.latency >= entry.latency) {
|
if (entry.rules.latency >= entry.latency) {
|
||||||
// additionalRulesProperties = styles.ruleSuccessRow
|
additionalRulesProperties = styles.ruleSuccessRow
|
||||||
// ruleSuccess = true
|
ruleSuccess = true
|
||||||
} else {
|
} else {
|
||||||
// additionalRulesProperties = styles.ruleFailureRow
|
additionalRulesProperties = styles.ruleFailureRow
|
||||||
// ruleSuccess = false
|
ruleSuccess = false
|
||||||
}
|
}
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
// additionalRulesProperties += ` ${entry.rules.latency >= entry.latency ? styles.ruleSuccessRowSelected : styles.ruleFailureRowSelected}`
|
additionalRulesProperties += ` ${entry.rules.latency >= entry.latency ? styles.ruleSuccessRowSelected : styles.ruleFailureRowSelected}`
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (entry.rules.status) {
|
if (entry.rules.status) {
|
||||||
// additionalRulesProperties = styles.ruleSuccessRow
|
additionalRulesProperties = styles.ruleSuccessRow
|
||||||
// ruleSuccess = true
|
ruleSuccess = true
|
||||||
} else {
|
} else {
|
||||||
// additionalRulesProperties = styles.ruleFailureRow
|
additionalRulesProperties = styles.ruleFailureRow
|
||||||
// ruleSuccess = false
|
ruleSuccess = false
|
||||||
}
|
}
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
// additionalRulesProperties += ` ${entry.rules.status ? styles.ruleSuccessRowSelected : styles.ruleFailureRowSelected}`
|
additionalRulesProperties += ` ${entry.rules.status ? styles.ruleSuccessRowSelected : styles.ruleFailureRowSelected}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let backgroundColor = "";
|
|
||||||
if ('latency' in entry.rules) {
|
|
||||||
if (entry.rules.latency !== -1) {
|
|
||||||
backgroundColor = entry.rules.latency >= entry.latency ? styles.ruleSuccessRow : styles.ruleFailureRow
|
|
||||||
} else {
|
|
||||||
backgroundColor = entry.rules.status ? styles.ruleSuccessRow : styles.ruleFailureRow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return <>
|
return <>
|
||||||
<div
|
<div
|
||||||
id={entry.id}
|
id={entry.id}
|
||||||
className={`${styles.row}
|
className={`${styles.row}
|
||||||
${isSelected ? styles.rowSelected : backgroundColor}`}
|
${isSelected && !rule ? styles.rowSelected : additionalRulesProperties}`}
|
||||||
onClick={() => setFocusedEntryId(entry.id)}
|
onClick={() => setFocusedEntryId(entry.id)}
|
||||||
style={{
|
style={{
|
||||||
border: isSelected ? `1px ${entry.protocol.backgroundColor} solid` : "1px transparent solid",
|
border: isSelected ? `1px ${entry.protocol.backgroundColor} solid` : "1px transparent solid",
|
||||||
@ -122,6 +115,13 @@ export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSel
|
|||||||
<span title="Service Name">{entry.service}</span>
|
<span title="Service Name">{entry.service}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{
|
||||||
|
rule ?
|
||||||
|
<div className={`${styles.ruleNumberText} ${ruleSuccess ? styles.ruleNumberTextSuccess : styles.ruleNumberTextFailure}`}>
|
||||||
|
{`Rules (${numberOfRules})`}
|
||||||
|
</div>
|
||||||
|
: ""
|
||||||
|
}
|
||||||
<div className={styles.directionContainer}>
|
<div className={styles.directionContainer}>
|
||||||
<span className={styles.port} title="Source Port">{entry.sourcePort}</span>
|
<span className={styles.port} title="Source Port">{entry.sourcePort}</span>
|
||||||
{entry.isOutgoing ?
|
{entry.isOutgoing ?
|
||||||
@ -138,4 +138,5 @@ export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSel
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
};
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user