import _ from 'lodash'; import BaseTable from './BaseTable.jsx'; import { formatLatencySec } from './util/Utils.js'; import React from 'react'; import { srcDstColumn } from './util/TapUtils.jsx'; import { Col, Icon, Row, Table } from 'antd'; // https://godoc.org/google.golang.org/grpc/codes#Code const grpcStatusCodes = { 0: "OK", 1: "Canceled", 2: "Unknown", 3: "InvalidArgument", 4: "DeadlineExceeded", 5: "NotFound", 6: "AlreadyExists", 7: "PermissionDenied", 8: "ResourceExhausted", 9: "FailedPrecondition", 10: "Aborted", 11: "OutOfRange", 12: "Unimplemented", 13: "Internal", 14: "Unavailable", 15: "DataLoss", 16: "Unauthenticated" }; const grpcStatusCodeFilters = _.map(grpcStatusCodes, (description, code) => { return { text: `${code}: ${description}`, value: code }; }); const genFilterOptionList = options => _.map(options, (_v, k) => { return { text: k, value: k }; }); let tapColumns = filterOptions => [ { title: "ID", dataIndex: "requestInit.http.requestInit.id.stream" }, { title: "Direction", dataIndex: "base.proxyDirection", filters: [ { text: "Inbound", value: "INBOUND" }, { text: "Outbound", value: "OUTBOUND" } ], onFilter: (value, row) => _.get(row, "base.proxyDirection").includes(value) }, { title: "Source", key: "source", dataIndex: "base", filters: genFilterOptionList(filterOptions.source), onFilter: (value, row) => row.base.source.pod === value || row.base.source.str === value, render: d => srcDstColumn(_.get(d, "source"), _.get(d, "sourceMeta.labels", {})) }, { title: "Destination", key: "destination", dataIndex: "base", filters: genFilterOptionList(filterOptions.destination), onFilter: (value, row) => row.base.destination.pod === value || row.base.destination.str === value, render: d => srcDstColumn(_.get(d, "destination"), _.get(d, "destinationMeta.labels", {})) }, { title: "TLS", dataIndex: "base.tls", filters: genFilterOptionList(filterOptions.tls), onFilter: (value, row) => row.tls === value }, { title: "Request Init", children: [ { title: "Authority", key: "authority", dataIndex: "requestInit.http.requestInit", filters: genFilterOptionList(filterOptions.authority), onFilter: (value, row) => _.get(row, "requestInit.http.requestInit.authority") === value, render: d => !d ? : d.authority }, { title: "Path", key: "path", dataIndex: "requestInit.http.requestInit", filters: genFilterOptionList(filterOptions.path), onFilter: (value, row) => _.get(row, "requestInit.http.requestInit.path") === value, render: d => !d ? : d.path }, { title: "Scheme", key: "scheme", dataIndex: "requestInit.http.requestInit", filters: genFilterOptionList(filterOptions.scheme), onFilter: (value, row) => _.get(row, "requestInit.http.requestInit.scheme.registered") === value, render: d => !d ? : _.get(d, "scheme.registered") }, { title: "Method", key: "method", dataIndex: "requestInit.http.requestInit", filters: _.map(filterOptions.httpMethod, d => { return { text: d, value: d}; }), onFilter: (value, row) => _.get(row, "requestInit.http.requestInit.method.registered") === value, render: d => !d ? : _.get(d, "method.registered") } ] }, { title: "Response Init", children: [ { title: "HTTP status", key: "http-status", dataIndex: "responseInit.http.responseInit", filters: genFilterOptionList(filterOptions.httpStatus), onFilter: (value, row) => _.get(row, "responseInit.http.responseInit.httpStatus") + "" === value, render: d => !d ? : d.httpStatus }, { title: "Latency", key: "rsp-latency", dataIndex: "responseInit.http.responseInit", render: d => !d ? : formatTapLatency(d.sinceRequestInit) }, ] }, { title: "Response End", children: [ { title: "GRPC status", key: "grpc-status", dataIndex: "responseEnd.http.responseEnd", filters: grpcStatusCodeFilters, onFilter: (value, row) => (_.get(row, "responseEnd.http.responseEnd.eos.grpcStatusCode") + "") === value, render: d => !d ? : _.get(d, "eos.grpcStatusCode") }, { title: "Latency", key: "end-latency", dataIndex: "responseEnd.http.responseEnd", render: d => !d ? : formatTapLatency(d.sinceResponseInit) }, { title: "Response Length (B)", key: "rsp-length", dataIndex: "responseEnd.http.responseEnd", render: d => !d ? : d.responseBytes }, ] } ]; const formatTapLatency = str => { return formatLatencySec(str.replace("s", "")); }; const srcDstMetaColumns = [ { title: "", dataIndex: "labelName" }, { title: "", dataIndex: "labelVal" } ]; const renderMetaLabels = (title, labels) => { let data = _.map(labels, (v, k) => { return { labelName: k, labelVal: v }; }); return (
{title}
title.replace(" ", "_") + row.labelName + row.labelVal} bordered={false} showHeader={false} pagination={false} /> ); }; // hide verbose information const expandedRowRender = d => { return ( { renderMetaLabels("Source Metadata", _.get(d, "base.sourceMeta.labels", {})) }{ renderMetaLabels("Destination Metadata", _.get(d, "base.destinationMeta.labels", {})) } ); }; export default class TapEventTable extends BaseTable { render() { return ( r.base.id} pagination={false} className="tap-event-table" size="middle" /> ); } }