diff --git a/agent/pkg/api/main.go b/agent/pkg/api/main.go index 97291fc9a..42f86817a 100644 --- a/agent/pkg/api/main.go +++ b/agent/pkg/api/main.go @@ -136,7 +136,7 @@ func startReadingChannel(outputItems <-chan *tapApi.OutputChannelItem, extension harEntry, err := utils.NewEntry(mizuEntry.Request, mizuEntry.Response, mizuEntry.StartTime, mizuEntry.ElapsedTime) if err == nil { - rules, _, _ := models.RunValidationRulesState(*harEntry, mizuEntry.Service) + rules, _, _ := models.RunValidationRulesState(*harEntry, mizuEntry.Destination.Name) baseEntry.Rules = rules } } diff --git a/agent/pkg/controllers/entries_controller.go b/agent/pkg/controllers/entries_controller.go index 2d5e2e536..0b2f0724a 100644 --- a/agent/pkg/controllers/entries_controller.go +++ b/agent/pkg/controllers/entries_controller.go @@ -119,7 +119,7 @@ func GetEntry(c *gin.Context) { var isRulesEnabled bool if entry.Protocol.Name == "http" { harEntry, _ := utils.NewEntry(entry.Request, entry.Response, entry.StartTime, entry.ElapsedTime) - _, rulesMatched, _isRulesEnabled := models.RunValidationRulesState(*harEntry, entry.Service) + _, rulesMatched, _isRulesEnabled := models.RunValidationRulesState(*harEntry, entry.Destination.Name) isRulesEnabled = _isRulesEnabled inrec, _ := json.Marshal(rulesMatched) json.Unmarshal(inrec, &rules) diff --git a/agent/pkg/up9/main.go b/agent/pkg/up9/main.go index 9f0a1d185..e44c2b9e2 100644 --- a/agent/pkg/up9/main.go +++ b/agent/pkg/up9/main.go @@ -251,12 +251,12 @@ func syncEntriesImpl(token string, model string, envPrefix string, uploadInterva if err != nil { continue } - if entry.ResolvedSource != "" { - harEntry.Request.Headers = append(harEntry.Request.Headers, har.Header{Name: "x-mizu-source", Value: entry.ResolvedSource}) + if entry.Source.Name != "" { + harEntry.Request.Headers = append(harEntry.Request.Headers, har.Header{Name: "x-mizu-source", Value: entry.Source.Name}) } - if entry.ResolvedDestination != "" { - harEntry.Request.Headers = append(harEntry.Request.Headers, har.Header{Name: "x-mizu-destination", Value: entry.ResolvedDestination}) - harEntry.Request.URL = utils.SetHostname(harEntry.Request.URL, entry.ResolvedDestination) + if entry.Destination.Name != "" { + harEntry.Request.Headers = append(harEntry.Request.Headers, har.Header{Name: "x-mizu-destination", Value: entry.Destination.Name}) + harEntry.Request.URL = utils.SetHostname(harEntry.Request.URL, entry.Destination.Name) } // go's default marshal behavior is to encode []byte fields to base64, python's default unmarshal behavior is to not decode []byte fields from base64 diff --git a/tap/api/api.go b/tap/api/api.go index 36bd6241f..3b1f9834a 100644 --- a/tap/api/api.go +++ b/tap/api/api.go @@ -129,19 +129,10 @@ type MizuEntry struct { Response map[string]interface{} `json:"response"` Base *BaseEntryDetails `json:"base"` Summary string `json:"summary"` - Url string `json:"url"` Method string `json:"method"` Status int `json:"status"` - RequestSenderIp string `json:"requestSenderIp"` - Service string `json:"service"` ElapsedTime int64 `json:"elapsedTime"` Path string `json:"path"` - ResolvedSource string `json:"resolvedSource,omitempty"` - ResolvedDestination string `json:"resolvedDestination,omitempty"` - SourceIp string `json:"sourceIp,omitempty"` - DestinationIp string `json:"destinationIp,omitempty"` - SourcePort string `json:"sourcePort,omitempty"` - DestinationPort string `json:"destinationPort,omitempty"` IsOutgoing bool `json:"isOutgoing,omitempty"` ContractStatus ContractStatus `json:"contractStatus,omitempty"` ContractRequestReason string `json:"contractRequestReason,omitempty"` @@ -160,24 +151,20 @@ type MizuEntryWrapper struct { } type BaseEntryDetails struct { - Id uint `json:"id"` - Protocol Protocol `json:"protocol,omitempty"` - Url string `json:"url,omitempty"` - RequestSenderIp string `json:"requestSenderIp,omitempty"` - Service string `json:"service,omitempty"` - Path string `json:"path,omitempty"` - Summary string `json:"summary,omitempty"` - StatusCode int `json:"statusCode"` - Method string `json:"method,omitempty"` - Timestamp int64 `json:"timestamp,omitempty"` - SourceIp string `json:"sourceIp,omitempty"` - DestinationIp string `json:"destinationIp,omitempty"` - SourcePort string `json:"sourcePort,omitempty"` - DestinationPort string `json:"destinationPort,omitempty"` - IsOutgoing bool `json:"isOutgoing,omitempty"` - Latency int64 `json:"latency"` - Rules ApplicableRules `json:"rules,omitempty"` - ContractStatus ContractStatus `json:"contractStatus"` + Id uint `json:"id"` + Protocol Protocol `json:"protocol,omitempty"` + Url string `json:"url,omitempty"` + Path string `json:"path,omitempty"` + Summary string `json:"summary,omitempty"` + StatusCode int `json:"statusCode"` + Method string `json:"method,omitempty"` + Timestamp int64 `json:"timestamp,omitempty"` + Source *TCP `json:"src"` + Destination *TCP `json:"dst"` + IsOutgoing bool `json:"isOutgoing,omitempty"` + Latency int64 `json:"latency"` + Rules ApplicableRules `json:"rules,omitempty"` + ContractStatus ContractStatus `json:"contractStatus"` } type ApplicableRules struct { @@ -202,18 +189,13 @@ type DataUnmarshaler interface { func (bed *BaseEntryDetails) UnmarshalData(entry *MizuEntry) error { bed.Protocol = entry.Protocol bed.Id = entry.Id - bed.Url = entry.Url - bed.RequestSenderIp = entry.RequestSenderIp - bed.Service = entry.Service bed.Path = entry.Path - bed.Summary = entry.Path + bed.Summary = entry.Summary bed.StatusCode = entry.Status bed.Method = entry.Method bed.Timestamp = entry.Timestamp - bed.SourceIp = entry.SourceIp - bed.DestinationIp = entry.DestinationIp - bed.SourcePort = entry.SourcePort - bed.DestinationPort = entry.DestinationPort + bed.Source = entry.Source + bed.Destination = entry.Destination bed.IsOutgoing = entry.IsOutgoing bed.Latency = entry.ElapsedTime bed.ContractStatus = entry.ContractStatus @@ -271,7 +253,6 @@ func (h HTTPPayload) MarshalJSON() ([]byte, error) { } return json.Marshal(&HTTPWrapper{ Method: harRequest.Method, - Url: "", Details: harRequest, RawRequest: &HTTPRequestWrapper{Request: h.Data.(*http.Request)}, }) diff --git a/tap/extensions/amqp/main.go b/tap/extensions/amqp/main.go index af9155461..01bd2fac6 100644 --- a/tap/extensions/amqp/main.go +++ b/tap/extensions/amqp/main.go @@ -226,12 +226,6 @@ func (d dissecting) Dissect(b *bufio.Reader, isClient bool, tcpID *api.TcpID, co func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, resolvedDestination string) *api.MizuEntry { request := item.Pair.Request.Payload.(map[string]interface{}) reqDetails := request["details"].(map[string]interface{}) - service := "amqp" - if resolvedDestination != "" { - service = resolvedDestination - } else if resolvedSource != "" { - service = resolvedSource - } summary := "" switch request["method"] { @@ -279,45 +273,31 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, IP: item.ConnectionInfo.ServerIP, Port: item.ConnectionInfo.ServerPort, }, - Outgoing: item.ConnectionInfo.IsOutgoing, - Request: reqDetails, - Url: fmt.Sprintf("%s%s", service, summary), - Method: request["method"].(string), - Status: 0, - RequestSenderIp: item.ConnectionInfo.ClientIP, - Service: service, - Timestamp: item.Timestamp, - StartTime: item.Pair.Request.CaptureTime, - ElapsedTime: 0, - Summary: summary, - ResolvedSource: resolvedSource, - ResolvedDestination: resolvedDestination, - SourceIp: item.ConnectionInfo.ClientIP, - DestinationIp: item.ConnectionInfo.ServerIP, - SourcePort: item.ConnectionInfo.ClientPort, - DestinationPort: item.ConnectionInfo.ServerPort, - IsOutgoing: item.ConnectionInfo.IsOutgoing, + Outgoing: item.ConnectionInfo.IsOutgoing, + Request: reqDetails, + Method: request["method"].(string), + Status: 0, + Timestamp: item.Timestamp, + StartTime: item.Pair.Request.CaptureTime, + ElapsedTime: 0, + Summary: summary, + IsOutgoing: item.ConnectionInfo.IsOutgoing, } } func (d dissecting) Summarize(entry *api.MizuEntry) *api.BaseEntryDetails { return &api.BaseEntryDetails{ - Id: entry.Id, - Protocol: protocol, - Url: entry.Url, - RequestSenderIp: entry.RequestSenderIp, - Service: entry.Service, - Summary: entry.Summary, - StatusCode: entry.Status, - Method: entry.Method, - Timestamp: entry.Timestamp, - SourceIp: entry.SourceIp, - DestinationIp: entry.DestinationIp, - SourcePort: entry.SourcePort, - DestinationPort: entry.DestinationPort, - IsOutgoing: entry.IsOutgoing, - Latency: entry.ElapsedTime, + Id: entry.Id, + Protocol: protocol, + Summary: entry.Summary, + StatusCode: entry.Status, + Method: entry.Method, + Timestamp: entry.Timestamp, + Source: entry.Source, + Destination: entry.Destination, + IsOutgoing: entry.IsOutgoing, + Latency: entry.ElapsedTime, Rules: api.ApplicableRules{ Latency: 0, Status: false, diff --git a/tap/extensions/http/main.go b/tap/extensions/http/main.go index fa3eea323..26cf40c8c 100644 --- a/tap/extensions/http/main.go +++ b/tap/extensions/http/main.go @@ -158,7 +158,7 @@ func (d dissecting) Dissect(b *bufio.Reader, isClient bool, tcpID *api.TcpID, co } func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, resolvedDestination string) *api.MizuEntry { - var host, authority, path, service string + var host, authority, path string request := item.Pair.Request.Payload.(map[string]interface{}) response := item.Pair.Response.Payload.(map[string]interface{}) @@ -191,9 +191,13 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, } if item.Protocol.Version == "2.0" && !isRequestUpgradedH2C { - service = authority + if resolvedDestination == "" { + resolvedDestination = authority + } + if resolvedDestination == "" { + resolvedDestination = host + } } else { - service = host u, err := url.Parse(reqDetails["url"].(string)) if err != nil { path = reqDetails["url"].(string) @@ -221,12 +225,6 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, reqDetails["_queryString"] = reqDetails["queryString"] reqDetails["queryString"] = mapSliceRebuildAsMap(reqDetails["_queryString"].([]interface{})) - if resolvedDestination != "" { - service = resolvedDestination - } else if resolvedSource != "" { - service = resolvedSource - } - method := reqDetails["method"].(string) statusCode := int(resDetails["status"].(float64)) if item.Protocol.Abbreviation == "gRPC" { @@ -255,47 +253,33 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, IP: item.ConnectionInfo.ServerIP, Port: item.ConnectionInfo.ServerPort, }, - Outgoing: item.ConnectionInfo.IsOutgoing, - Request: reqDetails, - Response: resDetails, - Url: fmt.Sprintf("%s%s", service, path), - Method: method, - Status: statusCode, - RequestSenderIp: item.ConnectionInfo.ClientIP, - Service: service, - Timestamp: item.Timestamp, - StartTime: item.Pair.Request.CaptureTime, - ElapsedTime: elapsedTime, - Summary: path, - ResolvedSource: resolvedSource, - ResolvedDestination: resolvedDestination, - SourceIp: item.ConnectionInfo.ClientIP, - DestinationIp: item.ConnectionInfo.ServerIP, - SourcePort: item.ConnectionInfo.ClientPort, - DestinationPort: item.ConnectionInfo.ServerPort, - IsOutgoing: item.ConnectionInfo.IsOutgoing, - HTTPPair: string(httpPair), + Outgoing: item.ConnectionInfo.IsOutgoing, + Request: reqDetails, + Response: resDetails, + Method: method, + Status: statusCode, + Timestamp: item.Timestamp, + StartTime: item.Pair.Request.CaptureTime, + ElapsedTime: elapsedTime, + Summary: path, + IsOutgoing: item.ConnectionInfo.IsOutgoing, + HTTPPair: string(httpPair), } } func (d dissecting) Summarize(entry *api.MizuEntry) *api.BaseEntryDetails { return &api.BaseEntryDetails{ - Id: entry.Id, - Protocol: entry.Protocol, - Url: entry.Url, - RequestSenderIp: entry.RequestSenderIp, - Service: entry.Service, - Path: entry.Path, - Summary: entry.Summary, - StatusCode: entry.Status, - Method: entry.Method, - Timestamp: entry.Timestamp, - SourceIp: entry.SourceIp, - DestinationIp: entry.DestinationIp, - SourcePort: entry.SourcePort, - DestinationPort: entry.DestinationPort, - IsOutgoing: entry.IsOutgoing, - Latency: entry.ElapsedTime, + Id: entry.Id, + Protocol: entry.Protocol, + Path: entry.Path, + Summary: entry.Summary, + StatusCode: entry.Status, + Method: entry.Method, + Timestamp: entry.Timestamp, + Source: entry.Source, + Destination: entry.Destination, + IsOutgoing: entry.IsOutgoing, + Latency: entry.ElapsedTime, Rules: api.ApplicableRules{ Latency: 0, Status: false, diff --git a/tap/extensions/kafka/main.go b/tap/extensions/kafka/main.go index 9dff00388..43af66140 100644 --- a/tap/extensions/kafka/main.go +++ b/tap/extensions/kafka/main.go @@ -65,12 +65,6 @@ func (d dissecting) Dissect(b *bufio.Reader, isClient bool, tcpID *api.TcpID, co func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, resolvedDestination string) *api.MizuEntry { request := item.Pair.Request.Payload.(map[string]interface{}) reqDetails := request["details"].(map[string]interface{}) - service := "kafka" - if resolvedDestination != "" { - service = resolvedDestination - } else if resolvedSource != "" { - service = resolvedSource - } apiKey := ApiKey(reqDetails["apiKey"].(float64)) summary := "" @@ -164,45 +158,31 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, IP: item.ConnectionInfo.ServerIP, Port: item.ConnectionInfo.ServerPort, }, - Outgoing: item.ConnectionInfo.IsOutgoing, - Request: reqDetails, - Response: item.Pair.Response.Payload.(map[string]interface{})["details"].(map[string]interface{}), - Url: fmt.Sprintf("%s%s", service, summary), - Method: apiNames[apiKey], - Status: 0, - RequestSenderIp: item.ConnectionInfo.ClientIP, - Service: service, - Timestamp: item.Timestamp, - StartTime: item.Pair.Request.CaptureTime, - ElapsedTime: elapsedTime, - Summary: summary, - ResolvedSource: resolvedSource, - ResolvedDestination: resolvedDestination, - SourceIp: item.ConnectionInfo.ClientIP, - DestinationIp: item.ConnectionInfo.ServerIP, - SourcePort: item.ConnectionInfo.ClientPort, - DestinationPort: item.ConnectionInfo.ServerPort, - IsOutgoing: item.ConnectionInfo.IsOutgoing, + Outgoing: item.ConnectionInfo.IsOutgoing, + Request: reqDetails, + Response: item.Pair.Response.Payload.(map[string]interface{})["details"].(map[string]interface{}), + Method: apiNames[apiKey], + Status: 0, + Timestamp: item.Timestamp, + StartTime: item.Pair.Request.CaptureTime, + ElapsedTime: elapsedTime, + Summary: summary, + IsOutgoing: item.ConnectionInfo.IsOutgoing, } } func (d dissecting) Summarize(entry *api.MizuEntry) *api.BaseEntryDetails { return &api.BaseEntryDetails{ - Id: entry.Id, - Protocol: _protocol, - Url: entry.Url, - RequestSenderIp: entry.RequestSenderIp, - Service: entry.Service, - Summary: entry.Summary, - StatusCode: entry.Status, - Method: entry.Method, - Timestamp: entry.Timestamp, - SourceIp: entry.SourceIp, - DestinationIp: entry.DestinationIp, - SourcePort: entry.SourcePort, - DestinationPort: entry.DestinationPort, - IsOutgoing: entry.IsOutgoing, - Latency: entry.ElapsedTime, + Id: entry.Id, + Protocol: _protocol, + Summary: entry.Summary, + StatusCode: entry.Status, + Method: entry.Method, + Timestamp: entry.Timestamp, + Source: entry.Source, + Destination: entry.Destination, + IsOutgoing: entry.IsOutgoing, + Latency: entry.ElapsedTime, Rules: api.ApplicableRules{ Latency: 0, Status: false, diff --git a/tap/extensions/redis/main.go b/tap/extensions/redis/main.go index f2d2836d5..e8a6d0f31 100644 --- a/tap/extensions/redis/main.go +++ b/tap/extensions/redis/main.go @@ -65,13 +65,6 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, reqDetails := request["details"].(map[string]interface{}) resDetails := response["details"].(map[string]interface{}) - service := "redis" - if resolvedDestination != "" { - service = resolvedDestination - } else if resolvedSource != "" { - service = resolvedSource - } - method := "" if reqDetails["command"] != nil { method = reqDetails["command"].(string) @@ -99,46 +92,32 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, resolvedSource string, IP: item.ConnectionInfo.ServerIP, Port: item.ConnectionInfo.ServerPort, }, - Outgoing: item.ConnectionInfo.IsOutgoing, - Request: reqDetails, - Response: resDetails, - Url: fmt.Sprintf("%s%s", service, summary), - Method: method, - Status: 0, - RequestSenderIp: item.ConnectionInfo.ClientIP, - Service: service, - Timestamp: item.Timestamp, - StartTime: item.Pair.Request.CaptureTime, - ElapsedTime: elapsedTime, - Summary: summary, - ResolvedSource: resolvedSource, - ResolvedDestination: resolvedDestination, - SourceIp: item.ConnectionInfo.ClientIP, - DestinationIp: item.ConnectionInfo.ServerIP, - SourcePort: item.ConnectionInfo.ClientPort, - DestinationPort: item.ConnectionInfo.ServerPort, - IsOutgoing: item.ConnectionInfo.IsOutgoing, + Outgoing: item.ConnectionInfo.IsOutgoing, + Request: reqDetails, + Response: resDetails, + Method: method, + Status: 0, + Timestamp: item.Timestamp, + StartTime: item.Pair.Request.CaptureTime, + ElapsedTime: elapsedTime, + Summary: summary, + IsOutgoing: item.ConnectionInfo.IsOutgoing, } } func (d dissecting) Summarize(entry *api.MizuEntry) *api.BaseEntryDetails { return &api.BaseEntryDetails{ - Id: entry.Id, - Protocol: protocol, - Url: entry.Url, - RequestSenderIp: entry.RequestSenderIp, - Service: entry.Service, - Summary: entry.Summary, - StatusCode: entry.Status, - Method: entry.Method, - Timestamp: entry.Timestamp, - SourceIp: entry.SourceIp, - DestinationIp: entry.DestinationIp, - SourcePort: entry.SourcePort, - DestinationPort: entry.DestinationPort, - IsOutgoing: entry.IsOutgoing, - Latency: entry.ElapsedTime, + Id: entry.Id, + Protocol: protocol, + Summary: entry.Summary, + StatusCode: entry.Status, + Method: entry.Method, + Timestamp: entry.Timestamp, + Source: entry.Source, + Destination: entry.Destination, + IsOutgoing: entry.IsOutgoing, + Latency: entry.ElapsedTime, Rules: api.ApplicableRules{ Latency: 0, Status: false, diff --git a/ui/src/components/EntryListItem/EntryListItem.module.sass b/ui/src/components/EntryListItem/EntryListItem.module.sass index 5a86a38ba..7e396d136 100644 --- a/ui/src/components/EntryListItem/EntryListItem.module.sass +++ b/ui/src/components/EntryListItem/EntryListItem.module.sass @@ -45,7 +45,7 @@ .ruleNumberTextSuccess color: #219653 -.service +.resolvedName text-overflow: ellipsis overflow: hidden white-space: nowrap diff --git a/ui/src/components/EntryListItem/EntryListItem.tsx b/ui/src/components/EntryListItem/EntryListItem.tsx index 0a3c12285..0b9a860a4 100644 --- a/ui/src/components/EntryListItem/EntryListItem.tsx +++ b/ui/src/components/EntryListItem/EntryListItem.tsx @@ -1,5 +1,6 @@ import React from "react"; import Moment from 'moment'; +import SwapHorizIcon from '@material-ui/icons/SwapHoriz'; import styles from './EntryListItem.module.sass'; import StatusCode, {getClassification, StatusCodeClassification} from "../UI/StatusCode"; import Protocol, {ProtocolInterface} from "../UI/Protocol" @@ -12,19 +13,21 @@ import outgoingIconSuccess from "../assets/outgoing-traffic-success.svg" import outgoingIconFailure from "../assets/outgoing-traffic-failure.svg" import outgoingIconNeutral from "../assets/outgoing-traffic-neutral.svg" +interface TCPInterface { + ip: string + port: string + name: string +} + interface Entry { protocol: ProtocolInterface, method?: string, summary: string, - service: string, id: number, statusCode?: number; - url?: string; timestamp: Date; - sourceIp: string, - sourcePort: string, - destinationIp: string, - destinationPort: string, + src: TCPInterface, + dst: TCPInterface, isOutgoing?: boolean; latency: number; rules: Rules; @@ -151,17 +154,33 @@ export const EntryItem: React.FC = ({entry, focusedEntryId, setFocus }
-
+
+ + {entry.src.name ? entry.src.name : "[Unresolved]"} + + + + - {entry.service} + {entry.dst.name ? entry.dst.name : "[Unresolved]"}
@@ -182,7 +201,7 @@ export const EntryItem: React.FC = ({entry, focusedEntryId, setFocus }
= ({entry, focusedEntryId, setFocus className={`${styles.tcpInfo} ${styles.ip}`} title="Source IP" > - {entry.sourceIp} + {entry.src.ip} : = ({entry, focusedEntryId, setFocus className={`${styles.tcpInfo} ${styles.port}`} title="Source Port" > - {entry.sourcePort} + {entry.src.port} {entry.isOutgoing ? @@ -243,7 +262,7 @@ export const EntryItem: React.FC = ({entry, focusedEntryId, setFocus } = ({entry, focusedEntryId, setFocus className={`${styles.tcpInfo} ${styles.ip}`} title="Destination IP" > - {entry.destinationIp} + {entry.dst.ip} : = ({entry, focusedEntryId, setFocus className={`${styles.tcpInfo} ${styles.port}`} title="Destination Port" > - {entry.destinationPort} + {entry.dst.port}
diff --git a/ui/src/components/Filters.tsx b/ui/src/components/Filters.tsx index 3ee23001b..0afc7325d 100644 --- a/ui/src/components/Filters.tsx +++ b/ui/src/components/Filters.tsx @@ -244,7 +244,7 @@ export const QueryForm: React.FC = ({query, setQuery, background diff --git a/ui/src/components/assets/filter-ui-example-1.png b/ui/src/components/assets/filter-ui-example-1.png index f8f76b85a..6f4d88430 100644 Binary files a/ui/src/components/assets/filter-ui-example-1.png and b/ui/src/components/assets/filter-ui-example-1.png differ