import { podOwnerLookup, toShortResourceName } from './Utils.js';
import BaseTable from '../BaseTable.jsx';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Grid from '@material-ui/core/Grid';
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
import Popover from '../Popover.jsx';
import PropTypes from 'prop-types';
import React from 'react';
import TapLink from '../TapLink.jsx';
import Tooltip from '@material-ui/core/Tooltip';
import { Trans } from '@lingui/macro';
import _each from 'lodash/each';
import _get from 'lodash/get';
import _has from 'lodash/has';
import _isEmpty from 'lodash/isEmpty';
import _isNil from 'lodash/isNil';
import _map from 'lodash/map';
import _merge from 'lodash/merge';
import _size from 'lodash/size';
import _take from 'lodash/take';
import { faLongArrowAltRight } from '@fortawesome/free-solid-svg-icons/faLongArrowAltRight';
export const httpMethods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'];
export const defaultMaxRps = '100.0';
export const setMaxRps = query => {
if (!_isEmpty(query.maxRps)) {
query.maxRps = parseFloat(query.maxRps);
} else {
query.maxRps = 0; // golang unset value for maxRps
}
};
// resources you can tap/top to tap all pods in the resource
export const tapResourceTypes = [
'deployment',
'daemonset',
'pod',
'replicationcontroller',
'statefulset',
'job',
'replicaset',
'cronjob',
];
// use a generator to get this object, to prevent it from being overwritten
export const emptyTapQuery = () => ({
resource: '',
namespace: '',
toResource: '',
toNamespace: '',
method: '',
path: '',
scheme: '',
authority: '',
maxRps: '',
});
export const tapQueryProps = {
resource: PropTypes.string,
namespace: PropTypes.string,
toResource: PropTypes.string,
toNamespace: PropTypes.string,
method: PropTypes.string,
path: PropTypes.string,
scheme: PropTypes.string,
authority: PropTypes.string,
maxRps: PropTypes.string,
extract: PropTypes.bool,
};
export const tapQueryPropType = PropTypes.shape(tapQueryProps);
// from https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
export const wsCloseCodes = {
1000: 'Normal Closure',
1001: 'Going Away',
1002: 'Protocol Error',
1003: 'Unsupported Data',
1004: 'Reserved',
1005: 'No Status Recvd',
1006: 'Abnormal Closure',
1007: 'Invalid frame payload data',
1008: 'Policy Violation',
1009: 'Message too big',
1010: 'Missing Extension',
1011: 'Internal Error',
1012: 'Service Restart',
1013: 'Try Again Later',
1014: 'Bad Gateway',
1015: 'TLS Handshake',
};
export const WS_NORMAL_CLOSURE = 1000;
export const WS_ABNORMAL_CLOSURE = 1006;
export const WS_POLICY_VIOLATION = 1008;
/*
Use tap data to figure out a resource's unmeshed upstreams/downstreams
*/
export const processNeighborData = (source, labels, resourceAgg, resourceType) => {
if (_isEmpty(labels)) {
return resourceAgg;
}
let neighbor = {};
if (_has(labels, resourceType)) {
neighbor = {
type: resourceType,
name: labels[resourceType],
namespace: labels.namespace,
};
} else if (_has(labels, 'pod')) {
neighbor = {
type: 'pod',
name: labels.pod,
namespace: labels.namespace,
};
} else if (_has(labels, 'node')) {
neighbor = {
type: 'node',
name: labels.node,
};
} else {
neighbor = {
type: 'ip',
name: source.str,
};
}
// keep track of pods under this resource to display the number of unmeshed source pods
neighbor.pods = {};
if (labels.pod) {
neighbor.pods[labels.pod] = true;
}
const key = `${neighbor.type}/${neighbor.name}`;
if (_has(labels, 'control_plane_ns')) {
delete resourceAgg[key];
} else {
if (_has(resourceAgg, key)) {
_merge(neighbor.pods, resourceAgg[key].pods);
}
resourceAgg[key] = neighbor;
}
return resourceAgg;
};
/*
Use this key to associate the corresponding response with the request
so that we can have one single event with reqInit, rspInit and rspEnd
current key: (src, dst, stream)
*/
const tapEventKey = (d, eventType) => {
return `${d.source.str},${d.destination.str},${_get(d, ['http', eventType, 'id', 'stream'])}`;
};
/*
produce octets given an ip address
*/
const decodeIPToOctets = ip => {
const ip_ = parseInt(ip, 10);
return [
(ip_ >> 24) & 255,
(ip_ >> 16) & 255,
(ip_ >> 8) & 255,
ip_ & 255,
];
};
/*
converts an address to an ipv4 formatted host
*/
const publicAddressToString = ipv4 => {
const octets = decodeIPToOctets(ipv4);
return octets.join('.');
};
/*
display more human-readable information about source/destination
*/
const resourceShortLink = (resourceType, labels, ResourceLink) => (