mirror of https://github.com/rancher/ui.git
commit
9d2e657a5f
|
|
@ -10,6 +10,7 @@ import { resolve } from 'rsvp';
|
||||||
import C from 'ui/utils/constants';
|
import C from 'ui/utils/constants';
|
||||||
import { isEmpty } from '@ember/utils';
|
import { isEmpty } from '@ember/utils';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
const TRUE = 'True';
|
||||||
|
|
||||||
export default Resource.extend(Grafana, ResourceUsage, {
|
export default Resource.extend(Grafana, ResourceUsage, {
|
||||||
globalStore: service(),
|
globalStore: service(),
|
||||||
|
|
@ -274,11 +275,46 @@ export default Resource.extend(Grafana, ResourceUsage, {
|
||||||
return get(this, 'nodes').filter( (n) => C.ACTIVEISH_STATES.indexOf(get(n, 'state')) === -1 );
|
return get(this, 'nodes').filter( (n) => C.ACTIVEISH_STATES.indexOf(get(n, 'state')) === -1 );
|
||||||
}),
|
}),
|
||||||
|
|
||||||
displayWarnings: computed('provider', 'inactiveNodes.[]', 'unhealthyComponents.[]', function() {
|
unhealthyNodes: computed('nodes.@each.conditions', function() {
|
||||||
|
const out = [];
|
||||||
|
|
||||||
|
(get(this, 'nodes') || []).forEach((n) => {
|
||||||
|
const conditions = get(n, 'conditions');
|
||||||
|
const outOfDisk = conditions.find((c) => c.type === 'OutOfDisk');
|
||||||
|
const diskPressure = conditions.find((c) => c.type === 'DiskPressure');
|
||||||
|
const memoryPressure = conditions.find((c) => c.type === 'MemoryPressure');
|
||||||
|
|
||||||
|
if ( outOfDisk && get(outOfDisk, 'status') === TRUE ) {
|
||||||
|
out.push({
|
||||||
|
displayName: get(n, 'displayName'),
|
||||||
|
error: 'outOfDisk'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( diskPressure && get(diskPressure, 'status') === TRUE ) {
|
||||||
|
out.push({
|
||||||
|
displayName: get(n, 'displayName'),
|
||||||
|
error: 'diskPressure'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( memoryPressure && get(memoryPressure, 'status') === TRUE ) {
|
||||||
|
out.push({
|
||||||
|
displayName: get(n, 'displayName'),
|
||||||
|
error: 'memoryPressure'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}),
|
||||||
|
|
||||||
|
displayWarnings: computed('unhealthyNodes.[]', 'provider', 'inactiveNodes.[]', 'unhealthyComponents.[]', function() {
|
||||||
const intl = get(this, 'intl');
|
const intl = get(this, 'intl');
|
||||||
const out = [];
|
const out = [];
|
||||||
const unhealthyComponents = get(this, 'unhealthyComponents') || [];
|
const unhealthyComponents = get(this, 'unhealthyComponents') || [];
|
||||||
const inactiveNodes = get(this, 'inactiveNodes') || [];
|
const inactiveNodes = get(this, 'inactiveNodes') || [];
|
||||||
|
const unhealthyNodes = get(this, 'unhealthyNodes') || [];
|
||||||
const provider = get(this, 'provider');
|
const provider = get(this, 'provider');
|
||||||
|
|
||||||
const grayOut = C.GRAY_OUT_SCHEDULER_STATUS_PROVIDERS.indexOf(provider) > -1;
|
const grayOut = C.GRAY_OUT_SCHEDULER_STATUS_PROVIDERS.indexOf(provider) > -1;
|
||||||
|
|
@ -294,6 +330,10 @@ export default Resource.extend(Grafana, ResourceUsage, {
|
||||||
out.pushObject(intl.t('clusterDashboard.alert.node', { node: get(node, 'displayName') }))
|
out.pushObject(intl.t('clusterDashboard.alert.node', { node: get(node, 'displayName') }))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
unhealthyNodes.forEach((node) => {
|
||||||
|
out.pushObject(intl.t(`clusterDashboard.alert.nodeCondition.${ get(node, 'error') }`, { node: get(node, 'displayName') }))
|
||||||
|
});
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,14 +89,9 @@
|
||||||
|
|
||||||
{{#unless hideManagerAndSchedulerStatus}}
|
{{#unless hideManagerAndSchedulerStatus}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{{#each unhealthyComponents as |component|}}
|
{{#each cluster.displayWarnings as |warning|}}
|
||||||
{{#banner-message icon="icon-alert" color="text-left bg-error mt-30"}}
|
{{#banner-message icon="icon-alert" color="text-left bg-error mt-30"}}
|
||||||
<p>{{t "clusterDashboard.alert.component" component=component.name}}</p>
|
<p>{{warning}}</p>
|
||||||
{{/banner-message}}
|
|
||||||
{{/each}}
|
|
||||||
{{#each inactiveNodes as |node|}}
|
|
||||||
{{#banner-message icon="icon-alert" color="text-left bg-error mt-30"}}
|
|
||||||
<p>{{t "clusterDashboard.alert.node" node=node.displayName}}</p>
|
|
||||||
{{/banner-message}}
|
{{/banner-message}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@
|
||||||
<h1 class="vertical-middle">
|
<h1 class="vertical-middle">
|
||||||
{{t 'hostsPage.hostPage.header.title' name=model.node.displayName}}{{copy-to-clipboard clipboardText=model.node.displayName size="small"}}
|
{{t 'hostsPage.hostPage.header.title' name=model.node.displayName}}{{copy-to-clipboard clipboardText=model.node.displayName size="small"}}
|
||||||
</h1>
|
</h1>
|
||||||
{{!-- <div class="vertical-middle">
|
{{#each model.node.displayRoles as |role|}}
|
||||||
<label class="acc-label vertical-middle p-0">{{t 'hostsPage.hostPage.hostname'}}:</label>
|
<span class="badge badge-xs vertical-middle bg-info">
|
||||||
{{model.node.hostname}} {{copy-to-clipboard clipboardText=model.node.hostname size="small"}}
|
{{role}}
|
||||||
</div> --}}
|
</span>
|
||||||
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
<div class="right-buttons">
|
<div class="right-buttons">
|
||||||
{{badge-state model=model.node}}
|
{{badge-state model=model.node}}
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,10 @@ clusterDashboard:
|
||||||
alert:
|
alert:
|
||||||
node: "Alert: Node {node} is not active."
|
node: "Alert: Node {node} is not active."
|
||||||
component: "Alert: Component {component} is unhealthy."
|
component: "Alert: Component {component} is unhealthy."
|
||||||
|
nodeCondition:
|
||||||
|
outOfDisk: "Alert: Node {node} is out of disk."
|
||||||
|
diskPressure: "Alert: Node {node} has disk pressure."
|
||||||
|
memoryPressure: "Alert: Node {node} has memory pressure."
|
||||||
liveTitle: "{used} of {total} Used"
|
liveTitle: "{used} of {total} Used"
|
||||||
reserved: Reserved
|
reserved: Reserved
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { get, set, observer } from '@ember/object';
|
||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
import layout from './template';
|
import layout from './template';
|
||||||
import EmberObject from '@ember/object';
|
import EmberObject from '@ember/object';
|
||||||
|
import C from 'ui/utils/constants';
|
||||||
|
|
||||||
const NO_SCHEDULE = 'NoSchedule';
|
const NO_SCHEDULE = 'NoSchedule';
|
||||||
const NO_EXECUTE = 'NoExecute';
|
const NO_EXECUTE = 'NoExecute';
|
||||||
|
|
@ -85,6 +86,7 @@ export default Component.extend({
|
||||||
key: get(taint, 'key'),
|
key: get(taint, 'key'),
|
||||||
value: get(taint, 'value'),
|
value: get(taint, 'value'),
|
||||||
effect: get(taint, 'effect'),
|
effect: get(taint, 'effect'),
|
||||||
|
readonly: C.LABEL_PREFIX_TO_IGNORE.find((L) => get(taint, 'key').startsWith(L))
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
class="form-control input-sm"
|
class="form-control input-sm"
|
||||||
type="text"
|
type="text"
|
||||||
value=taint.key
|
value=taint.key
|
||||||
|
disabled=taint.readonly
|
||||||
placeholder=(t "formNodeTaints.key.placeholder")
|
placeholder=(t "formNodeTaints.key.placeholder")
|
||||||
}}
|
}}
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -50,6 +51,7 @@
|
||||||
class="form-control input-sm"
|
class="form-control input-sm"
|
||||||
type="text"
|
type="text"
|
||||||
value=taint.value
|
value=taint.value
|
||||||
|
disabled=taint.readonly
|
||||||
placeholder=(t "formNodeTaints.value.placeholder")
|
placeholder=(t "formNodeTaints.value.placeholder")
|
||||||
}}
|
}}
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -61,12 +63,14 @@
|
||||||
classNames="form-control input-sm"
|
classNames="form-control input-sm"
|
||||||
content=effects
|
content=effects
|
||||||
value=taint.effect
|
value=taint.effect
|
||||||
|
disabled=taint.readonly
|
||||||
}}
|
}}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<button
|
<button
|
||||||
class="btn bg-primary btn-sm"
|
class="btn bg-primary btn-sm"
|
||||||
|
disabled={{taint.readonly}}
|
||||||
{{action "removeTaint" taint}}
|
{{action "removeTaint" taint}}
|
||||||
>
|
>
|
||||||
<i class="icon icon-minus"/>
|
<i class="icon icon-minus"/>
|
||||||
|
|
|
||||||
|
|
@ -719,10 +719,12 @@ export default Mixin.create({
|
||||||
const out = [];
|
const out = [];
|
||||||
const taints = get(this, 'nodeTaints') || get(this, 'taints') || [];
|
const taints = get(this, 'nodeTaints') || get(this, 'taints') || [];
|
||||||
|
|
||||||
taints.forEach((taint) => {
|
taints
|
||||||
|
.filter((taint) => !C.TAINT_PREFIX_TO_IGNORE.find((L) => taint.key.startsWith(L)))
|
||||||
|
.forEach((taint) => {
|
||||||
out.push(`${ get(taint, 'key') }${ get(taint, 'value') ? `=${ get(taint, 'value') }` : '' }:${ get(taint, 'effect') }`);
|
out.push(`${ get(taint, 'key') }${ get(taint, 'value') ? `=${ get(taint, 'value') }` : '' }:${ get(taint, 'effect') }`);
|
||||||
});
|
});
|
||||||
|
|
||||||
return out;
|
return out.sort();
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -560,6 +560,16 @@ C.LABELS_TO_IGNORE = [
|
||||||
|
|
||||||
C.LABEL_ISTIO_RULE = 'io.rancher.istio';
|
C.LABEL_ISTIO_RULE = 'io.rancher.istio';
|
||||||
|
|
||||||
|
C.TAINT_PREFIX_TO_IGNORE = [
|
||||||
|
'node-role.kubernetes.io/',
|
||||||
|
];
|
||||||
|
|
||||||
|
C.READONLY_TAINT_PREFIX = [
|
||||||
|
'node-role.kubernetes.io/',
|
||||||
|
'node.kubernetes.io/',
|
||||||
|
'node.cloudprovider.kubernetes.io/'
|
||||||
|
];
|
||||||
|
|
||||||
C.LABEL_PREFIX_TO_IGNORE = [
|
C.LABEL_PREFIX_TO_IGNORE = [
|
||||||
'io.cattle.lifecycle.',
|
'io.cattle.lifecycle.',
|
||||||
'beta.kubernetes.io/',
|
'beta.kubernetes.io/',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue