diff --git a/app/models/ext_management_system.rb b/app/models/ext_management_system.rb index 56cd3c3aea6..22237d1faed 100644 --- a/app/models/ext_management_system.rb +++ b/app/models/ext_management_system.rb @@ -153,7 +153,7 @@ def hostname_format_valid? virtual_total :total_miq_templates, :miq_templates virtual_total :total_hosts, :hosts virtual_total :total_storages, :storages - virtual_total :total_clusters, :clusters + virtual_total :total_clusters, :ems_clusters virtual_column :zone_name, :type => :string, :uses => :zone virtual_column :total_vms_on, :type => :integer virtual_column :total_vms_off, :type => :integer @@ -678,6 +678,31 @@ def tenant_identity User.super_admin.tap { |u| u.current_group = tenant.default_miq_group } end + def self.inventory_status + data = includes(:zone) + .select(:id, :parent_ems_id, :zone_id, :type, :name, :total_hosts, :total_vms, :total_clusters) + .map do |ems| + [ + ems.region_id, ems.zone.name, ems.class.short_token, ems.name, + ems.total_clusters, ems.total_hosts, ems.total_vms, ems.total_storages, + ems.try(:containers).try(:count) + ] + end + return if data.empty? + data = data.sort_by { |e| [e[0], e[1], e[2], e[3]] } + # remove 0's (except for the region) + data = data.map { |row| row.each_with_index.map { |col, i| i.positive? && col.to_s == "0" ? nil : col } } + data.unshift(%w(region zone kind ems clusters hosts vms storages containers)) + # remove columns where all values (except for the header) are blank + data.first.dup.each do |col_header| + col = data.first.index(col_header) + if data[1..-1].none? { |row| row[col] } + data.each { |row| row.delete_at(col) } + end + end + data + end + private def build_connection(options = {}) diff --git a/app/models/host.rb b/app/models/host.rb index 0cef31f3fe8..b48a1bcccb8 100644 --- a/app/models/host.rb +++ b/app/models/host.rb @@ -146,7 +146,7 @@ class Host < ApplicationRecord virtual_has_many :event_logs, :uses => {:operating_system => :event_logs} virtual_has_many :firewall_rules, :uses => {:operating_system => :firewall_rules} - virtual_total :v_total_storages, :storages + virtual_total :v_total_storages, :host_storages virtual_total :v_total_vms, :vms virtual_total :v_total_miq_templates, :miq_templates diff --git a/lib/tasks/evm.rake b/lib/tasks/evm.rake index b3a9a0df2cd..689c658f2a8 100644 --- a/lib/tasks/evm.rake +++ b/lib/tasks/evm.rake @@ -50,6 +50,12 @@ namespace :evm do EvmApplication.status(true) end + desc "Describe inventory of the ManageIQ EVM Application" + task :inventory => :environment do + inventory = ExtManagementSystem.inventory_status + puts inventory.tableize if inventory.present? + end + desc "Write a remote region id to this server's REGION file" task :join_region => :environment do configured_region = ApplicationRecord.region_number_from_sequence.to_i diff --git a/spec/lib/extensions/virtual_total_spec.rb b/spec/lib/extensions/virtual_total_spec.rb index 895160a4b15..3b0dd71edd9 100644 --- a/spec/lib/extensions/virtual_total_spec.rb +++ b/spec/lib/extensions/virtual_total_spec.rb @@ -362,21 +362,23 @@ def model_with_children(count) end end - describe ".virtual_total (with through relation (host#v_total_storages)" do - let(:base_model) { Host } + describe ".virtual_total (with through relation (ems#total_storages)" do + let(:base_model) { ExtManagementSystem } it "calculates totals locally" do - expect(model_with_children(0).v_total_storages).to eq(0) - expect(model_with_children(2).v_total_storages).to eq(2) + expect(model_with_children(0).total_storages).to eq(0) + expect(model_with_children(2).total_storages).to eq(2) end it "is not defined in sql" do - expect(base_model.attribute_supported_by_sql?(:v_total_storages)).to be(false) + expect(base_model.attribute_supported_by_sql?(:total_storages)).to be(false) end def model_with_children(count) - FactoryGirl.create(:host).tap do |host| - count.times { host.storages.create(FactoryGirl.attributes_for(:storage)) } + FactoryGirl.create(:ext_management_system).tap do |ems| + ems.hosts.create(FactoryGirl.attributes_for(:host)).tap do |host| + count.times { host.storages.create(FactoryGirl.attributes_for(:storage)) } + end end.reload end end diff --git a/spec/models/ext_management_system_spec.rb b/spec/models/ext_management_system_spec.rb index 09ece6b9f63..8182a50ba2d 100644 --- a/spec/models/ext_management_system_spec.rb +++ b/spec/models/ext_management_system_spec.rb @@ -495,4 +495,28 @@ def deliver_queue_message(queue_message = MiqQueue.order(:id).first) expect(ManageIQ::Providers::Amazon::CloudManager.raw_connect?).to eq(true) end end + + describe ".inventory_status" do + it "works with infra providers" do + ems = FactoryGirl.create(:ems_infra) + host = FactoryGirl.create(:host, :ext_management_system => ems) + FactoryGirl.create(:vm_infra, :ext_management_system => ems, :host => host) + FactoryGirl.create(:vm_infra, :ext_management_system => ems, :host => host) + + result = ExtManagementSystem.inventory_status + expect(result.size).to eq(2) + expect(result[0]).to eq(%w(region zone kind ems hosts vms)) + expect(result[1][4..-1]).to eq([1, 2]) + end + + it "works with container providers" do + ems = FactoryGirl.create(:ems_container) + FactoryGirl.create(:container, :ems_id => ems.id) + FactoryGirl.create(:container, :ems_id => ems.id) + result = ExtManagementSystem.inventory_status + expect(result.size).to eq(2) + expect(result[0]).to eq(%w(region zone kind ems containers)) + expect(result[1][4..-1]).to eq([2]) + end + end end diff --git a/spec/models/host_spec.rb b/spec/models/host_spec.rb index de2fc1c7f48..333dd82a45e 100644 --- a/spec/models/host_spec.rb +++ b/spec/models/host_spec.rb @@ -375,7 +375,6 @@ def assert_remote_credentials_validated host = FactoryGirl.create(:host) host.storages.create(FactoryGirl.attributes_for(:storage)) expect(host.v_total_storages).to eq(1) - expect(Host.attribute_supported_by_sql?(:v_total_storages)).to be false end end