diff --git a/client/src/views/namespace.js b/client/src/views/namespace.js
index 5334e73..52cd405 100644
--- a/client/src/views/namespace.js
+++ b/client/src/views/namespace.js
@@ -6,23 +6,38 @@ import Loading from '../components/loading';
import Field from '../components/field';
import MetadataFields from '../components/metadataFields';
import DeleteButton from '../components/deleteButton';
+import PodsPanel from '../components/podsPanel';
import EventsPanel from '../components/eventsPanel';
+import {defaultSortInfo} from '../components/sorter';
+import ChartsContainer from '../components/chartsContainer';
+import PodStatusChart from '../components/podStatusChart';
+import PodCpuChart from '../components/podCpuChart';
+import PodRamChart from '../components/podRamChart';
+import getMetrics from '../utils/metricsHelpers';
const service = api.namespace;
export default class Namespace extends Base {
+ state = {
+ podsSort: defaultSortInfo(x => this.setState({podsSort: x})),
+ };
+
componentDidMount() {
const {namespace} = this.props;
this.registerApi({
item: service.get(namespace, item => this.setState({item})),
events: api.event.list(namespace, events => this.setState({events})),
+ pods: api.pod.list(namespace, pods => this.setState({pods})),
+ podMetrics: api.metrics.pods(namespace, podMetrics => this.setState({podMetrics})),
});
}
render() {
const {namespace} = this.props;
- const {item, events} = this.state || {};
+ const {item, events, pods, podMetrics, podsSort} = this.state;
+
+ const filteredPodMetrics = getMetrics(pods, podMetrics);
return (
@@ -34,6 +49,12 @@ export default class Namespace extends Base {
>
+
+
+
+
+
+
{!item ?
: (
@@ -43,6 +64,15 @@ export default class Namespace extends Base {
)}
+
Pods
+
+
Events
diff --git a/client/src/views/node.js b/client/src/views/node.js
index d503b09..921491c 100644
--- a/client/src/views/node.js
+++ b/client/src/views/node.js
@@ -3,17 +3,20 @@ import React from 'react';
import moment from 'moment';
import api from '../services/api';
import Base from '../components/base';
-import Chart from '../components/chart';
import ItemHeader from '../components/itemHeader';
import Loading from '../components/loading';
import LoadingChart from '../components/loadingChart';
import MetadataFields from '../components/metadataFields';
import PodsPanel from '../components/podsPanel';
import {defaultSortInfo} from '../components/sorter';
-import {parseCpu, parseRam, TO_GB, TO_ONE_M_CPU} from '../utils/unitHelpers';
-import PodStatusChart from '../components/podStatusChart';
import Field from '../components/field';
import ChartsContainer from '../components/chartsContainer';
+import NodeCpuChart from '../components/nodeCpuChart';
+import NodeRamChart from '../components/nodeRamChart';
+import PodStatusChart from '../components/podStatusChart';
+import PodCpuChart from '../components/podCpuChart';
+import PodRamChart from '../components/podRamChart';
+import getMetrics from '../utils/metricsHelpers';
export default class Node extends Base {
state = {
@@ -25,12 +28,9 @@ export default class Node extends Base {
this.registerApi({
item: api.node.get(name, item => this.setState({item})),
- pods: api.pod.list(null, pods => this.setState({pods})),
metrics: api.metrics.node(name, metrics => this.setState({metrics})),
- podMetrics: api.metrics.pods(null, (x) => {
- const podMetrics = _.keyBy(x, 'metadata.name');
- this.setState({podMetrics});
- }),
+ pods: api.pod.list(null, pods => this.setState({pods})),
+ podMetrics: api.metrics.pods(null, podMetrics => this.setState({podMetrics})),
});
}
@@ -39,15 +39,29 @@ export default class Node extends Base {
const {item, pods, metrics, podMetrics, podsSort} = this.state;
const filteredPods = pods && pods.filter(x => x.spec.nodeName === name);
+ const filteredPodMetrics = getMetrics(filteredPods, podMetrics);
return (
+
+
+ {item ? (
+
{getUpTime(item)}
+ ) : (
+
+ )}
+
Days Up
+
+
+
+
+
-
-
+
+
@@ -97,7 +111,7 @@ export default class Node extends Base {
@@ -105,44 +119,12 @@ export default class Node extends Base {
}
}
-function CpuChart({item, metrics}) {
- const usedCpu = metrics && parseCpu(metrics.usage.cpu) / TO_ONE_M_CPU;
- const availableCpu = item && parseCpu(item.status.capacity.cpu) / TO_ONE_M_CPU;
+function getUpTime({status}) {
+ const ready = status.conditions.find(y => y.type === 'Ready');
+ if (!ready) return 'N/A';
- return (
-
- {item && metrics ? (
-
- ) : (
-
- )}
-
Cpu Used
-
- );
-}
-
-function RamChart({item, metrics}) {
- const usedRam = metrics && parseRam(metrics.usage.memory) / TO_GB;
- const availableRam = item && parseRam(item.status.capacity.memory) / TO_GB;
-
- return (
-
- {item && metrics ? (
-
- ) : (
-
- )}
-
Ram Used
-
- );
+ const last = moment(ready.lastTransitionTime);
+ const diff = moment().diff(last);
+ const hours = moment.duration(diff).asDays();
+ return _.round(hours);
}
diff --git a/client/src/views/nodes.js b/client/src/views/nodes.js
index 1559d15..5c92edb 100644
--- a/client/src/views/nodes.js
+++ b/client/src/views/nodes.js
@@ -1,4 +1,3 @@
-import _ from 'lodash';
import React from 'react';
import Base from '../components/base';
import ChartsContainer from '../components/chartsContainer';
@@ -8,9 +7,9 @@ import NodeStatusChart from '../components/nodeStatusChart';
import api from '../services/api';
import test from '../utils/filterHelper';
import NodesPanel from '../components/nodesPanel';
-import Chart from '../components/chart';
-import LoadingChart from '../components/loadingChart';
-import {parseCpu, parseRam, TO_GB, TO_ONE_CPU} from '../utils/unitHelpers';
+import NodeCpuChart from '../components/nodeCpuChart';
+import NodeRamChart from '../components/nodeRamChart';
+import getMetrics from '../utils/metricsHelpers';
export default class Nodes extends Base {
state = {
@@ -34,7 +33,7 @@ export default class Nodes extends Base {
return test(filter, x.metadata.name, ...searchableLabels);
});
- const filteredMetrics = getNodeMetrics(filtered, metrics);
+ const filteredMetrics = getMetrics(filtered, metrics);
return (
@@ -46,8 +45,8 @@ export default class Nodes extends Base {
-
-
+
+
- {totals ? (
-
- ) : (
-
- )}
- Cores
- Used vs Available
-
- );
-}
-
-function RamTotalsChart({items, metrics}) {
- const totals = getNodeRamTotals(items, metrics);
- return (
-
- {totals ? (
-
- ) : (
-
- )}
-
Ram
-
Used vs Available
-
- );
-}
-
-function getNodeMetrics(nodes, metrics) {
- if (!nodes || !metrics) return null;
-
- const names = _.map(nodes, x => x.metadata.name);
- const filteredMetrics = metrics.filter(x => names.includes(x.metadata.name));
-
- return _.keyBy(filteredMetrics, 'metadata.name');
-}
-
-function getNodeCpuTotals(items, metrics) {
- if (!items || !metrics) return null;
-
- const metricValues = Object.values(metrics);
- const used = _.sumBy(metricValues, x => parseCpu(x.usage.cpu)) / TO_ONE_CPU;
- const available = _.sumBy(items, x => parseCpu(x.status.capacity.cpu)) / TO_ONE_CPU;
-
- return {used, available};
-}
-
-function getNodeRamTotals(items, metrics) {
- if (!items || !metrics) return null;
-
- const metricValues = Object.values(metrics);
- const used = _.sumBy(metricValues, x => parseRam(x.usage.memory)) / TO_GB;
- const available = _.sumBy(items, x => parseRam(x.status.capacity.memory)) / TO_GB;
-
- return {used, available};
-}
diff --git a/client/src/views/pod.js b/client/src/views/pod.js
index db88b62..a2c940a 100644
--- a/client/src/views/pod.js
+++ b/client/src/views/pod.js
@@ -15,9 +15,9 @@ import EventsPanel from '../components/eventsPanel';
import ContainersPanel from '../components/containersPanel';
import {objectMap} from '../components/listViewHelpers';
import {filterByOwner} from '../utils/filterHelper';
-import getPodMetrics from '../utils/metricsHelpers';
-import CpuChart from '../components/cpuChart';
-import RamChart from '../components/ramChart';
+import getMetrics from '../utils/metricsHelpers';
+import PodCpuChart from '../components/podCpuChart';
+import PodRamChart from '../components/podRamChart';
import ChartsContainer from '../components/chartsContainer';
const service = api.pod;
@@ -39,7 +39,7 @@ export default class Pod extends Base {
const errors = getErrors(item);
const filteredEvents = filterByOwner(events, item);
- const filteredMetrics = getPodMetrics(item && [item], metrics && [metrics]);
+ const filteredMetrics = getMetrics(item && [item], metrics && [metrics]);
return (
@@ -69,8 +69,8 @@ export default class Pod extends Base {
{errors && !!errors.length &&
}
-
-
+
+
diff --git a/client/src/views/pods.js b/client/src/views/pods.js
index e19a6ef..e2a848c 100644
--- a/client/src/views/pods.js
+++ b/client/src/views/pods.js
@@ -3,12 +3,12 @@ import Base from '../components/base';
import Filter from '../components/filter';
import api from '../services/api';
import test from '../utils/filterHelper';
-import CpuChart from '../components/cpuChart';
-import RamChart from '../components/ramChart';
+import PodCpuChart from '../components/podCpuChart';
+import PodRamChart from '../components/podRamChart';
import PodsPanel from '../components/podsPanel';
import PodStatusChart from '../components/podStatusChart';
import {defaultSortInfo} from '../components/sorter';
-import getPodMetrics from '../utils/metricsHelpers';
+import getMetrics from '../utils/metricsHelpers';
import ChartsContainer from '../components/chartsContainer';
export default class Pods extends Base {
@@ -31,7 +31,7 @@ export default class Pods extends Base {
render() {
const {items, metrics, namespace, sort, filter} = this.state;
const filtered = items && items.filter(x => test(filter, x.metadata.name));
- const filteredMetrics = getPodMetrics(filtered, metrics);
+ const filteredMetrics = getMetrics(filtered, metrics);
return (
@@ -44,8 +44,8 @@ export default class Pods extends Base {
-
-
+
+
@@ -70,8 +70,8 @@ export default class ReplicaSet extends Base {
-
-
+
+
diff --git a/client/src/views/statefulSet.js b/client/src/views/statefulSet.js
index 97b176e..4e77b9f 100644
--- a/client/src/views/statefulSet.js
+++ b/client/src/views/statefulSet.js
@@ -9,9 +9,9 @@ import ScaleButton from '../components/scaleButton';
import SaveButton from '../components/saveButton';
import DeleteButton from '../components/deleteButton';
import EventsPanel from '../components/eventsPanel';
-import RamChart from '../components/ramChart';
-import CpuChart from '../components/cpuChart';
-import getPodMetrics from '../utils/metricsHelpers';
+import PodRamChart from '../components/podRamChart';
+import PodCpuChart from '../components/podCpuChart';
+import getMetrics from '../utils/metricsHelpers';
import {filterByOwner} from '../utils/filterHelper';
import ContainersPanel from '../components/containersPanel';
import {defaultSortInfo} from '../components/sorter';
@@ -43,7 +43,7 @@ export default class StatefulSet extends Base {
const filteredPods = filterByOwner(pods, item);
const filteredEvents = filterByOwner(events, item);
- const filteredMetrics = getPodMetrics(filteredPods, metrics);
+ const filteredMetrics = getMetrics(filteredPods, metrics);
return (
@@ -68,8 +68,8 @@ export default class StatefulSet extends Base {
-
-
+
+
diff --git a/client/src/views/workloads.js b/client/src/views/workloads.js
index 14b2473..47e20f8 100644
--- a/client/src/views/workloads.js
+++ b/client/src/views/workloads.js
@@ -145,9 +145,13 @@ function getExpectedCount({spec, status}) {
}
function filterControllers(filter, items) {
- const results = items.flat();
+ const results = items
+ .flat()
+ .filter(x => !!x);
- if (results.length && items.some(x => !x)) return null;
+ // If there are no results yet but some of the workload types are still
+ // loading, return "null" so we display the "loading" control
+ if (!results.length && items.some(x => !x)) return null;
return _(results)
.flatten()