K8s banners

This commit is contained in:
Vincent Fiduccia 2017-03-28 17:44:55 -07:00
parent 4c55c59360
commit f9566f4af6
No known key found for this signature in database
GPG Key ID: 2B29AD6BB2BB2582
4 changed files with 240 additions and 66 deletions

View File

@ -0,0 +1,16 @@
import Ember from 'ember';
export default Ember.Component.extend({
classNames: ['banner'],
classNameBindings: ['color'],
showIcon: function() {
let value = this.get('value');
return value === null || value === undefined;
}.property('value'),
color: 'bg-default',
icon: 'icon icon-info',
value: null,
message: '',
});

View File

@ -0,0 +1,10 @@
<div class="banner-icon {{valueClass}}">{{#if showIcon}}<span class="icon {{icon}}"></span>{{else}}{{value}}{{/if}}</div>
<div class="banner-message">
<p>
{{#if hasBlock}}
{{yield}}
{{else}}
{{message}}
{{/if}}
</p>
</div>

View File

@ -0,0 +1,184 @@
import Ember from 'ember';
import {
formatPercent, formatMib, formatKbps
}
from 'ui/utils/util';
const formatters = {
value: (value) => {
return value;
},
percent: formatPercent,
mib: formatMib,
kbps: formatKbps
};
export default Ember.Component.extend({
attributeBindings: ['cssSize:style', 'tooltip'],
tagName : 'span',
classNames : ['spark-line'],
intl : Ember.inject.service(),
data : null,
width : null,
height : 20,
min : 0,
max : null,
interpolation : 'step-after',
formatter : 'value',
prefix : '',
type : null,
svg : null,
line : null,
dot : null,
x : null,
y : null,
tooltipModel: null,
hasData: function() {
if (this.get('data.length') > 0 && !this.get('svg')) {
this.create();
}
}.observes('data.length'),
cssSize: function() {
return new Ember.String.htmlSafe('width: ' + this.get('width') + 'px; height: ' + this.get('height') + 'px');
}.property('width', 'height'),
lastValue: function() {
var data = this.get('data');
if (data && data.get('length')) {
return data.objectAt(data.get('length') - 1);
}
}.property('data.[]'),
tooltip: function() {
let prefix = this.get('prefix');
let prefixI18n = null;
let out = null;
if (prefix) {
prefixI18n = this.get('intl').findTranslationByKey(prefix);
out = `${this.get('intl').formatMessage(prefixI18n)} ${formatters[this.get('formatter')](this.get('lastValue'))}`;
} else {
out = ` ${formatters[this.get('formatter')](this.get('lastValue'))}`;
}
Ember.run.next(() => {
if ( this.isDestoyed || this.isDestroying ) {
return;
}
this.set('tooltipModel', out);
});
}.property('prefix', 'lastValue', 'formatter'),
create() {
var svg = d3.select(this.$()[0])
.append('svg:svg')
.attr('width', '100%')
.attr('height', '100%');
var gradient = svg.append('svg:defs')
.append("svg:linearGradient")
.attr('id', `${this.get('type')}-gradient`)
.attr('x1', '0%')
.attr('y1', '0%')
.attr('x2', '100%')
.attr('y2', '100%')
.attr('spreadMethod', 'pad');
gradient.append('svg:stop')
.attr('offset', '0%')
.attr('stop-color', this.typePath())
.attr('stop-opacity', '1');
gradient.append('svg:stop')
.attr('offset', '100%')
.attr('stop-color', this.typePath())
.attr('stop-opacity', '.1');
this.set('svg', svg);
this.set('x', d3.scale.linear());
this.set('y', d3.scale.linear());
var line = d3.svg.area()
.x((d, i) => {
return this.get('x')(i);
})
.y0(this.get('height'))
.y1((d) => {
return this.get('y')(d);
});
this.set('line', line);
this.updateLine();
svg.append('path')
.attr('class', `spark-path ${this.get('type')}-path`)
.attr('d', line(this.get('data')));
},
typePath: function() {
var out;
switch (this.get('type')) {
case 'cpu':
out = '#2ecc71'; //$green
break;
case 'memory':
out = '#00558b'; //$primary-dark
break;
case 'network':
out = '#d35401'; //mix($warning, $error, 20%)Dark
break;
case 'storage':
out = '#3a6f81'; //$info
break;
default:
break;
}
return out;
},
updateLine: function() {
var line = this.get('line');
var interp = this.get('interpolation');
if (line) {
line.interpolate(interp);
}
}.observes('interpolation'),
update: function() {
var svg = this.get('svg');
var data = (this.get('data') || []).slice();
var x = this.get('x');
var y = this.get('y');
var line = this.get('line');
var width = this.get('width');
var height = this.get('height');
if (svg && data && x && y && line) {
x.domain([0, data.get('length') - 1]);
x.range([0, width - 1]);
var min = this.get('min') === null ? d3.min(data) : this.get('min');
var max = this.get('max') === null ? d3.max(data) : this.get('max');
y.domain([min, max]);
y.range([height, 0]);
y.rangeRound([height, 0]);
//console.log('update', data[data.length-2], data[data.length-1], x.domain(), x.range(), y.domain(), y.range());
svg.selectAll('path')
.data([data])
.style('fill', `url(${window.location.pathname}#${this.get('type')}-gradient)`)
.attr('d', line);
}
}.observes('data', 'data.[]'),
});

View File

@ -1,83 +1,47 @@
{{waiting-orchestration}}
<div class="k8s-tab">
<h1 class="mt-10 mb-0">Status</h1>
<section class="header mb-0">
<h1>Status</h1>
</section>
<div class="row text-center">
<div class="col span-3 count-box {{if etcd 'text-success' 'bg-warning'}}">
<h1>{{#if etcd}}<i class="icon icon-face-open-smile"></i>{{else}}<i class="icon icon-alert text-error"></i>{{/if}}</h1>
<h2>etcd</h2>
<div class="col span-3 mt-0">
{{banner-message icon=(if etcd 'icon-success' 'icon-alert') color=(if etcd 'bg-success' 'bg-warning') message='Etcd'}}
</div>
<div class="col span-3 count-box {{if kubelet 'text-success' 'bg-warning'}}">
<h1>{{#if kubelet}}<i class="icon icon-face-open-smile"></i>{{else}}<i class="icon icon-alert text-error"></i>{{/if}}</h1>
<h2>Kubelet</h2>
<div class="col span-3 mt-0">
{{banner-message icon=(if kubelet 'icon-success' 'icon-alert') color=(if kubelet 'bg-success' 'bg-warning') message='Kubelets'}}
</div>
<div class="col span-3 count-box {{if controlPlane 'text-success' 'bg-warning'}}">
<h1>{{#if controlPlane}}<i class="icon icon-face-open-smile"></i>{{else}}<i class="icon icon-alert text-error"></i>{{/if}}</h1>
<h2>Control Plane</h2>
<div class="col span-3 mt-0">
{{banner-message icon=(if controlPlane 'icon-success' 'icon-alert') color=(if controlPlane 'bg-success' 'bg-warning') message='Control Plane'}}
</div>
<div class="col span-3 count-box {{if systemStacks 'text-success' 'bg-warning'}}">
<h1>{{#if systemStacks}}<i class="icon icon-face-open-smile"></i>{{else}}<i class="icon icon-alert text-error"></i>{{/if}}</h1>
<h2>System Services</h2>
<div class="col span-3 mt-0">
{{banner-message icon=(if systemStacks 'icon-success' 'icon-alert') color=(if systemStacks 'bg-success' 'bg-warning') message='System Services'}}
</div>
</div>
<h1 class="mt-10 mb-0">Resources</h1>
<div class="row text-center">
<div class="col span-4">
<div class="count-box">
<h1>{{model.workload.deploymentList.listMeta.totalItems}}</h1>
<h2>Deployments</h2>
<section class="header">
<h1>Resources</h1>
</section>
<div class="box">
<div class="row">
<div class="col span-6 mt-0">
{{banner-message value=model.workload.deploymentList.listMeta.totalItems color='bg-info' message='Deployments'}}
{{banner-message value=model.workload.replicaSetList.listMeta.totalItems color='bg-info' message='Replica Sets'}}
{{banner-message value=model.workload.replicationControllerList.listMeta.totalItems color='bg-info' message='Replication Controllers'}}
{{banner-message value=model.workload.podList.listMeta.totalItems color='bg-info' message='Pods'}}
</div>
</div>
<div class="col span-4">
<div class="count-box">
<h1>{{model.workload.replicaSetList.listMeta.totalItems}}</h1>
<h2>Replica Sets</h2>
</div>
</div>
<div class="col span-4">
<div class="count-box">
<h1>{{model.workload.podList.listMeta.totalItems}}</h1>
<h2>Pods</h2>
</div>
</div>
</div>
<div class="row text-center">
<div class="col span-3">
<div class="count-box">
<h1>{{model.workload.daemonSetList.listMeta.totalItems}}</h1>
<h2>Daemon Sets</h2>
</div>
</div>
<div class="col span-3">
<div class="count-box">
<h1>{{model.workload.replicationControllerList.listMeta.totalItems}}</h1>
<h2>RCs</h2>
</div>
</div>
<div class="col span-3">
<div class="count-box">
<h1>{{model.workload.statefulSetList.listMeta.totalItems}}</h1>
<h2>Stateful Sets</h2>
</div>
</div>
<div class="col span-3">
<div class="count-box">
<h1>{{model.workload.jobList.listMeta.totalItems}}</h1>
<h2>Job Lists</h2>
<div class="col span-6 mt-0">
{{banner-message value=model.workload.daemonSetList.listMeta.totalItems color='bg-info' message='Daemon Sets'}}
{{banner-message value=model.workload.statefulSetList.listMeta.totalItems color='bg-info' message='Stateful Sets'}}
{{banner-message value=model.workload.jobList.listMeta.totalItems color='bg-info' message='Jobs'}}
</div>
</div>
</div>
<div class="row text-center">
<div class="col span-4">
<a href="{{k8s.kubernetesDashboard}}" target="_blank" rel="noopener nofollow" class="btn bg-primary btn-lg"><i class="icon icon-external-link"></i> Launch Dashboard</a>
</div>
<div class="col span-4">
<button {{action "kubectl"}} class="btn bg-primary btn-lg"><i class="icon icon-terminal"></i> Launch kubectl Shell</button>
</div>
<div class="col span-4">
<button {{action "kubeconfig"}} class="btn bg-primary btn-lg"><i class="icon icon-file"></i> Generate Config File</button>
</div>
<div class="text-right mt-10">
<a href="{{k8s.kubernetesDashboard}}" target="_blank" rel="noopener nofollow" class="btn bg-primary"><i class="icon icon-external-link"></i> Launch Dashboard</a>
<button {{action "kubectl"}} class="btn bg-primary"><i class="icon icon-terminal"></i> Launch kubectl Shell</button>
<button {{action "kubeconfig"}} class="btn bg-primary"><i class="icon icon-file"></i> Generate Config File</button>
</div>
</div>