-
Notifications
You must be signed in to change notification settings - Fork 359
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a dashboard view for a physical infra provider
- Loading branch information
Showing
21 changed files
with
470 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
app/assets/javascripts/controllers/ems_infra_dashboard/utilization_trend_chart_controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
...ascripts/controllers/ems_physical_infra_dashboard/recent_servers_line_chart_controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* global miqHttpInject */ | ||
angular.module( 'patternfly.charts' ).controller( 'recentServersLineChartController', ['$q', 'providerId', '$http', 'chartsMixin', 'miqService', function($q, providerId, $http, chartsMixin, miqService) { | ||
var vm = this; | ||
vm.id = "recentServersLineChart_" + providerId; | ||
var init = function() { | ||
ManageIQ.angular.scope = vm; | ||
vm.loadingDone = false; | ||
vm.config = chartsMixin.chartConfig.recentServersConfig; | ||
vm.timeframeLabel = __('Last 30 Days'); | ||
var url = '/ems_physical_infra_dashboard/recent_servers_data/' + providerId; | ||
var serversDataPromise = $http.get(url) | ||
.then(function(response) { | ||
vm.data = response.data.data; | ||
}) | ||
.catch(miqService.handleFailure); | ||
|
||
$q.all([serversDataPromise]).then(function() { | ||
if (vm.data.recentServers.dataAvailable === false) { | ||
vm.data.dataAvailable = false; | ||
} else { | ||
vm.data = chartsMixin.processData(vm.data.recentServers, 'dates', vm.data.recentServers.config.label); | ||
} | ||
Object.assign(vm.config, vm.data); | ||
vm.loadingDone = true; | ||
}); | ||
|
||
vm.custShowXAxis = false; | ||
vm.custShowYAxis = false; | ||
vm.custAreaChart = true; | ||
}; | ||
|
||
init(); | ||
}]); |
63 changes: 63 additions & 0 deletions
63
app/assets/javascripts/controllers/ems_physical_infra_dashboard/status_card_controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* global miqHttpInject */ | ||
|
||
angular.module( 'patternfly.card' ).controller('statusCardController', ['$q', 'providerId', 'API', 'miqService', 'chartsMixin', function($q, providerId, API, miqService, chartsMixin) { | ||
var vm = this; | ||
var attributes = ["physical_servers", "physical_racks"]; | ||
|
||
var attrIconHsh = { | ||
"physical_servers": "pficon pficon-cluster", | ||
"physical_racks": "pficon pficon-enterprise", | ||
}; | ||
|
||
var attrUrl = { | ||
"physical_servers": "physical_servers", | ||
"physical_racks": "physical_racks", | ||
}; | ||
|
||
var init = function() { | ||
ManageIQ.angular.scope = vm; | ||
var promiseProviderData = API.get("/api/providers/" + providerId + "?attributes=" + attributes) | ||
.then(function(data) { | ||
vm.provider = data; | ||
}) | ||
.catch(miqService.handleFailure); | ||
|
||
$q.all([promiseProviderData]).then(function() { | ||
vm.status = { | ||
"iconImage": "/assets/svg/vendor-" + getIcon(vm.provider.type) + ".svg", | ||
"largeIcon": true, | ||
}; | ||
|
||
var attrHsh = { | ||
"physical_servers": "Servers", | ||
"physical_racks": "Racks", | ||
}; | ||
|
||
vm.AggStatus = []; | ||
for (var i = 0; i < attributes.length; i++) { | ||
vm.AggStatus.push({ | ||
"id": attrHsh[attributes[i]] + '_' + providerId, | ||
"iconClass": attrIconHsh[attributes[i]], | ||
"title": __(attrHsh[attributes[i]]), | ||
"count": vm.provider[attributes[i]].length, | ||
"href": getUrl(attributes[i]), | ||
"notification": { | ||
"iconClass": "pficon pficon-error-circle-o", | ||
"count": 0, | ||
}, | ||
}); | ||
} | ||
}); | ||
}; | ||
|
||
var getIcon = function getIcon(providerType) { | ||
var type = providerType.split("::"); | ||
return type[2].toLowerCase(); | ||
}; | ||
|
||
var getUrl = function(entity) { | ||
return providerId + "?display=" + attrUrl[entity]; | ||
}; | ||
|
||
init(); | ||
}]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
app/controllers/ems_physical_infra_dashboard_controller.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
class EmsPhysicalInfraDashboardController < ApplicationController | ||
extend ActiveSupport::Concern | ||
|
||
before_action :check_privileges | ||
before_action :get_session_data | ||
after_action :cleanup_action | ||
after_action :set_session_data | ||
|
||
def show | ||
if params[:id].nil? | ||
@breadcrumbs.clear | ||
end | ||
end | ||
|
||
def data | ||
render :json => {:data => collect_data(params[:id])} | ||
end | ||
|
||
def cluster_metrics_data | ||
render :json => {:data => cluster_heatmap_data(params[:id])} | ||
end | ||
|
||
def recent_servers_data | ||
render :json => {:data => recent_servers(params[:id])} | ||
end | ||
|
||
def recent_vms_data | ||
render :json => {:data => recent_vms(params[:id])} | ||
end | ||
|
||
def ems_utilization_data | ||
render :json => {:data => ems_data(params[:id])} | ||
end | ||
|
||
private | ||
|
||
def collect_data(ems_id) | ||
EmsPhysicalInfraDashboardService.new(ems_id, self).all_data | ||
end | ||
|
||
def cluster_heatmap_data(ems_id) | ||
EmsPhysicalInfraDashboardService.new(ems_id, self).cluster_heatmap_data | ||
end | ||
|
||
def recent_servers(ems_id) | ||
EmsPhysicalInfraDashboardService.new(ems_id, self).recent_servers_data | ||
end | ||
|
||
def recent_vms(ems_id) | ||
EmsPhysicalInfraDashboardService.new(ems_id, self).recent_vms_data | ||
end | ||
|
||
def ems_data(ems_id) | ||
EmsPhysicalInfraDashboardService.new(ems_id, self).ems_utilization_data | ||
end | ||
|
||
def get_session_data | ||
@layout = "ems_physical_infra_dashboard" | ||
end | ||
|
||
def set_session_data | ||
session[:layout] = @layout | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
class EmsPhysicalInfraDashboardService < DashboardService | ||
include UiServiceMixin | ||
CPU_USAGE_PRECISION = 2 # 2 decimal points | ||
|
||
def initialize(ems_id, controller) | ||
@ems_id = ems_id | ||
@ems = EmsPhysicalInfra.find(@ems_id) unless @ems_id.blank? | ||
@controller = controller | ||
end | ||
|
||
def cluster_heatmap_data | ||
{ | ||
:heatmaps => heatmaps | ||
}.compact | ||
end | ||
|
||
def recent_servers_data | ||
{ | ||
:recentServers => recent_servers | ||
}.compact | ||
end | ||
|
||
def recent_vms_data | ||
{ | ||
:recentVms => recentVms | ||
}.compact | ||
end | ||
|
||
def ems_utilization_data | ||
{ | ||
:ems_utilization => ems_utilization | ||
}.compact | ||
end | ||
|
||
def heatmaps | ||
# Get latest hourly rollup for each node. | ||
cluster_ids = @ems.ems_clusters if @ems.present? | ||
metrics = MetricRollup.latest_rollups(EmsCluster.name, cluster_ids) | ||
metrics = metrics.where('timestamp > ?', 30.days.ago.utc).includes(:resource) | ||
metrics = metrics.includes(:resource => [:ext_management_system]) unless @ems.present? | ||
|
||
cluster_cpu_usage = [] | ||
cluster_memory_usage = [] | ||
|
||
metrics.each do |m| | ||
next if m.resource.nil? # Metrics are purged asynchronously and might be missing their node | ||
provider_name = @ems.present? ? @ems.name : m.resource.ext_management_system.name | ||
|
||
cluster_cpu_usage << { | ||
:id => m.resource.id, | ||
:node => m.resource.name, | ||
:provider => provider_name, | ||
:unit => "Cores", | ||
:total => m.derived_vm_numvcpus.present? ? m.derived_vm_numvcpus.round : nil, | ||
:percent => m.cpu_usage_rate_average.present? ? | ||
(m.cpu_usage_rate_average / 100.0).round(CPU_USAGE_PRECISION) : nil # pf accepts fractions 90% = 0.90 | ||
} | ||
|
||
cluster_memory_usage << { | ||
:id => m.resource.id, | ||
:node => m.resource.name, | ||
:provider => m.resource.ext_management_system.name, | ||
:unit => "GB", | ||
:total => m.derived_memory_available.present? ? (m.derived_memory_available / 1024).round : nil, | ||
:percent => m.mem_usage_absolute_average.present? ? | ||
(m.mem_usage_absolute_average / 100.0).round(CPU_USAGE_PRECISION) : nil # pf accepts fractions 90% = 0.90 | ||
} | ||
end | ||
|
||
{ | ||
:clusterCpuUsage => cluster_cpu_usage.presence, | ||
:clusterMemoryUsage => cluster_memory_usage.presence, | ||
:title => openstack? ? _('Deployment Roles Utilization') : _('Cluster Utilization') | ||
} | ||
end | ||
|
||
def recent_servers | ||
# Get recent servers | ||
all_servers = recentRecords(PhysicalServer) | ||
config = { | ||
:title => _('Recent Servers'), | ||
:label => _('Servers') | ||
} | ||
return { :dataAvailable => false, :config => config} if all_servers.blank? | ||
{ | ||
:dataAvailable => true, | ||
:xData => all_servers.keys, | ||
:yData => all_servers.values.map, | ||
:config => config | ||
} | ||
end | ||
|
||
def recentVms | ||
# Get recent VMs | ||
all_vms = recentRecords(VmOrTemplate) | ||
config = { | ||
:title => _('Recent VMs'), | ||
:label => _('VMs'), | ||
} | ||
return { :dataAvailable => false, :config => config } if all_vms.blank? | ||
{ | ||
:dataAvailable => true, | ||
:xData => all_vms.keys, | ||
:yData => all_vms.values.map, | ||
:config => config | ||
} | ||
end | ||
|
||
def recentRecords(model) | ||
all_records = Hash.new(0) | ||
records = model.where('created_at > ? and ems_id = ?', 30.days.ago.utc, @ems.id) | ||
records = records.includes(:resource => [:ext_management_system]) unless @ems.present? | ||
records.sort_by { |r| r.created_at }.uniq.each do |r| | ||
date = r.created_at.strftime("%Y-%m-%d") | ||
all_records[date] += model.where('created_at = ?', r.created_at).count | ||
end | ||
all_records | ||
end | ||
|
||
def ems_utilization | ||
used_cpu = Hash.new(0) | ||
used_mem = Hash.new(0) | ||
total_cpu = Hash.new(0) | ||
total_mem = Hash.new(0) | ||
|
||
daily_provider_metrics.each do |metric| | ||
date = metric.timestamp.strftime("%Y-%m-%d") | ||
used_cpu[date] += metric.v_derived_cpu_total_cores_used if metric.v_derived_cpu_total_cores_used.present? | ||
used_mem[date] += metric.derived_memory_used if metric.derived_memory_used.present? | ||
total_cpu[date] += metric.derived_vm_numvcpus if metric.derived_vm_numvcpus.present? | ||
total_mem[date] += metric.derived_memory_available if metric.derived_memory_available.present? | ||
end | ||
|
||
format_utilization_data(used_cpu, used_mem, total_cpu, total_mem) | ||
end | ||
|
||
def daily_provider_metrics | ||
current_user = @controller.current_user | ||
tp = TimeProfile.profile_for_user_tz(current_user.id, current_user.get_timezone) || TimeProfile.default_time_profile | ||
|
||
@daily_metrics ||= Metric::Helper.find_for_interval_name('daily', tp) | ||
.where(:resource => (@ems || ManageIQ::Providers::InfraManager.all)) | ||
.where('timestamp > ?', 30.days.ago.utc).order('timestamp') | ||
end | ||
|
||
def openstack? | ||
@ems.kind_of?(ManageIQ::Providers::Openstack::InfraManager) | ||
end | ||
end |
Oops, something went wrong.