mirror of
https://github.com/skooner-k8s/skooner.git
synced 2026-08-24 04:16:18 +00:00
Refactoring. More chart clean up. Improving sorting by pod resources.
This commit is contained in:
@@ -34,22 +34,40 @@ export default class NodesPanel extends Base {
|
||||
<Sorter field={getReadyStatus} sort={sort}>Ready</Sorter>
|
||||
</th>
|
||||
<th>
|
||||
<Sorter field={this.sortByCpuUsage} sort={sort}>Cpu</Sorter>
|
||||
<Sorter field={this.sortByCpuUsage} sort={sort}>
|
||||
Cpu
|
||||
<div className='smallText'>Actual</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
<th className='optional_xsmall'>
|
||||
<Sorter field={this.sortByCpuRequest} sort={sort}>Requests</Sorter>
|
||||
<Sorter field={this.sortByCpuRequest} sort={sort}>
|
||||
Cpu
|
||||
<div className='smallText'>Requests</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
<th className='optional_xsmall'>
|
||||
<Sorter field={this.sortByCpuLimit} sort={sort}>Limits</Sorter>
|
||||
<Sorter field={this.sortByCpuLimit} sort={sort}>
|
||||
Cpu
|
||||
<div className='smallText'>Limits</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
<th>
|
||||
<Sorter field={this.sortByRamUsage} sort={sort}>Ram</Sorter>
|
||||
<Sorter field={this.sortByRamUsage} sort={sort}>
|
||||
Ram
|
||||
<div className='smallText'>Actual</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
<th className='optional_xsmall'>
|
||||
<Sorter field={this.sortByRamRequest} sort={sort}>Requests</Sorter>
|
||||
<Sorter field={this.sortByRamRequest} sort={sort}>
|
||||
Ram
|
||||
<div className='smallText'>Requests</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
<th className='optional_xsmall'>
|
||||
<Sorter field={this.sortByRamLimit} sort={sort}>Limits</Sorter>
|
||||
<Sorter field={this.sortByRamLimit} sort={sort}>
|
||||
Ram
|
||||
<div className='smallText'>Limits</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -57,7 +75,7 @@ export default class NodesPanel extends Base {
|
||||
<TableBody items={items} filter={filter} sort={sort} colSpan='11' row={x => (
|
||||
<tr key={x.metadata.uid}>
|
||||
<MetadataColumns item={x} href={`#!node/${x.metadata.name}`} />
|
||||
<td className='podsPanel_label optional_medium'>{objectMap(x.metadata.labels)}</td>
|
||||
<td className='smallText optional_medium'>{objectMap(x.metadata.labels)}</td>
|
||||
<td className='optional_small'>{getReadyStatus(x)}</td>
|
||||
<td>{getPercentDisplay(x, metrics, 'cpu')}</td>
|
||||
<td className='optional_xsmall'>{getResourcePercentDisplay(x, pods, 'cpu', 'requests')}</td>
|
||||
@@ -92,7 +110,7 @@ function getResourcePercentDisplay(node, pods, resource, type) {
|
||||
|
||||
function percent(node, used, resource) {
|
||||
if (used == null) return <LoadingEllipsis />;
|
||||
if (!used) return <span className='podsPanel_label'>-</span>;
|
||||
if (!used) return <span className='smallText'>-</span>;
|
||||
|
||||
const unparser = resource === 'cpu' ? unparseCpu : unparseRam;
|
||||
const result = unparser(used);
|
||||
@@ -103,8 +121,8 @@ function percent(node, used, resource) {
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{displayPercent}<span className='podsPanel_label'>%</span>
|
||||
<div className='podsPanel_label'>{result.value}{result.unit}</div>
|
||||
{displayPercent}<span className='smallText'>%</span>
|
||||
<div className='smallText'>{result.value}{result.unit}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import './podsPanel.scss';
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import Base from './base';
|
||||
@@ -13,17 +12,17 @@ export default class PodsPanel extends Base {
|
||||
super(props);
|
||||
|
||||
this.sortByCpuUsage = x => getPodUsage(x, this.props.metrics, 'cpu');
|
||||
this.sortByCpuRequest = x => getPodResourcePercent(x, this.props.metrics, 'cpu', 'requests');
|
||||
this.sortByCpuLimit = x => getPodResourcePercent(x, this.props.metrics, 'cpu', 'limits');
|
||||
this.sortByCpuRequest = x => sortBy(x, this.props.metrics, 'cpu', 'requests');
|
||||
this.sortByCpuLimit = x => sortBy(x, this.props.metrics, 'cpu', 'limits');
|
||||
|
||||
this.sortByRamUsage = x => getPodUsage(x, this.props.metrics, 'memory');
|
||||
this.sortByRamRequest = x => getPodResourcePercent(x, this.props.metrics, 'memory', 'requests');
|
||||
this.sortByRamLimit = x => getPodResourcePercent(x, this.props.metrics, 'memory', 'limits');
|
||||
this.sortByRamRequest = x => sortBy(x, this.props.metrics, 'memory', 'requests');
|
||||
this.sortByRamLimit = x => sortBy(x, this.props.metrics, 'memory', 'limits');
|
||||
}
|
||||
|
||||
render() {
|
||||
const {items, metrics, sort, filter, skipNamespace, skipNodeName} = this.props;
|
||||
const col = 8 + !skipNamespace + !skipNodeName; // TODO: fix me
|
||||
const {items, metrics, sort, filter, skipNamespace} = this.props;
|
||||
const col = 10 + !skipNamespace;
|
||||
|
||||
return (
|
||||
<div className='contentPanel'>
|
||||
@@ -31,30 +30,42 @@ export default class PodsPanel extends Base {
|
||||
<thead>
|
||||
<tr>
|
||||
<MetadataHeaders sort={sort} includeNamespace={!skipNamespace} />
|
||||
{/*
|
||||
TODO: remove this (and all callers too)
|
||||
{!skipNodeName && (
|
||||
<th className='optional_small'><Sorter field='spec.nodeName' sort={sort}>Node</Sorter></th>
|
||||
)}
|
||||
*/}
|
||||
<th className='optional_medium'><Sorter field={getRestartCount} sort={sort}>Restarts</Sorter></th>
|
||||
<th>
|
||||
<Sorter field={this.sortByCpuUsage} sort={sort}>Cpu</Sorter>
|
||||
<Sorter field={this.sortByCpuUsage} sort={sort}>
|
||||
Cpu
|
||||
<div className='smallText'>Actual</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
<th className='optional_xsmall'>
|
||||
<Sorter field={this.sortByCpuRequest} sort={sort}>Request</Sorter>
|
||||
<Sorter field={this.sortByCpuRequest} sort={sort}>
|
||||
Cpu
|
||||
<div className='smallText'>Request</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
<th className='optional_xsmall'>
|
||||
<Sorter field={this.sortByCpuLimit} sort={sort}>Limit</Sorter>
|
||||
<Sorter field={this.sortByCpuLimit} sort={sort}>
|
||||
Cpu
|
||||
<div className='smallText'>Limit</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
<th>
|
||||
<Sorter field={this.sortByRamUsage} sort={sort}>Ram</Sorter>
|
||||
<Sorter field={this.sortByRamUsage} sort={sort}>
|
||||
Ram
|
||||
<div className='smallText'>Actual</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
<th className='optional_xsmall'>
|
||||
<Sorter field={this.sortByRamRequest} sort={sort}>Request</Sorter>
|
||||
<Sorter field={this.sortByRamRequest} sort={sort}>
|
||||
Ram
|
||||
<div className='smallText'>Request</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
<th className='optional_xsmall'>
|
||||
<Sorter field={this.sortByRamLimit} sort={sort}>Limit</Sorter>
|
||||
<Sorter field={this.sortByRamLimit} sort={sort}>
|
||||
Ram
|
||||
<div className='smallText'>Limit</div>
|
||||
</Sorter>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -67,7 +78,6 @@ export default class PodsPanel extends Base {
|
||||
includeNamespace={!skipNamespace}
|
||||
href={`#!pod/${x.metadata.namespace}/${x.metadata.name}`}
|
||||
/>
|
||||
{/* {!skipNodeName && <td className='optional_small'>{x.spec.nodeName}</td>} */}
|
||||
<td className='optional_medium'>{getRestartCount(x)}</td>
|
||||
{getChart(x, metrics, 'cpu')}
|
||||
{getChart(x, metrics, 'memory')}
|
||||
@@ -79,6 +89,11 @@ export default class PodsPanel extends Base {
|
||||
}
|
||||
}
|
||||
|
||||
function sortBy(item, metrics, resource, type) {
|
||||
const result = getPodResourcePercent(item, metrics, resource, type);
|
||||
return Number.isFinite(result) ? result : -1;
|
||||
}
|
||||
|
||||
function getRestartCount({status}) {
|
||||
return _.sumBy(status.containerStatuses, 'restartCount');
|
||||
}
|
||||
@@ -104,16 +119,16 @@ function getRawDisplay(item, metrics, actual, resource) {
|
||||
return (
|
||||
<td>
|
||||
{actualResult.value}
|
||||
<span className='podsPanel_label'>{actualResult.unit}</span>
|
||||
<span className='smallText'>{actualResult.unit}</span>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
function getPercentDisplay(item, metrics, actual, resource, type) {
|
||||
if (!item || !metrics) return <td><LoadingEllipsis /></td>;
|
||||
if (!item || !metrics) return <td className='optional_xsmall'><LoadingEllipsis /></td>;
|
||||
|
||||
const request = getPodResourceValue(item, resource, type);
|
||||
if (!request) return <td className='podsPanel_label'>-</td>;
|
||||
if (!request) return <td className='smallText optional_xsmall'>-</td>;
|
||||
|
||||
const unparser = resource === 'cpu' ? unparseCpu : unparseRam;
|
||||
const result = unparser(request);
|
||||
@@ -122,8 +137,8 @@ function getPercentDisplay(item, metrics, actual, resource, type) {
|
||||
|
||||
return (
|
||||
<td className={className}>
|
||||
{percent}<span className='podsPanel_label'>%</span>
|
||||
<div className='podsPanel_label'>{result.value}{result.unit}</div>
|
||||
{percent}<span className='smallText'>%</span>
|
||||
<div className='smallText'>{result.value}{result.unit}</div>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
@import '../scss/settings.scss';
|
||||
|
||||
.podsPanel_label {
|
||||
margin-left: 2px;
|
||||
color: $color-light;
|
||||
font-size: $font-size-small;
|
||||
}
|
||||
@@ -75,6 +75,11 @@ button.titleBar_hamburger {
|
||||
fill: $color-white;
|
||||
}
|
||||
|
||||
.smallText {
|
||||
color: $color-light;
|
||||
font-size: $font-size-small;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $media-medium) {
|
||||
.optional_medium {
|
||||
display: none;
|
||||
|
||||
@@ -21,4 +21,4 @@ $font-size-xlarge: 100px;
|
||||
|
||||
$media-xsmall: 700px;
|
||||
$media-small: 812px;
|
||||
$media-medium: 1024px;
|
||||
$media-medium: 1200px;
|
||||
@@ -33,19 +33,14 @@ export function getNodeUsagePercent(node, metrics, resource) {
|
||||
}
|
||||
|
||||
export function getNodeResourcesAvailable(node, resource) {
|
||||
if (!node) return null;
|
||||
return resource === 'cpu' ? parseCpu(node.status.capacity.cpu) : parseRam(node.status.capacity.memory);
|
||||
return node ? parse(resource, node.status.capacity) : null;
|
||||
}
|
||||
|
||||
export function getNodeUsage(node, metrics, resource) {
|
||||
if (!node || !metrics) return null;
|
||||
|
||||
const result = metrics[node.metadata.name] || {};
|
||||
if (!result) return null;
|
||||
|
||||
const value = resource === 'cpu' ? result.usage.cpu : result.usage.memory;
|
||||
const parser = resource === 'cpu' ? parseCpu : parseRam;
|
||||
return parser(value);
|
||||
const result = metrics[node.metadata.name];
|
||||
return result ? parse(resource, result.usage) : null;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,14 +55,16 @@ export function getPodUsage(pod, metrics, resource) {
|
||||
if (!pod || !metrics) return null;
|
||||
|
||||
const metric = metrics[pod.metadata.name] || {};
|
||||
const parser = resource === 'cpu' ? parseCpu : parseRam;
|
||||
return _.sumBy(metric.containers, x => parser(x.usage[resource]));
|
||||
return _.sumBy(metric.containers, x => parse(resource, x.usage));
|
||||
}
|
||||
|
||||
export function getPodResourceValue(pod, resource, type) {
|
||||
const parser = resource === 'cpu' ? parseCpu : parseRam;
|
||||
|
||||
return _(pod.spec.containers)
|
||||
.filter(x => x.resources && x.resources[type])
|
||||
.sumBy(x => parser(x.resources[type][resource]));
|
||||
.sumBy(x => parse(resource, x.resources[type]));
|
||||
}
|
||||
|
||||
function parse(resource, target) {
|
||||
const parser = resource === 'cpu' ? parseCpu : parseRam;
|
||||
return parser(target[resource]);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,6 @@ export default class Namespace extends Base {
|
||||
sort={podsSort}
|
||||
metrics={filteredPodMetrics}
|
||||
skipNamespace={true}
|
||||
skipNodeName={false}
|
||||
/>
|
||||
|
||||
<div className='contentPanel_header'>Events</div>
|
||||
|
||||
@@ -112,7 +112,6 @@ export default class Node extends Base {
|
||||
items={filteredPods}
|
||||
sort={podsSort}
|
||||
metrics={filteredPodMetrics}
|
||||
skipNodeName={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user