initial commit of chrome only of new replacement web ui
remove node modules make new data file for web ui initial commit of dashboard switch back to non SSL request move port splitting to common place; add to node resource location Signed-off-by: Patrick Reilly <patrick@kismatic.io> various path fixes make svg path relative work around missing mime type Signed-off-by: Patrick Reilly <patrick@kismatic.io> fix paths fix karma path remove bad protractor test
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
|
||||
|
||||
app.controller('cAdvisorController', [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'k8sApi',
|
||||
'lodash',
|
||||
'cAdvisorService',
|
||||
'$q',
|
||||
'$interval',
|
||||
function($scope, $routeParams, k8sApi, lodash, cAdvisorService, $q, $interval) {
|
||||
$scope.k8sApi = k8sApi;
|
||||
|
||||
$scope.activeMinionDataById = {};
|
||||
$scope.maxDataByById = {};
|
||||
|
||||
$scope.getData = function() {
|
||||
$scope.loading = true;
|
||||
|
||||
k8sApi.getMinions().success(angular.bind(this, function(res) {
|
||||
$scope.minions = res;
|
||||
// console.log(res);
|
||||
var promises = lodash.map(res.items, function(m) { return cAdvisorService.getDataForMinion(m.id); });
|
||||
|
||||
$q.all(promises).then(
|
||||
function(dataArray) {
|
||||
lodash.each(dataArray, function(data, i) {
|
||||
var m = res.items[i];
|
||||
|
||||
var maxData = maxMemCpuInfo(m.id, data.memoryData, data.cpuData, data.filesystemData);
|
||||
|
||||
// console.log("maxData", maxData);
|
||||
|
||||
$scope.activeMinionDataById[m.id] =
|
||||
transformMemCpuInfo(data.memoryData, data.cpuData, data.filesystemData, maxData, m.hostIP)
|
||||
});
|
||||
|
||||
},
|
||||
function(errorData) {
|
||||
// console.log("Error: " + errorData);
|
||||
$scope.loading = false;
|
||||
});
|
||||
|
||||
$scope.loading = false;
|
||||
})).error(angular.bind(this, this.handleError));
|
||||
};
|
||||
|
||||
function getcAdvisorDataForMinion(m) {
|
||||
var p = cAdvisorService.getDataForMinion(m.hostIP);
|
||||
return p;
|
||||
}
|
||||
|
||||
function handleError(data, status, headers, config) {
|
||||
// console.log("Error (" + status + "): " + data);
|
||||
$scope.loading = false;
|
||||
};
|
||||
|
||||
// d3
|
||||
function getColorForIndex(i, percentage) {
|
||||
// var colors = ['red', 'blue', 'yellow', 'pink', 'purple', 'green', 'orange'];
|
||||
// return colors[i];
|
||||
var c = "color-" + (i + 1);
|
||||
if (percentage && percentage >= 90)
|
||||
c = c + ' color-critical';
|
||||
else if (percentage && percentage >= 80)
|
||||
c = c + ' color-warning';
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
function getMaxColorForIndex(i, percentage) {
|
||||
// var colors = ['red', 'blue', 'yellow', 'pink', 'purple', 'green', 'orange'];
|
||||
// return colors[i];
|
||||
var c = "color-max-" + (i + 1);
|
||||
if (percentage && percentage >= 90)
|
||||
c = c + ' color-max-critical';
|
||||
else if (percentage && percentage >= 80)
|
||||
c = c + ' color-max-warning';
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
function maxMemCpuInfo(mId, mem, cpu, fsDataArray) {
|
||||
if ($scope.maxDataByById[mId] === undefined) $scope.maxDataByById[mId] = {};
|
||||
|
||||
var currentMem = mem.current;
|
||||
var currentCpu = cpu;
|
||||
|
||||
var items = [];
|
||||
|
||||
if ($scope.maxDataByById[mId]['cpu'] === undefined ||
|
||||
$scope.maxDataByById[mId]['cpu'] < currentCpu.cpuPercentUsage) {
|
||||
// console.log("New max cpu " + mId, $scope.maxDataByById[mId].cpu, currentCpu.cpuPercentUsage);
|
||||
$scope.maxDataByById[mId]['cpu'] = currentCpu.cpuPercentUsage;
|
||||
}
|
||||
items.push({
|
||||
maxValue: $scope.maxDataByById[mId]['cpu'],
|
||||
maxTickClassNames: getColorForIndex(0, $scope.maxDataByById[mId]['cpu']),
|
||||
maxClassNames: getMaxColorForIndex(0, $scope.maxDataByById[mId]['cpu'])
|
||||
});
|
||||
|
||||
var memPercentage = Math.floor((currentMem.memoryUsage * 100.0) / currentMem.memoryLimit);
|
||||
if ($scope.maxDataByById[mId]['mem'] === undefined || $scope.maxDataByById[mId]['mem'] < memPercentage)
|
||||
$scope.maxDataByById[mId]['mem'] = memPercentage;
|
||||
items.push({
|
||||
maxValue: $scope.maxDataByById[mId]['mem'],
|
||||
maxTickClassNames: getColorForIndex(1, $scope.maxDataByById[mId]['mem']),
|
||||
maxClassNames: getMaxColorForIndex(1, $scope.maxDataByById[mId]['mem'])
|
||||
});
|
||||
|
||||
for (var i = 0; i < fsDataArray.length; i++) {
|
||||
var f = fsDataArray[i];
|
||||
var fid = 'FS #' + f.filesystemNumber;
|
||||
if ($scope.maxDataByById[mId][fid] === undefined || $scope.maxDataByById[mId][fid] < f.totalUsage)
|
||||
$scope.maxDataByById[mId][fid] = f.totalUsage;
|
||||
items.push({
|
||||
maxValue: $scope.maxDataByById[mId][fid],
|
||||
maxTickClassNames: getColorForIndex(2 + i, $scope.maxDataByById[mId][fid]),
|
||||
maxClassNames: getMaxColorForIndex(2 + i, $scope.maxDataByById[mId][fid])
|
||||
});
|
||||
}
|
||||
|
||||
// console.log("Max Data is now " + mId, $scope.maxDataByById[mId]);
|
||||
return items;
|
||||
}
|
||||
|
||||
function transformMemCpuInfo(mem, cpu, fsDataArray, maxData, hostName) {
|
||||
var currentMem = mem.current;
|
||||
var currentCpu = cpu;
|
||||
|
||||
var items = [];
|
||||
|
||||
items.push({
|
||||
label: 'CPU',
|
||||
stats: currentCpu.cpuPercentUsage + '%',
|
||||
value: currentCpu.cpuPercentUsage,
|
||||
classNames: getColorForIndex(0, currentCpu.cpuPercentUsage),
|
||||
maxData: maxData[0],
|
||||
hostName: hostName
|
||||
});
|
||||
|
||||
var memPercentage = Math.floor((currentMem.memoryUsage * 100.0) / currentMem.memoryLimit);
|
||||
items.push({
|
||||
label: 'Memory',
|
||||
stats: currentMem.memoryUsageDescription + ' / ' + currentMem.memoryLimitDescription,
|
||||
value: memPercentage,
|
||||
classNames: getColorForIndex(1, memPercentage),
|
||||
maxData: maxData[1],
|
||||
hostName: hostName
|
||||
});
|
||||
|
||||
for (var i = 0; i < fsDataArray.length; i++) {
|
||||
var f = fsDataArray[i];
|
||||
|
||||
items.push({
|
||||
label: 'FS #' + f.filesystemNumber,
|
||||
stats: f.usageDescription + ' / ' + f.capacityDescription,
|
||||
value: f.totalUsage,
|
||||
classNames: getColorForIndex(2 + i, f.totalUsage),
|
||||
maxData: maxData[2 + i],
|
||||
hostName: hostName
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
var a = [];
|
||||
var segments = {
|
||||
segments: items
|
||||
};
|
||||
a.push(segments);
|
||||
return a;
|
||||
};
|
||||
|
||||
// end d3
|
||||
var promise = $interval($scope.getData, 3000);
|
||||
|
||||
// Cancel interval on page changes
|
||||
$scope.$on('$destroy', function() {
|
||||
if (angular.isDefined(promise)) {
|
||||
$interval.cancel(promise);
|
||||
promise = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.getData();
|
||||
|
||||
}
|
||||
]);
|
@@ -0,0 +1,6 @@
|
||||
/**=========================================================
|
||||
* Module: Dashboard
|
||||
* Visualizer for clusters
|
||||
=========================================================*/
|
||||
|
||||
app.controller('DashboardCtrl', ['$scope', function($scope) {}]);
|
@@ -0,0 +1,223 @@
|
||||
/**=========================================================
|
||||
* Module: Group
|
||||
* Visualizer for groups
|
||||
=========================================================*/
|
||||
|
||||
app.controller('GroupCtrl', [
|
||||
'$scope',
|
||||
'$route',
|
||||
'$interval',
|
||||
'$routeParams',
|
||||
'k8sApi',
|
||||
'$rootScope',
|
||||
'$location',
|
||||
'lodash',
|
||||
function($scope, $route, $interval, $routeParams, k8sApi, $rootScope, $location, _) {
|
||||
'use strict';
|
||||
$scope.doTheBack = function() { window.history.back(); };
|
||||
|
||||
$scope.capitalize = function(s) { return _.capitalize(s); };
|
||||
|
||||
$rootScope.doTheBack = $scope.doTheBack;
|
||||
|
||||
$scope.resetGroupLayout = function(group) { delete group.settings; };
|
||||
|
||||
$scope.handlePath = function(path) {
|
||||
var parts = path.split("/");
|
||||
// split leaves an empty string at the beginning.
|
||||
parts = parts.slice(1);
|
||||
|
||||
if (parts.length === 0) {
|
||||
return;
|
||||
}
|
||||
this.handleGroups(parts.slice(1));
|
||||
};
|
||||
|
||||
$scope.getState = function(obj) { return Object.keys(obj)[0]; };
|
||||
|
||||
$scope.clearSelector = function(grouping) { $location.path("/dashboard/groups/" + grouping + "/selector/"); };
|
||||
|
||||
$scope.changeGroupBy = function() {
|
||||
var grouping = $scope.selectedGroupBy;
|
||||
|
||||
var s = _.clone($location.search());
|
||||
if ($scope.routeParams.grouping != grouping)
|
||||
$location.path("/dashboard/groups/" + grouping + "/selector/").search(s);
|
||||
};
|
||||
|
||||
$scope.createBarrier = function(count, callback) {
|
||||
var barrier = count;
|
||||
var barrierFunction = angular.bind(this, function(data) {
|
||||
// JavaScript is single threaded so this is safe.
|
||||
barrier--;
|
||||
if (barrier === 0) {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
return barrierFunction;
|
||||
};
|
||||
|
||||
$scope.handleGroups = function(parts, selector) {
|
||||
$scope.groupBy = parts;
|
||||
$scope.loading = true;
|
||||
$scope.selector = selector;
|
||||
var args = [];
|
||||
var type = "";
|
||||
if (selector && selector.length > 0) {
|
||||
$scope.selectorPieces = selector.split(",");
|
||||
var labels = [];
|
||||
var fields = [];
|
||||
for (var i = 0; i < $scope.selectorPieces.length; i++) {
|
||||
var piece = $scope.selectorPieces[i];
|
||||
if (piece[0] == '$') {
|
||||
fields.push(piece.slice(2));
|
||||
} else {
|
||||
if (piece.indexOf("type=") === 0) {
|
||||
var labelParts = piece.split("=");
|
||||
if (labelParts.length > 1) {
|
||||
type = labelParts[1];
|
||||
}
|
||||
} else {
|
||||
labels.push(piece);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (labels.length > 0) {
|
||||
args.push("labels=" + encodeURI(labels.join(",")));
|
||||
}
|
||||
if (fields.length > 0) {
|
||||
args.push("fields=" + encodeURI(fields.join(",")));
|
||||
}
|
||||
}
|
||||
var query = "?" + args.join("&");
|
||||
var list = [];
|
||||
var count = type.length > 0 ? 1 : 3;
|
||||
var barrier = $scope.createBarrier(count, function() {
|
||||
$scope.groups = $scope.groupData(list, 0);
|
||||
$scope.loading = false;
|
||||
$scope.groupByOptions = buildGroupByOptions();
|
||||
$scope.selectedGroupBy = $routeParams.grouping;
|
||||
});
|
||||
|
||||
if (type === "" || type == "pod") {
|
||||
k8sApi.getPods(query).success(function(data) {
|
||||
$scope.addLabel("type", "pod", data.items);
|
||||
for (var i = 0; data.items && i < data.items.length; ++i) {
|
||||
data.items[i].labels.host = data.items[i].currentState.host;
|
||||
list.push(data.items[i]);
|
||||
}
|
||||
barrier();
|
||||
}).error($scope.handleError);
|
||||
}
|
||||
if (type === "" || type == "service") {
|
||||
k8sApi.getServices(query).success(function(data) {
|
||||
$scope.addLabel("type", "service", data.items);
|
||||
for (var i = 0; data.items && i < data.items.length; ++i) {
|
||||
list.push(data.items[i]);
|
||||
}
|
||||
barrier();
|
||||
}).error($scope.handleError);
|
||||
}
|
||||
if (type === "" || type == "replicationController") {
|
||||
k8sApi.getReplicationControllers(query).success(angular.bind(this, function(data) {
|
||||
$scope.addLabel("type", "replicationController", data.items);
|
||||
for (var i = 0; data.items && i < data.items.length; ++i) {
|
||||
list.push(data.items[i]);
|
||||
}
|
||||
barrier();
|
||||
})).error($scope.handleError);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.addLabel = function(key, value, items) {
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (!items[i].labels) {
|
||||
items[i].labels = [];
|
||||
}
|
||||
items[i].labels[key] = value;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.groupData = function(items, index) {
|
||||
var result = {
|
||||
"items": {},
|
||||
"kind": "grouping"
|
||||
};
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
key = items[i].labels[$scope.groupBy[index]];
|
||||
if (!key) {
|
||||
key = "";
|
||||
}
|
||||
var list = result.items[key];
|
||||
if (!list) {
|
||||
list = [];
|
||||
result.items[key] = list;
|
||||
}
|
||||
list.push(items[i]);
|
||||
}
|
||||
|
||||
if (index + 1 < $scope.groupBy.length) {
|
||||
for (var key in result.items) {
|
||||
result.items[key] = $scope.groupData(result.items[key], index + 1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
$scope.getGroupColor = function(type) {
|
||||
if (type === 'pod') {
|
||||
return '#6193F0';
|
||||
} else if (type === 'replicationController') {
|
||||
return '#E008FE';
|
||||
} else if (type === 'service') {
|
||||
return '#7C43FF';
|
||||
}
|
||||
};
|
||||
|
||||
var groups = $routeParams.grouping;
|
||||
if (!groups) {
|
||||
groups = '';
|
||||
}
|
||||
|
||||
$scope.routeParams = $routeParams;
|
||||
$scope.route = $route;
|
||||
|
||||
$scope.handleGroups(groups.split('/'), $routeParams.selector);
|
||||
|
||||
$scope.handleError = function(data, status, headers, config) {
|
||||
console.log("Error (" + status + "): " + data);
|
||||
$scope_.loading = false;
|
||||
};
|
||||
|
||||
function getDefaultGroupByOptions() { return [{name: 'Type', value: 'type'}, {name: 'Name', value: 'name'}]; }
|
||||
|
||||
function buildGroupByOptions() {
|
||||
var g = $scope.groups;
|
||||
var options = getDefaultGroupByOptions();
|
||||
var newOptions = _.map(g.items, function(vals) { return _.map(vals, function(v) { return _.keys(v.labels); }); });
|
||||
newOptions =
|
||||
_.reject(_.uniq(_.flattenDeep(newOptions)), function(o) { return o == 'name' || o == 'type' || o == ""; });
|
||||
newOptions = _.map(newOptions, function(o) {
|
||||
return {
|
||||
name: o,
|
||||
value: o
|
||||
};
|
||||
});
|
||||
|
||||
options = options.concat(newOptions);
|
||||
return options;
|
||||
}
|
||||
|
||||
$scope.changeFilterBy = function(selector) {
|
||||
var grouping = $scope.selectedGroupBy;
|
||||
|
||||
var s = _.clone($location.search());
|
||||
if ($scope.routeParams.selector != selector)
|
||||
$location.path("/dashboard/groups/" + $scope.routeParams.grouping + "/selector/" + selector).search(s);
|
||||
};
|
||||
}
|
||||
]);
|
@@ -0,0 +1,27 @@
|
||||
/**=========================================================
|
||||
* Module: Header
|
||||
* Visualizer for clusters
|
||||
=========================================================*/
|
||||
|
||||
angular.module('kubernetesApp.components.dashboard', [])
|
||||
.controller('HeaderCtrl', [
|
||||
'$scope',
|
||||
'$location',
|
||||
function($scope, $location) {
|
||||
'use strict';
|
||||
$scope.$watch('Pages', function(newValue, oldValue) {
|
||||
if (typeof newValue !== 'undefined') {
|
||||
$location.path(newValue);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.subPages = [
|
||||
{category: 'dashboard', name: 'Explore', value: '/dashboard/groups/type/selector/'},
|
||||
{category: 'dashboard', name: 'Pods', value: '/dashboard/pods'},
|
||||
{category: 'dashboard', name: 'Minions', value: '/dashboard/minions'},
|
||||
{category: 'dashboard', name: 'Replication Controllers', value: '/dashboard/replicationcontrollers'},
|
||||
{category: 'dashboard', name: 'Services', value: '/dashboard/services'},
|
||||
{category: 'dashboard', name: 'Events', value: '/dashboard/events'}
|
||||
];
|
||||
}
|
||||
]);
|
@@ -0,0 +1,85 @@
|
||||
/**=========================================================
|
||||
* Module: List Events
|
||||
* Visualizer list events
|
||||
=========================================================*/
|
||||
|
||||
app.controller('ListEventsCtrl', [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'k8sApi',
|
||||
'$location',
|
||||
'$filter',
|
||||
function($scope, $routeParams, k8sApi, $location, $filter) {
|
||||
'use strict';
|
||||
$scope.getData = getData;
|
||||
$scope.loading = true;
|
||||
$scope.k8sApi = k8sApi;
|
||||
$scope.pods = null;
|
||||
$scope.groupedPods = null;
|
||||
$scope.serverView = false;
|
||||
|
||||
$scope.headers = [
|
||||
{name: 'Time', field: 'time'},
|
||||
{name: 'From', field: 'from'},
|
||||
{name: 'Sub Object Path', field: 'subobject'},
|
||||
{name: 'Reason', field: 'reason'},
|
||||
{name: 'Message', field: 'message'}
|
||||
];
|
||||
|
||||
$scope.custom = {
|
||||
time: '',
|
||||
from: 'grey',
|
||||
subobject: 'grey',
|
||||
reason: 'grey',
|
||||
message: 'grey'
|
||||
};
|
||||
$scope.sortable = ['time', 'from', 'subobject'];
|
||||
$scope.thumbs = 'thumb';
|
||||
$scope.count = 10;
|
||||
|
||||
$scope.go = function(d) { $location.path('/dashboard/pods/' + d.id); };
|
||||
|
||||
$scope.moreClick = function(d, e) {
|
||||
$location.path('/dashboard/pods/' + d.id);
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
function handleError(data, status, headers, config) {
|
||||
console.log("Error (" + status + "): " + data);
|
||||
$scope.loading = false;
|
||||
}
|
||||
|
||||
$scope.content = [];
|
||||
|
||||
function getData(dataId) {
|
||||
$scope.loading = true;
|
||||
k8sApi.getEvents().success(function(data) {
|
||||
$scope.loading = false;
|
||||
|
||||
var _fixComma = function(str) {
|
||||
if (str.substring(0, 1) == ',') {
|
||||
return str.substring(1);
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
data.items.forEach(function(event) {
|
||||
|
||||
$scope.content.push({
|
||||
time: $filter('date')(event.timestamp, 'medium'),
|
||||
from: event.source,
|
||||
subobject: event.involvedObject.fieldPath,
|
||||
reason: event.reason,
|
||||
message: event.message
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}).error($scope.handleError);
|
||||
}
|
||||
|
||||
getData($routeParams.serviceId);
|
||||
|
||||
}
|
||||
]);
|
@@ -0,0 +1,76 @@
|
||||
/**=========================================================
|
||||
* Module: Minions
|
||||
* Visualizer for minions
|
||||
=========================================================*/
|
||||
|
||||
app.controller('ListMinionsCtrl', [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'k8sApi',
|
||||
'$location',
|
||||
function($scope, $routeParams, k8sApi, $location) {
|
||||
'use strict';
|
||||
$scope.getData = getData;
|
||||
$scope.loading = true;
|
||||
$scope.k8sApi = k8sApi;
|
||||
$scope.pods = null;
|
||||
$scope.groupedPods = null;
|
||||
$scope.serverView = false;
|
||||
|
||||
$scope.headers = [{name: 'Name', field: 'name'}, {name: 'IP', field: 'ip'}, {name: 'Status', field: 'status'}];
|
||||
|
||||
$scope.custom = {
|
||||
name: '',
|
||||
status: 'grey',
|
||||
ip: 'grey'
|
||||
};
|
||||
$scope.sortable = ['name', 'status', 'ip'];
|
||||
$scope.thumbs = 'thumb';
|
||||
$scope.count = 10;
|
||||
|
||||
$scope.go = function(d) { $location.path('/dashboard/pods/' + d.id); };
|
||||
|
||||
$scope.moreClick = function(d, e) {
|
||||
$location.path('/dashboard/pods/' + d.id);
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
function handleError(data, status, headers, config) {
|
||||
console.log("Error (" + status + "): " + data);
|
||||
$scope.loading = false;
|
||||
}
|
||||
|
||||
$scope.content = [];
|
||||
|
||||
function getData(dataId) {
|
||||
$scope.loading = true;
|
||||
k8sApi.getMinions().success(function(data) {
|
||||
$scope.loading = false;
|
||||
|
||||
var _fixComma = function(str) {
|
||||
if (str.substring(0, 1) == ',') {
|
||||
return str.substring(1);
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
data.items.forEach(function(minion) {
|
||||
var _kind = '';
|
||||
|
||||
if (minion.status.conditions) {
|
||||
Object.keys(minion.status.conditions)
|
||||
.forEach(function(key) { _kind += minion.status.conditions[key].kind; });
|
||||
}
|
||||
|
||||
$scope.content.push({name: minion.id, ip: minion.hostIP, status: _kind});
|
||||
|
||||
});
|
||||
|
||||
}).error($scope.handleError);
|
||||
}
|
||||
|
||||
getData($routeParams.serviceId);
|
||||
|
||||
}
|
||||
]);
|
@@ -0,0 +1,137 @@
|
||||
|
||||
|
||||
app.controller('ListPodsCtrl', [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'k8sApi',
|
||||
'lodash',
|
||||
'$location',
|
||||
function($scope, $routeParams, k8sApi, lodash, $location) {
|
||||
var _ = lodash;
|
||||
$scope.getData = getData;
|
||||
$scope.loading = true;
|
||||
$scope.k8sApi = k8sApi;
|
||||
$scope.pods = null;
|
||||
$scope.groupedPods = null;
|
||||
$scope.serverView = false;
|
||||
|
||||
$scope.headers = [
|
||||
{name: '', field: 'thumb'},
|
||||
{name: 'Pod', field: 'pod'},
|
||||
{name: 'IP', field: 'ip'},
|
||||
{name: 'Status', field: 'status'},
|
||||
{name: 'Containers', field: 'containers'},
|
||||
{name: 'Images', field: 'images'},
|
||||
{name: 'Host', field: 'host'},
|
||||
{name: 'Labels', field: 'labels'}
|
||||
];
|
||||
|
||||
$scope.custom = {
|
||||
pod: '',
|
||||
ip: 'grey',
|
||||
containers: 'grey',
|
||||
images: 'grey',
|
||||
host: 'grey',
|
||||
labels: 'grey',
|
||||
status: 'grey'
|
||||
};
|
||||
$scope.sortable = ['pod', 'ip', 'status'];
|
||||
$scope.thumbs = 'thumb';
|
||||
$scope.count = 10;
|
||||
|
||||
$scope.go = function(d) { $location.path('/dashboard/pods/' + d.id); };
|
||||
|
||||
$scope.moreClick = function(d, e) {
|
||||
$location.path('/dashboard/pods/' + d.id);
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
var orderedPodNames = [];
|
||||
|
||||
function handleError(data, status, headers, config) {
|
||||
console.log("Error (" + status + "): " + data);
|
||||
$scope.loading = false;
|
||||
};
|
||||
|
||||
function getPodName(pod) { return _.has(pod.labels, 'name') ? pod.labels.name : pod.id; }
|
||||
|
||||
$scope.content = [];
|
||||
|
||||
function getData(dataId) {
|
||||
$scope.loading = true;
|
||||
k8sApi.getPods().success(angular.bind(this, function(data) {
|
||||
$scope.loading = false;
|
||||
|
||||
var _fixComma = function(str) {
|
||||
if (str.substring(0, 1) == ',') {
|
||||
return str.substring(1);
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
data.items.forEach(function(pod) {
|
||||
var _containers = '', _images = '', _labels = '', _uses = '';
|
||||
|
||||
if (pod.desiredState.manifest) {
|
||||
Object.keys(pod.desiredState.manifest.containers)
|
||||
.forEach(function(key) {
|
||||
_containers += ', ' + pod.desiredState.manifest.containers[key].name;
|
||||
_images += ', ' + pod.desiredState.manifest.containers[key].image;
|
||||
});
|
||||
}
|
||||
|
||||
Object.keys(pod.labels)
|
||||
.forEach(function(key) {
|
||||
if (key == 'name') {
|
||||
_labels += ', ' + pod.labels[key];
|
||||
}
|
||||
if (key == 'uses') {
|
||||
_uses += ', ' + pod.labels[key];
|
||||
}
|
||||
});
|
||||
|
||||
$scope.content.push({
|
||||
thumb: '"assets/img/kubernetes.svg"',
|
||||
pod: pod.id,
|
||||
ip: pod.currentState.podIP,
|
||||
containers: _fixComma(_containers),
|
||||
images: _fixComma(_images),
|
||||
host: pod.currentState.host,
|
||||
labels: _fixComma(_labels) + ':' + _fixComma(_uses),
|
||||
status: pod.currentState.status
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})).error(angular.bind(this, handleError));
|
||||
};
|
||||
|
||||
$scope.getPodRestarts = function(pod) {
|
||||
var r = null;
|
||||
var container = _.first(pod.desiredState.manifest.containers);
|
||||
if (container) r = pod.currentState.info[container.name].restartCount;
|
||||
return r;
|
||||
};
|
||||
|
||||
$scope.otherLabels = function(labels) { return _.omit(labels, 'name') };
|
||||
|
||||
$scope.podStatusClass = function(pod) {
|
||||
|
||||
var s = pod.currentState.status.toLowerCase();
|
||||
|
||||
if (s == 'running' || s == 'succeeded')
|
||||
return null;
|
||||
else
|
||||
return "status-" + s;
|
||||
};
|
||||
|
||||
$scope.podIndexFromName = function(pod) {
|
||||
var name = getPodName(pod);
|
||||
return _.indexOf(orderedPodNames, name) + 1;
|
||||
};
|
||||
|
||||
getData($routeParams.serviceId);
|
||||
|
||||
}
|
||||
]);
|
@@ -0,0 +1,101 @@
|
||||
/**=========================================================
|
||||
* Module: Replication Controllers
|
||||
* Visualizer for replication controllers
|
||||
=========================================================*/
|
||||
|
||||
app.controller('ListReplicationControllersCtrl', [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'k8sApi',
|
||||
'$location',
|
||||
function($scope, $routeParams, k8sApi, $location) {
|
||||
'use strict';
|
||||
$scope.getData = getData;
|
||||
$scope.loading = true;
|
||||
$scope.k8sApi = k8sApi;
|
||||
$scope.pods = null;
|
||||
$scope.groupedPods = null;
|
||||
$scope.serverView = false;
|
||||
|
||||
$scope.headers = [
|
||||
{name: 'Controller', field: 'controller'},
|
||||
{name: 'Containers', field: 'containers'},
|
||||
{name: 'Images', field: 'images'},
|
||||
{name: 'Selector', field: 'selector'},
|
||||
{name: 'Replicas', field: 'replicas'}
|
||||
];
|
||||
|
||||
$scope.custom = {
|
||||
controller: '',
|
||||
containers: 'grey',
|
||||
images: 'grey',
|
||||
selector: 'grey',
|
||||
replicas: 'grey'
|
||||
};
|
||||
$scope.sortable = ['controller', 'containers', 'images'];
|
||||
$scope.thumbs = 'thumb';
|
||||
$scope.count = 10;
|
||||
|
||||
$scope.go = function(d) { $location.path('/dashboard/pods/' + d.id); };
|
||||
|
||||
$scope.moreClick = function(d, e) {
|
||||
$location.path('/dashboard/pods/' + d.id);
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
function handleError(data, status, headers, config) {
|
||||
console.log("Error (" + status + "): " + data);
|
||||
$scope.loading = false;
|
||||
}
|
||||
|
||||
$scope.content = [];
|
||||
|
||||
function getData(dataId) {
|
||||
$scope.loading = true;
|
||||
k8sApi.getReplicationControllers().success(function(data) {
|
||||
$scope.loading = false;
|
||||
|
||||
var _fixComma = function(str) {
|
||||
if (str.substring(0, 1) == ',') {
|
||||
return str.substring(1);
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
data.items.forEach(function(replicationController) {
|
||||
|
||||
var _name = '', _image = '';
|
||||
|
||||
if (replicationController.desiredState.podTemplate.desiredState.manifest.containers) {
|
||||
Object.keys(replicationController.desiredState.podTemplate.desiredState.manifest.containers)
|
||||
.forEach(function(key) {
|
||||
_name += replicationController.desiredState.podTemplate.desiredState.manifest.containers[key].name;
|
||||
_image += replicationController.desiredState.podTemplate.desiredState.manifest.containers[key].image;
|
||||
});
|
||||
}
|
||||
|
||||
var _name_selector = '';
|
||||
|
||||
if (replicationController.desiredState.replicaSelector) {
|
||||
Object.keys(replicationController.desiredState.replicaSelector)
|
||||
.forEach(function(key) { _name_selector += replicationController.desiredState.replicaSelector[key]; });
|
||||
}
|
||||
|
||||
$scope.content.push({
|
||||
controller: replicationController.id,
|
||||
containers: _name,
|
||||
images: _image,
|
||||
selector: _name_selector,
|
||||
replicas: replicationController.currentState.replicas
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}).error($scope.handleError);
|
||||
}
|
||||
|
||||
getData($routeParams.serviceId);
|
||||
|
||||
}
|
||||
]);
|
@@ -0,0 +1,110 @@
|
||||
/**=========================================================
|
||||
* Module: Services
|
||||
* Visualizer for services
|
||||
=========================================================*/
|
||||
|
||||
app.controller('ListServicesCtrl', [
|
||||
'$scope',
|
||||
'$interval',
|
||||
'$routeParams',
|
||||
'k8sApi',
|
||||
'$rootScope',
|
||||
function($scope, $interval, $routeParams, k8sApi, $rootScope) {
|
||||
'use strict';
|
||||
$scope.doTheBack = function() { window.history.back(); };
|
||||
|
||||
$scope.headers = [
|
||||
{name: 'Name', field: 'name'},
|
||||
{name: 'Labels', field: 'labels'},
|
||||
{name: 'Selector', field: 'selector'},
|
||||
{name: 'IP', field: 'ip'},
|
||||
{name: 'Port', field: 'port'}
|
||||
];
|
||||
|
||||
$scope.custom = {
|
||||
name: '',
|
||||
ip: 'grey',
|
||||
selector: 'grey',
|
||||
port: 'grey',
|
||||
labels: 'grey'
|
||||
};
|
||||
$scope.sortable = ['name', 'ip', 'port'];
|
||||
$scope.count = 10;
|
||||
|
||||
$scope.content = [];
|
||||
|
||||
$rootScope.doTheBack = $scope.doTheBack;
|
||||
|
||||
$scope.handleError = function(data, status, headers, config) {
|
||||
console.log("Error (" + status + "): " + data);
|
||||
$scope_.loading = false;
|
||||
};
|
||||
|
||||
$scope.getData = function(dataId) {
|
||||
$scope.loading = true;
|
||||
k8sApi.getServices(dataId).success(angular.bind(this, function(data) {
|
||||
$scope.services = data;
|
||||
$scope.loading = false;
|
||||
|
||||
var _fixComma = function(str) {
|
||||
if (str.substring(0, 1) == ',') {
|
||||
return str.substring(1);
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
var addLabel = function(str, label) {
|
||||
if (str) {
|
||||
str = label + str;
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
if (data.items.constructor === Array) {
|
||||
data.items.forEach(function(service) {
|
||||
|
||||
var _name = '', _uses = '', _component = '', _provider = '';
|
||||
|
||||
if (service.labels !== null && typeof service.labels === 'object') {
|
||||
Object.keys(service.labels)
|
||||
.forEach(function(key) {
|
||||
if (key == 'name') {
|
||||
_name += ',' + service.labels[key];
|
||||
}
|
||||
if (key == 'component') {
|
||||
_component += ',' + service.labels[key];
|
||||
}
|
||||
if (key == 'provider') {
|
||||
_provider += ',' + service.labels[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var _selectors = '';
|
||||
|
||||
if (service.selector !== null && typeof service.selector === 'object') {
|
||||
Object.keys(service.selector)
|
||||
.forEach(function(key) {
|
||||
if (key == 'name') {
|
||||
_selectors += ',' + service.selector[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.content.push({
|
||||
name: service.id,
|
||||
ip: service.portalIP,
|
||||
port: service.port,
|
||||
selector: addLabel(_fixComma(_selectors), 'name='),
|
||||
labels: addLabel(_fixComma(_name), 'name=') + ' ' + addLabel(_fixComma(_component), 'component=') + ' ' +
|
||||
addLabel(_fixComma(_provider), 'provider=')
|
||||
});
|
||||
});
|
||||
}
|
||||
})).error($scope.handleError);
|
||||
};
|
||||
|
||||
$scope.getData($routeParams.serviceId);
|
||||
}
|
||||
]);
|
@@ -0,0 +1,33 @@
|
||||
/**=========================================================
|
||||
* Module: Pods
|
||||
* Visualizer for pods
|
||||
=========================================================*/
|
||||
|
||||
app.controller('PodCtrl', [
|
||||
'$scope',
|
||||
'$interval',
|
||||
'$routeParams',
|
||||
'k8sApi',
|
||||
'$rootScope',
|
||||
function($scope, $interval, $routeParams, k8sApi, $rootScope) {
|
||||
'use strict';
|
||||
$scope.doTheBack = function() { window.history.back(); };
|
||||
|
||||
$rootScope.doTheBack = $scope.doTheBack;
|
||||
|
||||
$scope.handleError = function(data, status, headers, config) {
|
||||
console.log("Error (" + status + "): " + data);
|
||||
$scope_.loading = false;
|
||||
};
|
||||
|
||||
$scope.handlePod = function(podId) {
|
||||
$scope.loading = true;
|
||||
k8sApi.getPods(podId).success(angular.bind(this, function(data) {
|
||||
$scope.pod = data;
|
||||
$scope.loading = false;
|
||||
})).error($scope.handleError);
|
||||
};
|
||||
|
||||
$scope.handlePod($routeParams.podId);
|
||||
}
|
||||
]);
|
@@ -0,0 +1,32 @@
|
||||
/**=========================================================
|
||||
* Module: Replication
|
||||
* Visualizer for replication controllers
|
||||
=========================================================*/
|
||||
|
||||
function ReplicationController() {
|
||||
}
|
||||
|
||||
ReplicationController.prototype.getData = function(dataId) {
|
||||
this.scope.loading = true;
|
||||
this.k8sApi.getReplicationControllers(dataId).success(angular.bind(this, function(data) {
|
||||
this.scope.replicationController = data;
|
||||
this.scope.loading = false;
|
||||
})).error(angular.bind(this, this.handleError));
|
||||
};
|
||||
|
||||
ReplicationController.prototype.handleError = function(data, status, headers, config) {
|
||||
console.log("Error (" + status + "): " + data);
|
||||
this.scope.loading = false;
|
||||
};
|
||||
|
||||
app.controller('ReplicationControllerCtrl', [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'k8sApi',
|
||||
function($scope, $routeParams, k8sApi) {
|
||||
$scope.controller = new ReplicationController();
|
||||
$scope.controller.k8sApi = k8sApi;
|
||||
$scope.controller.scope = $scope;
|
||||
$scope.controller.getData($routeParams.replicationControllerId);
|
||||
}
|
||||
]);
|
@@ -0,0 +1,40 @@
|
||||
/**=========================================================
|
||||
* Module: Services
|
||||
* Visualizer for services
|
||||
=========================================================*/
|
||||
|
||||
function ServiceController() {
|
||||
}
|
||||
|
||||
ServiceController.prototype.getData = function(dataId) {
|
||||
this.scope.loading = true;
|
||||
this.k8sApi.getServices(dataId).success(angular.bind(this, function(data) {
|
||||
this.scope.service = data;
|
||||
this.scope.loading = false;
|
||||
})).error(angular.bind(this, this.handleError));
|
||||
};
|
||||
|
||||
ServiceController.prototype.handleError = function(data, status, headers, config) {
|
||||
console.log("Error (" + status + "): " + data);
|
||||
this.scope.loading = false;
|
||||
};
|
||||
|
||||
app.controller('ServiceCtrl', [
|
||||
'$scope',
|
||||
'$routeParams',
|
||||
'k8sApi',
|
||||
'$location',
|
||||
function($scope, $routeParams, k8sApi, $location) {
|
||||
$scope.controller = new ServiceController();
|
||||
$scope.controller.k8sApi = k8sApi;
|
||||
$scope.controller.scope = $scope;
|
||||
$scope.controller.getData($routeParams.serviceId);
|
||||
|
||||
$scope.go = function(d) { $location.path('/dashboard/services/' + d.id); }
|
||||
|
||||
$scope.moreClick = function(d, e) {
|
||||
$location.path('/dashboard/services/' + d.id);
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
]);
|
Reference in New Issue
Block a user