diff --git a/client/app/scripts/components/node-details.js b/client/app/scripts/components/node-details.js
index d37694729..387565ea6 100644
--- a/client/app/scripts/components/node-details.js
+++ b/client/app/scripts/components/node-details.js
@@ -5,6 +5,7 @@ import { Map as makeMap } from 'immutable';
import { clickCloseDetails, clickShowTopologyForNode } from '../actions/app-actions';
import { brightenColor, getNeutralColor, getNodeColorDark } from '../utils/color-utils';
+import { isGenericTable, isPropertyList } from '../utils/node-details-utils';
import { resetDocumentTitle, setDocumentTitle } from '../utils/title-utils';
import MatchedText from './matched-text';
@@ -25,9 +26,6 @@ function getTruncationText(count) {
+ ` (${count} extra entries not included). We are working to remove this limitation.`;
}
-const TABLE_TYPE_PROPERTY_LIST = 'property-list';
-const TABLE_TYPE_GENERIC = 'multicolumn-table';
-
class NodeDetails extends React.Component {
constructor(props, context) {
super(props, context);
@@ -215,7 +213,7 @@ class NodeDetails extends React.Component {
return (
- {table.label}
+ {table.label.length > 0 && table.label}
{table.truncationCount > 0 &&
@@ -234,25 +232,25 @@ class NodeDetails extends React.Component {
renderTable(table) {
const { nodeMatches = makeMap() } = this.props;
- switch (table.type) {
- case TABLE_TYPE_GENERIC:
- return (
-
- );
- case TABLE_TYPE_PROPERTY_LIST:
- return (
-
- );
- default:
- logError(`Undefined type '${table.type}' for table ${table.id}`);
- return null;
+
+ if (isGenericTable(table)) {
+ return (
+
+ );
+ } else if (isPropertyList(table)) {
+ return (
+
+ );
}
+
+ logError(`Undefined type '${table.type}' for table ${table.id}`);
+ return null;
}
componentDidUpdate() {
diff --git a/client/app/scripts/components/node-details/node-details-generic-table.js b/client/app/scripts/components/node-details/node-details-generic-table.js
index ad37ee44a..3478078be 100644
--- a/client/app/scripts/components/node-details/node-details-generic-table.js
+++ b/client/app/scripts/components/node-details/node-details-generic-table.js
@@ -2,28 +2,25 @@ import React from 'react';
import { Map as makeMap } from 'immutable';
import { sortBy } from 'lodash';
+import { NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT } from '../../constants/limits';
+import {
+ isNumber, getTableColumnsStyles, genericTableEntryKey
+} from '../../utils/node-details-utils';
+import NodeDetailsTableHeaders from './node-details-table-headers';
import MatchedText from '../matched-text';
import ShowMore from '../show-more';
-function columnStyle(column) {
- return {
- textAlign: column.dataType === 'number' ? 'right' : 'left',
- paddingRight: '10px',
- maxWidth: '140px'
- };
-}
-
-function sortedRows(rows, sortedByColumn, sortedDesc) {
- const orderedRows = sortBy(rows, row => row.id);
- const sorted = sortBy(orderedRows, (row) => {
- let value = row.entries[sortedByColumn.id];
- if (sortedByColumn.dataType === 'number') {
+function sortedRows(rows, columns, sortedBy, sortedDesc) {
+ const column = columns.find(c => c.id === sortedBy);
+ const sorted = sortBy(rows, (row) => {
+ let value = row.entries[sortedBy];
+ if (isNumber(column)) {
value = parseFloat(value);
}
return value;
});
- if (!sortedDesc) {
+ if (sortedDesc) {
sorted.reverse();
}
return sorted;
@@ -32,85 +29,68 @@ function sortedRows(rows, sortedByColumn, sortedDesc) {
export default class NodeDetailsGenericTable extends React.Component {
constructor(props, context) {
super(props, context);
- this.DEFAULT_LIMIT = 5;
this.state = {
- limit: this.DEFAULT_LIMIT,
- sortedByColumn: props.columns[0],
+ limit: NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT,
+ sortedBy: props.columns[0].id,
sortedDesc: true
};
this.handleLimitClick = this.handleLimitClick.bind(this);
+ this.updateSorted = this.updateSorted.bind(this);
}
- handleHeaderClick(ev, column) {
- ev.preventDefault();
- this.setState({
- sortedByColumn: column,
- sortedDesc: this.state.sortedByColumn.id === column.id
- ? !this.state.sortedDesc : true
- });
+ updateSorted(sortedBy, sortedDesc) {
+ this.setState({ sortedBy, sortedDesc });
}
handleLimitClick() {
- const limit = this.state.limit ? 0 : this.DEFAULT_LIMIT;
- this.setState({limit});
+ this.setState({
+ limit: this.state.limit ? 0 : NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT
+ });
}
render() {
- const { sortedByColumn, sortedDesc } = this.state;
+ const { sortedBy, sortedDesc } = this.state;
const { columns, matches = makeMap() } = this.props;
- let rows = this.props.rows;
- let notShown = 0;
- const limited = rows && this.state.limit > 0 && rows.length > this.state.limit;
const expanded = this.state.limit === 0;
- if (rows && limited) {
- const hasNotShownMatch = rows.filter((row, index) => index >= this.state.limit
- && matches.has(row.id)).length > 0;
- if (!hasNotShownMatch) {
- notShown = rows.length - this.DEFAULT_LIMIT;
+
+ // Stabilize the order of rows
+ let rows = sortBy(this.props.rows || [], row => row.id);
+ let notShown = 0;
+
+ // If there are rows that would be hidden behind 'show more', keep them
+ // expanded if any of them match the search query; otherwise hide them.
+ if (this.state.limit > 0 && rows.length > this.state.limit) {
+ const hasHiddenMatch = rows.slice(this.state.limit).some(row =>
+ columns.some(column => matches.has(genericTableEntryKey(row, column)))
+ );
+ if (!hasHiddenMatch) {
+ notShown = rows.length - NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT;
rows = rows.slice(0, this.state.limit);
}
}
+ const styles = getTableColumnsStyles(columns);
return (
-
- {columns.map((column) => {
- const onHeaderClick = (ev) => {
- this.handleHeaderClick(ev, column);
- };
- const isSorted = column.id === this.state.sortedByColumn.id;
- const isSortedDesc = isSorted && this.state.sortedDesc;
- const isSortedAsc = isSorted && !isSortedDesc;
- const style = Object.assign(columnStyle(column), {
- cursor: 'pointer',
- fontSize: '11px'
- });
- return (
- |
- {isSortedAsc
- && }
- {isSortedDesc
- && }
- {column.label}
- |
- );
- })}
-
+
- {sortedRows(rows, sortedByColumn, sortedDesc).map(row => (
+ {sortedRows(rows, columns, sortedBy, sortedDesc).map(row => (
- {columns.map((column) => {
+ {columns.map((column, index) => {
+ const match = matches.get(genericTableEntryKey(row, column));
const value = row.entries[column.id];
- const match = matches.get(column.id);
return (
|
+ className="node-details-generic-table-value truncate"
+ title={value} key={column.id} style={styles[index]}>
|
);
diff --git a/client/app/scripts/components/node-details/node-details-labels.js b/client/app/scripts/components/node-details/node-details-labels.js
index 2fd01a482..e25ec4ccd 100644
--- a/client/app/scripts/components/node-details/node-details-labels.js
+++ b/client/app/scripts/components/node-details/node-details-labels.js
@@ -2,8 +2,9 @@ import React from 'react';
import { Map as makeMap } from 'immutable';
import sortBy from 'lodash/sortBy';
-import MatchedText from '../matched-text';
+import { NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT } from '../../constants/limits';
import NodeDetailsControlButton from './node-details-control-button';
+import MatchedText from '../matched-text';
import ShowMore from '../show-more';
const Controls = controls => (
@@ -17,15 +18,14 @@ export default class NodeDetailsLabels extends React.Component {
constructor(props, context) {
super(props, context);
- this.DEFAULT_LIMIT = 5;
this.state = {
- limit: this.DEFAULT_LIMIT,
+ limit: NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT,
};
this.handleLimitClick = this.handleLimitClick.bind(this);
}
handleLimitClick() {
- const limit = this.state.limit ? 0 : this.DEFAULT_LIMIT;
+ const limit = this.state.limit ? 0 : NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT;
this.setState({limit});
}
@@ -39,7 +39,7 @@ export default class NodeDetailsLabels extends React.Component {
const hasNotShownMatch = rows.filter((row, index) => index >= this.state.limit
&& matches.has(row.id)).length > 0;
if (!hasNotShownMatch) {
- notShown = rows.length - this.DEFAULT_LIMIT;
+ notShown = rows.length - NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT;
rows = rows.slice(0, this.state.limit);
}
}
diff --git a/client/app/scripts/components/node-details/node-details-relatives.js b/client/app/scripts/components/node-details/node-details-relatives.js
index 26cef8a78..3004011fd 100644
--- a/client/app/scripts/components/node-details/node-details-relatives.js
+++ b/client/app/scripts/components/node-details/node-details-relatives.js
@@ -1,22 +1,22 @@
import React from 'react';
import { Map as makeMap } from 'immutable';
+import { NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT } from '../../constants/limits';
import NodeDetailsRelativesLink from './node-details-relatives-link';
export default class NodeDetailsRelatives extends React.Component {
constructor(props, context) {
super(props, context);
- this.DEFAULT_LIMIT = 5;
this.state = {
- limit: this.DEFAULT_LIMIT
+ limit: NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT
};
this.handleLimitClick = this.handleLimitClick.bind(this);
}
handleLimitClick(ev) {
ev.preventDefault();
- const limit = this.state.limit ? 0 : this.DEFAULT_LIMIT;
+ const limit = this.state.limit ? 0 : NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT;
this.setState({limit});
}
@@ -26,7 +26,7 @@ export default class NodeDetailsRelatives extends React.Component {
const limited = this.state.limit > 0 && relatives.length > this.state.limit;
const showLimitAction = limited || (this.state.limit === 0
- && relatives.length > this.DEFAULT_LIMIT);
+ && relatives.length > NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT);
const limitActionText = limited ? 'Show more' : 'Show less';
if (limited) {
relatives = relatives.slice(0, this.state.limit);
diff --git a/client/app/scripts/components/node-details/node-details-table-headers.js b/client/app/scripts/components/node-details/node-details-table-headers.js
new file mode 100644
index 000000000..9d72a2ce4
--- /dev/null
+++ b/client/app/scripts/components/node-details/node-details-table-headers.js
@@ -0,0 +1,55 @@
+import React from 'react';
+import { defaultSortDesc, getTableColumnsStyles } from '../../utils/node-details-utils';
+import { NODE_DETAILS_TABLE_CW, NODE_DETAILS_TABLE_XS_LABEL } from '../../constants/styles';
+
+
+export default class NodeDetailsTableHeaders extends React.Component {
+ handleClick(ev, headerId, currentSortedBy, currentSortedDesc) {
+ ev.preventDefault();
+ const header = this.props.headers.find(h => h.id === headerId);
+ const sortedBy = header.id;
+ const sortedDesc = sortedBy === currentSortedBy
+ ? !currentSortedDesc : defaultSortDesc(header);
+ this.props.onClick(sortedBy, sortedDesc);
+ }
+
+ render() {
+ const { headers, sortedBy, sortedDesc } = this.props;
+ const colStyles = getTableColumnsStyles(headers);
+ return (
+
+ {headers.map((header, index) => {
+ const headerClasses = ['node-details-table-header', 'truncate'];
+ const onClick = (ev) => {
+ this.handleClick(ev, header.id, sortedBy, sortedDesc);
+ };
+ // sort by first metric by default
+ const isSorted = header.id === sortedBy;
+ const isSortedDesc = isSorted && sortedDesc;
+ const isSortedAsc = isSorted && !isSortedDesc;
+
+ if (isSorted) {
+ headerClasses.push('node-details-table-header-sorted');
+ }
+
+ const style = colStyles[index];
+ const label =
+ (style.width === NODE_DETAILS_TABLE_CW.XS && NODE_DETAILS_TABLE_XS_LABEL[header.id]) ?
+ NODE_DETAILS_TABLE_XS_LABEL[header.id] : header.label;
+
+ return (
+ |
+ {isSortedAsc
+ && }
+ {isSortedDesc
+ && }
+ {label}
+ |
+ );
+ })}
+
+ );
+ }
+}
diff --git a/client/app/scripts/components/node-details/node-details-table.js b/client/app/scripts/components/node-details/node-details-table.js
index a7c820fc1..2cd8f9eba 100644
--- a/client/app/scripts/components/node-details/node-details-table.js
+++ b/client/app/scripts/components/node-details/node-details-table.js
@@ -2,59 +2,15 @@ import React from 'react';
import classNames from 'classnames';
import { find, get, union, sortBy, groupBy, concat } from 'lodash';
+import { NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT } from '../../constants/limits';
+
import ShowMore from '../show-more';
import NodeDetailsTableRow from './node-details-table-row';
+import NodeDetailsTableHeaders from './node-details-table-headers';
import { ipToPaddedString } from '../../utils/string-utils';
-
-
-function isNumber(data) {
- return data.dataType && data.dataType === 'number';
-}
-
-
-function isIP(data) {
- return data.dataType && data.dataType === 'ip';
-}
-
-
-const CW = {
- XS: '32px',
- S: '50px',
- M: '70px',
- L: '120px',
- XL: '140px',
- XXL: '170px',
-};
-
-
-const XS_LABEL = {
- count: '#',
- // TODO: consider changing the name of this field on the BE
- container: '#',
-};
-
-
-const COLUMN_WIDTHS = {
- count: CW.XS,
- container: CW.XS,
- docker_container_created: CW.XXL,
- docker_container_restart_count: CW.M,
- docker_container_state_human: CW.XXL,
- docker_container_uptime: '85px',
- docker_cpu_total_usage: CW.M,
- docker_memory_usage: CW.M,
- open_files_count: CW.M,
- pid: CW.S,
- port: CW.S,
- ppid: CW.S,
- process_cpu_usage_percent: CW.M,
- process_memory_usage_bytes: CW.M,
- threads: CW.M,
-
- // e.g. details panel > pods
- kubernetes_ip: CW.L,
- kubernetes_state: CW.M,
-};
+import {
+ isIP, isNumber, defaultSortDesc, getTableColumnsStyles
+} from '../../utils/node-details-utils';
function getDefaultSortedBy(columns, nodes) {
@@ -158,54 +114,27 @@ function getSortedNodes(nodes, sortedByHeader, sortedDesc) {
}
-function getColumnWidth(headers, h) {
- //
- // More beauty hacking, ports and counts can only get so big, free up WS for other longer
- // fields like IPs!
- //
- return COLUMN_WIDTHS[h.id];
-}
-
-
-function getColumnsStyles(headers) {
- return headers.map((h, i) => ({
- width: getColumnWidth(headers, h, i),
- textAlign: h.dataType === 'number' ? 'right' : 'left',
- }));
-}
-
-
-function defaultSortDesc(header) {
- return header && header.dataType === 'number';
-}
-
-
export default class NodeDetailsTable extends React.Component {
constructor(props, context) {
super(props, context);
- this.DEFAULT_LIMIT = 5;
this.state = {
- limit: props.limit || this.DEFAULT_LIMIT,
+ limit: props.limit || NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT,
sortedDesc: this.props.sortedDesc,
sortedBy: this.props.sortedBy
};
this.handleLimitClick = this.handleLimitClick.bind(this);
+ this.updateSorted = this.updateSorted.bind(this);
}
- handleHeaderClick(ev, headerId, currentSortedBy, currentSortedDesc) {
- ev.preventDefault();
- const header = this.getColumnHeaders().find(h => h.id === headerId);
- const sortedBy = header.id;
- const sortedDesc = header.id === currentSortedBy
- ? !currentSortedDesc : defaultSortDesc(header);
- this.setState({sortedBy, sortedDesc});
+ updateSorted(sortedBy, sortedDesc) {
+ this.setState({ sortedBy, sortedDesc });
this.props.onSortChange(sortedBy, sortedDesc);
}
handleLimitClick() {
- const limit = this.state.limit ? 0 : this.DEFAULT_LIMIT;
- this.setState({limit});
+ const limit = this.state.limit ? 0 : NODE_DETAILS_DATA_ROWS_DEFAULT_LIMIT;
+ this.setState({ limit });
}
getColumnHeaders() {
@@ -213,60 +142,13 @@ export default class NodeDetailsTable extends React.Component {
return [{id: 'label', label: this.props.label}].concat(columns);
}
- renderHeaders(sortedBy, sortedDesc) {
- if (!this.props.nodes || this.props.nodes.length === 0) {
- return null;
- }
-
- const headers = this.getColumnHeaders();
- const colStyles = getColumnsStyles(headers);
-
- return (
-
- {headers.map((header, i) => {
- const headerClasses = ['node-details-table-header', 'truncate'];
- const onHeaderClick = (ev) => {
- this.handleHeaderClick(ev, header.id, sortedBy, sortedDesc);
- };
- // sort by first metric by default
- const isSorted = header.id === sortedBy;
- const isSortedDesc = isSorted && sortedDesc;
- const isSortedAsc = isSorted && !isSortedDesc;
-
- if (isSorted) {
- headerClasses.push('node-details-table-header-sorted');
- }
-
- const style = colStyles[i];
- const label = (style.width === CW.XS && XS_LABEL[header.id]) ?
- XS_LABEL[header.id] :
- header.label;
-
- return (
- |
- {isSortedAsc
- && }
- {isSortedDesc
- && }
- {label}
- |
- );
- })}
-
- );
- }
-
render() {
const { nodeIdKey, columns, topologyId, onClickRow, onMouseEnter, onMouseLeave,
onMouseEnterRow, onMouseLeaveRow } = this.props;
const sortedBy = this.state.sortedBy || getDefaultSortedBy(columns, this.props.nodes);
const sortedByHeader = this.getColumnHeaders().find(h => h.id === sortedBy);
- const sortedDesc = this.state.sortedDesc !== null ?
- this.state.sortedDesc :
- defaultSortDesc(sortedByHeader);
+ const sortedDesc = this.state.sortedDesc || defaultSortDesc(sortedByHeader);
let nodes = getSortedNodes(this.props.nodes, sortedByHeader, sortedDesc);
const limited = nodes && this.state.limit > 0 && nodes.length > this.state.limit;
@@ -277,13 +159,20 @@ export default class NodeDetailsTable extends React.Component {
}
const className = classNames('node-details-table-wrapper-wrapper', this.props.className);
+ const headers = this.getColumnHeaders();
+ const styles = getTableColumnsStyles(headers);
return (
- {this.renderHeaders(sortedBy, sortedDesc)}
+ {this.props.nodes && this.props.nodes.length > 0 && }
pods
+ kubernetes_ip: NODE_DETAILS_TABLE_CW.XL,
+ kubernetes_state: NODE_DETAILS_TABLE_CW.M,
+
+ // weave connections
+ weave_connection_connection: NODE_DETAILS_TABLE_CW.XXL,
+ weave_connection_state: NODE_DETAILS_TABLE_CW.L,
+ weave_connection_info: NODE_DETAILS_TABLE_CW.XL,
+};
+
+export const NODE_DETAILS_TABLE_XS_LABEL = {
+ count: '#',
+ // TODO: consider changing the name of this field on the BE
+ container: '#',
+};
diff --git a/client/app/scripts/utils/node-details-utils.js b/client/app/scripts/utils/node-details-utils.js
new file mode 100644
index 000000000..7d9c3d2aa
--- /dev/null
+++ b/client/app/scripts/utils/node-details-utils.js
@@ -0,0 +1,36 @@
+import { NODE_DETAILS_TABLE_COLUMN_WIDTHS } from '../constants/styles';
+
+export function isGenericTable(table) {
+ return (table.type || (table.get && table.get('type'))) === 'multicolumn-table';
+}
+
+export function isPropertyList(table) {
+ return (table.type || (table.get && table.get('type'))) === 'property-list';
+}
+
+export function isNumber(data) {
+ return data.dataType && data.dataType === 'number';
+}
+
+export function isIP(data) {
+ return data.dataType && data.dataType === 'ip';
+}
+
+export function genericTableEntryKey(row, column) {
+ const columnId = column.id || column.get('id');
+ const rowId = row.id || row.get('id');
+ return `${rowId}_${columnId}`;
+}
+
+export function defaultSortDesc(header) {
+ return header && isNumber(header);
+}
+
+export function getTableColumnsStyles(headers) {
+ return headers.map(header => ({
+ // More beauty hacking, ports and counts can only get
+ // so big, free up WS for other longer fields like IPs!
+ width: NODE_DETAILS_TABLE_COLUMN_WIDTHS[header.id],
+ textAlign: isNumber(header) ? 'right' : 'left'
+ }));
+}
diff --git a/client/app/scripts/utils/search-utils.js b/client/app/scripts/utils/search-utils.js
index c297ae96a..2ea844c23 100644
--- a/client/app/scripts/utils/search-utils.js
+++ b/client/app/scripts/utils/search-utils.js
@@ -1,6 +1,7 @@
import { Map as makeMap, Set as makeSet, List as makeList } from 'immutable';
import { escapeRegExp } from 'lodash';
+import { isGenericTable, isPropertyList, genericTableEntryKey } from './node-details-utils';
import { slugify } from './string-utils';
// topolevel search fields
@@ -148,20 +149,26 @@ export function searchTopology(nodes, { prefix, query, metric, comp, value }) {
});
}
- // tables (envvars and labels)
- const tables = node.get('tables');
- if (tables) {
- tables.forEach((table) => {
- if (table.get('rows')) {
- table.get('rows').forEach((field) => {
- const entries = field.get('entries');
- const keyPath = [nodeId, 'tables', field.get('id')];
- nodeMatches = findNodeMatch(nodeMatches, keyPath, entries.get('value'),
- query, prefix, entries.get('label'));
- });
- }
+ // property lists
+ (node.get('tables') || []).filter(isPropertyList).forEach((propertyList) => {
+ (propertyList.get('rows') || []).forEach((row) => {
+ const entries = row.get('entries');
+ const keyPath = [nodeId, 'labels', row.get('id')];
+ nodeMatches = findNodeMatch(nodeMatches, keyPath, entries.get('value'),
+ query, prefix, entries.get('label'));
});
- }
+ });
+
+ // generic tables
+ (node.get('tables') || []).filter(isGenericTable).forEach((table) => {
+ (table.get('rows') || []).forEach((row) => {
+ table.get('columns').forEach((column) => {
+ const val = row.get('entries').get(column.get('id'));
+ const keyPath = [nodeId, 'tables', genericTableEntryKey(row, column)];
+ nodeMatches = findNodeMatch(nodeMatches, keyPath, val, query);
+ });
+ });
+ });
} else if (metric) {
const metrics = node.get('metrics');
if (metrics) {
diff --git a/client/app/styles/main.less b/client/app/styles/main.less
index e3e8d75cb..801ad53db 100644
--- a/client/app/styles/main.less
+++ b/client/app/styles/main.less
@@ -897,6 +897,17 @@ h2 {
}
}
+ &-generic-table {
+ width: 100%;
+
+ tr {
+ display: flex;
+ th, td {
+ padding: 0 5px;
+ }
+ }
+ }
+
&-table {
width: 100%;
border-spacing: 0;
diff --git a/probe/overlay/weave.go b/probe/overlay/weave.go
index 2fb3aea18..fde8ccf86 100644
--- a/probe/overlay/weave.go
+++ b/probe/overlay/weave.go
@@ -46,6 +46,9 @@ const (
WeavePluginTableID = "weave_plugin_table"
WeavePluginStatus = "weave_plugin_status"
WeavePluginDriver = "weave_plugin_driver"
+ WeaveConnectionsConnection = "weave_connection_connection"
+ WeaveConnectionsState = "weave_connection_state"
+ WeaveConnectionsInfo = "weave_connection_info"
WeaveConnectionsTablePrefix = "weave_connections_table_"
WeaveConnectionsMulticolumnTablePrefix = "weave_connections_multicolumn_table_"
)
@@ -115,26 +118,25 @@ var (
},
WeaveConnectionsTablePrefix: {
ID: WeaveConnectionsTablePrefix,
- Label: "Connections",
+ Label: "Connections (old)",
Type: report.PropertyListType,
Prefix: WeaveConnectionsTablePrefix,
},
WeaveConnectionsMulticolumnTablePrefix: {
ID: WeaveConnectionsMulticolumnTablePrefix,
- Label: "Connections (new)",
Type: report.MulticolumnTableType,
Prefix: WeaveConnectionsMulticolumnTablePrefix,
Columns: []report.Column{
report.Column{
- ID: "ip",
- Label: "IP",
+ ID: WeaveConnectionsConnection,
+ Label: "Connections",
},
report.Column{
- ID: "state",
+ ID: WeaveConnectionsState,
Label: "State",
},
report.Column{
- ID: "info",
+ ID: WeaveConnectionsInfo,
Label: "Info",
},
},
@@ -488,9 +490,9 @@ func getConnectionsTable(router weave.Router) []report.Row {
table = append(table, report.Row{
ID: conn.Address,
Entries: map[string]string{
- "ip": fmt.Sprintf("%s %s", arrow, conn.Address),
- "state": conn.State,
- "info": conn.Info,
+ WeaveConnectionsConnection: fmt.Sprintf("%s %s", arrow, conn.Address),
+ WeaveConnectionsState: conn.State,
+ WeaveConnectionsInfo: conn.Info,
},
})
}