diff --git a/v2/assets/css/chart.css b/v2/assets/css/chart.css index dcb6468..064d711 100644 --- a/v2/assets/css/chart.css +++ b/v2/assets/css/chart.css @@ -71,3 +71,42 @@ treechart rect[data-state='warning'] { treechart rect[data-state='error'] { fill: red; } + + +/* gantt chart */ + +ganttchart .chart { + font-family: Arial, sans-serif; + font-size: 12px; + margin-top: 30px; +} + +ganttchart text { + font-family: "Lucida Grande","Lucida Sans Unicode",Helvetica,Arial,Verdana,sans-serif !important; +} + +ganttchart .axis path, ganttchart .axis line { + fill: none; + stroke: #000; + shape-rendering: crispEdges; +} + +ganttchart .bar { + fill: #33b5e5; +} + +ganttchart .bar-failed { + fill: #CC0000; +} + +ganttchart .bar-running { + fill: #669900; +} + +ganttchart .bar-succeeded { + fill: #33b5e5; +} + +ganttchart .bar-killed { + fill: #ffbb33; +} \ No newline at end of file diff --git a/v2/assets/css/style.css b/v2/assets/css/style.css index 685888e..0f97202 100644 --- a/v2/assets/css/style.css +++ b/v2/assets/css/style.css @@ -202,7 +202,7 @@ select { .border-radius-4 { border-radius: 4px !important; } -textarea, input[type="text"], input[type="password"] { +textarea, input[type="text"], input[type="password"], input[type="number"] { -webkit-appearance: none; /* Remove inner shadow from inputs on mobile iOS */ /*background: inherit;*/ @@ -519,6 +519,10 @@ td.center-align { padding-right: 20px !important; /*padding-top:7px !important;*/ } +.side-margin-3 { + margin-left: 3px !important; + margin-right: 3px !important; +} .top-margin-14 { margin-top: 14px; } diff --git a/v2/index.html b/v2/index.html index de1452c..d5f1e4f 100644 --- a/v2/index.html +++ b/v2/index.html @@ -54,6 +54,7 @@ + diff --git a/v2/src/app/appDev.js b/v2/src/app/appDev.js index e09c6e6..2abe170 100644 --- a/v2/src/app/appDev.js +++ b/v2/src/app/appDev.js @@ -23,25 +23,47 @@ compassAppDev.run(function($httpBackend, settings, $http) { "display": "OpenStack", "os_installer": "cobbler", "package_installer": "chef", - "roles": [{ - "display_name": "Compute", - "name": "os-compute-worker" - }, { - "display_name": "Controller", - "name": "os-controller" - }, { - "display_name": "Network", - "name": "os-network" - }, { - "display_name": "Storage", - "name": "os-block-storage-worker" - }], "supported_oses": [{ "name": "CentOs", "id": 1 }, { "name": "Ubuntu", "id": 2 + }], + "flavors": [{ + "display_name": "allinone", + "id": 1, + "name": "allinone", + "roles": [{ + "display_name": "Compute", + "name": "os-compute-worker" + }, { + "display_name": "Controller", + "name": "os-controller" + }, { + "display_name": "Network", + "name": "os-network" + }, { + "display_name": "Storage", + "name": "os-block-storage-worker" + }] + }, { + "display_name": "multiroles", + "id": 2, + "name": "multiroles", + "roles": [{ + "display_name": "Compute", + "name": "os-compute-worker" + }, { + "display_name": "Controller", + "name": "os-controller" + }, { + "display_name": "Network", + "name": "os-network" + }, { + "display_name": "Storage", + "name": "os-block-storage-worker" + }] }] }, { "id": 2, @@ -434,7 +456,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { "create_by": "user@someemail.com", "create_at": "2014-3-25 12:00:00", "updated_at": "2014-3-26 13:00:00", - " links": [{ + "links": [{ "href": "/clusters/1", "rel": "self" }, { @@ -452,7 +474,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { "create_by": "user@someemail.com", "create_at": "2014-3-25 12:00:00", "updated_at": "2014-3-28 14:00:00", - " links": [{ + "links": [{ "href": "/clusters/1", "rel": "self" }, { @@ -470,7 +492,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { "create_by": "user@someemail.com", "create_at": "2014-3-25 12:00:00", "updated_at": "2014-5-26 09:00:00", - " links": [{ + "links": [{ "href": "/clusters/1", "rel": "self" }, { @@ -488,7 +510,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { "create_by": "user@someemail.com", "create_at": "2014-3-25 12:00:00", "updated_at": "2014-3-19 08:00:00", - " links": [{ + "links": [{ "href": "/clusters/1", "rel": "self" }, { @@ -506,7 +528,7 @@ compassAppDev.run(function($httpBackend, settings, $http) { "create_by": "user@someemail.com", "create_at": "2014-4-25 12:00:00", "updated_at": "2014-2-27 20:00:00", - " links": [{ + "links": [{ "href": "/clusters/2", "rel": "self" }, { @@ -530,7 +552,19 @@ compassAppDev.run(function($httpBackend, settings, $http) { "create_by": "user@someemail.com", "create_at": "2014-3-25 12:00:00", "updated_at": "2014-3-26 13:00:00", - " links": [{ + "flavor": { + "roles": [{ + "display_name": "Compute", + "name": "os-compute-worker" + }, { + "display_name": "Controller", + "name": "os-controller" + }, { + "display_name": "Network", + "name": "os-network" + }] + }, + "links": [{ "href": "/clusters/" + id, "rel": "self" }, { @@ -837,6 +871,11 @@ compassAppDev.run(function($httpBackend, settings, $http) { return [200, hosts, {}]; }); + $httpBackend.whenPUT(/\.*\/clusters\/([0-9]|[1-9][0-9])\/hosts\/([0-9]|[1-9][0-9])$/).respond(function(method, url, data) { + var updateData = JSON.parse(data); + return [200, updateData, {}]; + }) + $httpBackend.whenPUT(/\.*\/clusters\/[1-9][0-9]*\/hosts\/[1-9][0-9]*\/config/).respond(function(method, url, data) { console.log(method, url, data); var config = JSON.parse(data); diff --git a/v2/src/app/monitoring/alerts.tpl.html b/v2/src/app/monitoring/alerts.tpl.html index 06243e9..267ba57 100644 --- a/v2/src/app/monitoring/alerts.tpl.html +++ b/v2/src/app/monitoring/alerts.tpl.html @@ -5,26 +5,32 @@
- - Alerts -
- - - -
-
-
- - - Alarms! - - Alarms - TBD - - Event Viewer - TBD - -
+ + +
+ + + +
+
+ +
+
+ + + Alarms + + Alarms - TBD + + + + Event Viewer + + Event Viewer - TBD + +
diff --git a/v2/src/app/monitoring/monitoring.js b/v2/src/app/monitoring/monitoring.js index 0f53741..4e1c7ba 100644 --- a/v2/src/app/monitoring/monitoring.js +++ b/v2/src/app/monitoring/monitoring.js @@ -40,6 +40,36 @@ angular.module('compass.monitoring', [ {"start":1406774590378,"end":1406850781190} ]} ]}; + + $scope.alerts = [ + {"startDate":new Date("Sun Dec 09 01:36:45 EST 2012"),"endDate":new Date("Sun Dec 09 02:36:45 EST 2012"),"name":"host-01","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 04:56:32 EST 2012"),"endDate":new Date("Sun Dec 09 06:35:47 EST 2012"),"name":"host-05","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 06:29:53 EST 2012"),"endDate":new Date("Sun Dec 09 06:34:04 EST 2012"),"name":"host-02","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 05:35:21 EST 2012"),"endDate":new Date("Sun Dec 09 06:21:22 EST 2012"),"name":"host-01","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 05:00:06 EST 2012"),"endDate":new Date("Sun Dec 09 05:05:07 EST 2012"),"name":"host-03","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 03:46:59 EST 2012"),"endDate":new Date("Sun Dec 09 04:54:19 EST 2012"),"name":"host-01","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 04:02:45 EST 2012"),"endDate":new Date("Sun Dec 09 04:48:56 EST 2012"),"name":"host-02","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 03:27:35 EST 2012"),"endDate":new Date("Sun Dec 09 03:58:43 EST 2012"),"name":"host-03","status":"SUCCEEDED"}, + {"startDate":new Date("Sun Dec 09 01:40:11 EST 2012"),"endDate":new Date("Sun Dec 09 03:26:35 EST 2012"),"name":"host-04","status":"SUCCEEDED"}, + {"startDate":new Date("Sun Dec 09 03:00:03 EST 2012"),"endDate":new Date("Sun Dec 09 03:09:51 EST 2012"),"name":"host-05","status":"SUCCEEDED"}, + {"startDate":new Date("Sun Dec 09 01:21:00 EST 2012"),"endDate":new Date("Sun Dec 09 02:51:42 EST 2012"),"name":"host-01","status":"SUCCEEDED"}, + {"startDate":new Date("Sun Dec 09 01:08:42 EST 2012"),"endDate":new Date("Sun Dec 09 01:33:42 EST 2012"),"name":"host-04","status":"CRITICAL"}, + {"startDate":new Date("Sun Dec 09 00:27:15 EST 2012"),"endDate":new Date("Sun Dec 09 00:54:56 EST 2012"),"name":"host-04","status":"SUCCEEDED"}, + {"startDate":new Date("Sun Dec 09 00:29:48 EST 2012"),"endDate":new Date("Sun Dec 09 00:44:50 EST 2012"),"name":"host-01","status":"SUCCEEDED"}, + {"startDate":new Date("Sun Dec 09 07:39:21 EST 2012"),"endDate":new Date("Sun Dec 09 07:43:22 EST 2012"),"name":"host-03","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 07:00:06 EST 2012"),"endDate":new Date("Sun Dec 09 07:05:07 EST 2012"),"name":"host-02","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 08:46:59 EST 2012"),"endDate":new Date("Sun Dec 09 09:54:19 EST 2012"),"name":"host-02","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 09:02:45 EST 2012"),"endDate":new Date("Sun Dec 09 09:48:56 EST 2012"),"name":"host-01","status":"WARNING"}, + {"startDate":new Date("Sun Dec 09 08:27:35 EST 2012"),"endDate":new Date("Sun Dec 09 08:58:43 EST 2012"),"name":"host-05","status":"SUCCEEDED"}, + {"startDate":new Date("Sun Dec 09 08:40:11 EST 2012"),"endDate":new Date("Sun Dec 09 08:46:35 EST 2012"),"name":"host-03","status":"SUCCEEDED"}, + {"startDate":new Date("Sun Dec 09 08:00:03 EST 2012"),"endDate":new Date("Sun Dec 09 08:09:51 EST 2012"),"name":"host-02","status":"SUCCEEDED"}, + {"startDate":new Date("Sun Dec 09 10:21:00 EST 2012"),"endDate":new Date("Sun Dec 09 10:51:42 EST 2012"),"name":"host-04","status":"SUCCEEDED"}, + {"startDate":new Date("Sun Dec 09 11:08:42 EST 2012"),"endDate":new Date("Sun Dec 09 11:33:42 EST 2012"),"name":"host-04","status":"CRITICAL"}, + {"startDate":new Date("Sun Dec 09 12:27:15 EST 2012"),"endDate":new Date("Sun Dec 09 12:54:56 EST 2012"),"name":"host-02","status":"SUCCEEDED"}, + {"startDate":new Date("Sat Dec 08 23:12:24 EST 2012"),"endDate":new Date("Sun Dec 09 00:26:13 EST 2012"),"name":"host-01","status":"UNKNOWN"}]; + + $scope.hosts = ["host-01", "host-02", "host-03", "host-04", "host-05"]; + } ]) diff --git a/v2/src/app/monitoring/topology.tpl.html b/v2/src/app/monitoring/topology.tpl.html index 0d93a0f..d9d9b45 100644 --- a/v2/src/app/monitoring/topology.tpl.html +++ b/v2/src/app/monitoring/topology.tpl.html @@ -5,14 +5,15 @@
- - Layer 2/3 Topology - - - - Service Diagram - - - + + + Layer 2/3 Topology + + + + Service Diagram + + +
diff --git a/v2/src/app/services.js b/v2/src/app/services.js index 16a47da..76ba194 100644 --- a/v2/src/app/services.js +++ b/v2/src/app/services.js @@ -173,6 +173,10 @@ angular.module('compass.services', []) return $http.get(settings.apiUrlBase + '/clusters/' + clusterId + '/hosts'); }; + this.updateClusterHost = function(clusterId, hostId, data) { + return $http.put(settings.apiUrlBase + '/clusters/' + clusterId + '/hosts/' + hostId, angular.toJson(data)); + }; + this.updateClusterHostConfig = function(clusterId, hostId, config) { return $http.put(settings.apiUrlBase + '/clusters/' + clusterId + '/hosts/' + hostId + '/config', angular.toJson(config)); }; @@ -217,7 +221,7 @@ angular.module('compass.services', []) wizard.commit = {}; wizard.servers = []; wizard.allServers = []; - wizard.adapter = {}; // + //wizard.adapter = {}; // wizard.generalConfig = {}; wizard.subnetworks = []; wizard.routingtable = []; @@ -282,7 +286,7 @@ angular.module('compass.services', []) wizard.getServers = function() { return angular.copy(wizard.servers); }; - +/* wizard.setAdapter = function(adapter) { //// wizard.adapter = adapter; }; @@ -290,7 +294,7 @@ angular.module('compass.services', []) wizard.getAdapter = function() { ///// return angular.copy(wizard.adapter); }; - +*/ wizard.setGeneralConfig = function(config) { wizard.generalConfig = config; }; diff --git a/v2/src/app/wizard/partition.tpl.html b/v2/src/app/wizard/partition.tpl.html index 2eeee8a..a27e714 100644 --- a/v2/src/app/wizard/partition.tpl.html +++ b/v2/src/app/wizard/partition.tpl.html @@ -16,15 +16,15 @@ - + - + - - - + + + @@ -33,11 +33,11 @@ {{data.percentage}} - + {{data.max_size}} - + diff --git a/v2/src/app/wizard/role_assignment.tpl.html b/v2/src/app/wizard/role_assignment.tpl.html index 94719be..a1d2c9b 100644 --- a/v2/src/app/wizard/role_assignment.tpl.html +++ b/v2/src/app/wizard/role_assignment.tpl.html @@ -53,7 +53,7 @@
- + ' + + '' + + '' + + '' + + '' + + '
' + + '
', + link: function(scope, element, attrs) { + var tasks = scope.data; + var hostnames = scope.hosts; + var taskStatus = { + "SUCCEEDED": "bar", + "CRITICAL": "bar-failed", + "WARNING": "bar-running", + "UNKNOWN": "bar-killed" + }; + + tasks.sort(function(a, b) { + return a.endDate - b.endDate; + }); + var maxDate = tasks[tasks.length - 1].endDate; + tasks.sort(function(a, b) { + return a.startDate - b.startDate; + }); + var minDate = tasks[0].startDate; + + var format = "%H:%M"; + var timeDomainString = "1day"; + + var gantt = d3.gantt().taskTypes(hostnames).taskStatus(taskStatus).tickFormat(format).height(450).width(800); + + scope.changeTimeDomain = function(timeDomainString) { + this.timeDomainString = timeDomainString; + switch (timeDomainString) { + case "1hr": + format = "%H:%M:%S"; + gantt.timeDomain([d3.time.hour.offset(getEndDate(), -1), getEndDate()]); + break; + case "3hr": + format = "%H:%M"; + gantt.timeDomain([d3.time.hour.offset(getEndDate(), -3), getEndDate()]); + break; + + case "6hr": + format = "%H:%M"; + gantt.timeDomain([d3.time.hour.offset(getEndDate(), -6), getEndDate()]); + break; + + case "1day": + format = "%H:%M"; + gantt.timeDomain([d3.time.day.offset(getEndDate(), -1), getEndDate()]); + break; + + case "1week": + format = "%a %H:%M"; + gantt.timeDomain([d3.time.day.offset(getEndDate(), -7), getEndDate()]); + break; + default: + format = "%H:%M" + + } + gantt.tickFormat(format); + gantt.redraw(tasks); + } + + gantt.timeDomainMode("fixed"); + scope.changeTimeDomain(timeDomainString); + + gantt(tasks); + + + + function getEndDate() { + var lastEndDate = Date.now(); + if (tasks.length > 0) { + lastEndDate = tasks[tasks.length - 1].endDate; + } + + return lastEndDate; + } + + } + } + +}) diff --git a/v2/src/common/gantt-chart-d3v2.js b/v2/src/common/gantt-chart-d3v2.js new file mode 100644 index 0000000..63a82f2 --- /dev/null +++ b/v2/src/common/gantt-chart-d3v2.js @@ -0,0 +1,221 @@ +/** + * @author Dimitry Kudrayvtsev + * @version 2.0 + */ + +d3.gantt = function() { + var FIT_TIME_DOMAIN_MODE = "fit"; + var FIXED_TIME_DOMAIN_MODE = "fixed"; + + var margin = { + top : 20, + right : 40, + bottom : 20, + left : 150 + }; + var timeDomainStart = d3.time.day.offset(new Date(),-3); + var timeDomainEnd = d3.time.hour.offset(new Date(),+3); + var timeDomainMode = FIT_TIME_DOMAIN_MODE;// fixed or fit + var taskTypes = []; + var taskStatus = []; + var height = document.body.clientHeight - margin.top - margin.bottom-5; + var width = document.body.clientWidth - margin.right - margin.left-5; + + var tickFormat = "%H:%M"; + + var keyFunction = function(d) { + return d.startDate + d.name + d.endDate; + }; + + var rectTransform = function(d) { + return "translate(" + x(d.startDate) + "," + y(d.name) + ")"; + }; + + var x = d3.time.scale().domain([ timeDomainStart, timeDomainEnd ]).range([ 0, width ]).clamp(true); + + var y = d3.scale.ordinal().domain(taskTypes).rangeRoundBands([ 0, height - margin.top - margin.bottom ], .1); + + var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format(tickFormat)).tickSubdivide(true) + .tickSize(8).tickPadding(8); + + var yAxis = d3.svg.axis().scale(y).orient("left").tickSize(0); + + var initTimeDomain = function() { + if (timeDomainMode === FIT_TIME_DOMAIN_MODE) { + if (tasks === undefined || tasks.length < 1) { + timeDomainStart = d3.time.day.offset(new Date(), -3); + timeDomainEnd = d3.time.hour.offset(new Date(), +3); + return; + } + tasks.sort(function(a, b) { + return a.endDate - b.endDate; + }); + timeDomainEnd = tasks[tasks.length - 1].endDate; + tasks.sort(function(a, b) { + return a.startDate - b.startDate; + }); + timeDomainStart = tasks[0].startDate; + } + }; + + var initAxis = function() { + x = d3.time.scale().domain([ timeDomainStart, timeDomainEnd ]).range([ 0, width ]).clamp(true); + y = d3.scale.ordinal().domain(taskTypes).rangeRoundBands([ 0, height - margin.top - margin.bottom ], .1); + xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(d3.time.format(tickFormat)).tickSubdivide(true) + .tickSize(8).tickPadding(8); + + yAxis = d3.svg.axis().scale(y).orient("left").tickSize(0); + }; + + function gantt(tasks) { + + initTimeDomain(); + initAxis(); + + var svg = d3.select("ganttchart") + .append("svg") + .attr("class", "chart") + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.top + margin.bottom) + .append("g") + .attr("class", "gantt-chart") + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.top + margin.bottom) + .attr("transform", "translate(" + margin.left + ", " + margin.top + ")"); + + svg.selectAll(".chart") + .data(tasks, keyFunction).enter() + .append("rect") + .attr("rx", 5) + .attr("ry", 5) + .attr("class", function(d){ + if(taskStatus[d.status] == null){ return "bar";} + return taskStatus[d.status]; + }) + .attr("y", 0) + .attr("transform", rectTransform) + .attr("height", function(d) { return y.rangeBand(); }) + .attr("width", function(d) { + return (x(d.endDate) - x(d.startDate)); + }); + + + svg.append("g") + .attr("class", "x axis") + .attr("transform", "translate(0, " + (height - margin.top - margin.bottom) + ")") + .transition() + .call(xAxis); + + svg.append("g").attr("class", "y axis").transition().call(yAxis); + + return gantt; + + }; + + gantt.redraw = function(tasks) { + + initTimeDomain(); + initAxis(); + + var svg = d3.select("svg"); + + var ganttChartGroup = svg.select(".gantt-chart"); + var rect = ganttChartGroup.selectAll("rect").data(tasks, keyFunction); + + rect.enter() + .insert("rect",":first-child") + .attr("rx", 5) + .attr("ry", 5) + .attr("class", function(d){ + if(taskStatus[d.status] == null){ return "bar";} + return taskStatus[d.status]; + }) + .transition() + .attr("y", 0) + .attr("transform", rectTransform) + .attr("height", function(d) { return y.rangeBand(); }) + .attr("width", function(d) { + return (x(d.endDate) - x(d.startDate)); + }); + + rect.transition() + .attr("transform", rectTransform) + .attr("height", function(d) { return y.rangeBand(); }) + .attr("width", function(d) { + return (x(d.endDate) - x(d.startDate)); + }); + + rect.exit().remove(); + + svg.select(".x").transition().call(xAxis); + svg.select(".y").transition().call(yAxis); + + return gantt; + }; + + gantt.margin = function(value) { + if (!arguments.length) + return margin; + margin = value; + return gantt; + }; + + gantt.timeDomain = function(value) { + if (!arguments.length) + return [ timeDomainStart, timeDomainEnd ]; + timeDomainStart = +value[0], timeDomainEnd = +value[1]; + return gantt; + }; + + /** + * @param {string} + * vale The value can be "fit" - the domain fits the data or + * "fixed" - fixed domain. + */ + gantt.timeDomainMode = function(value) { + if (!arguments.length) + return timeDomainMode; + timeDomainMode = value; + return gantt; + + }; + + gantt.taskTypes = function(value) { + if (!arguments.length) + return taskTypes; + taskTypes = value; + return gantt; + }; + + gantt.taskStatus = function(value) { + if (!arguments.length) + return taskStatus; + taskStatus = value; + return gantt; + }; + + gantt.width = function(value) { + if (!arguments.length) + return width; + width = +value; + return gantt; + }; + + gantt.height = function(value) { + if (!arguments.length) + return height; + height = +value; + return gantt; + }; + + gantt.tickFormat = function(value) { + if (!arguments.length) + return tickFormat; + tickFormat = value; + return gantt; + }; + + + + return gantt; +}; \ No newline at end of file