diff --git a/app/models/manageiq/providers/vmware/infra_manager.rb b/app/models/manageiq/providers/vmware/infra_manager.rb index c649a7dbb..5b7b7010a 100644 --- a/app/models/manageiq/providers/vmware/infra_manager.rb +++ b/app/models/manageiq/providers/vmware/infra_manager.rb @@ -27,6 +27,11 @@ class Vmware::InfraManager < InfraManager supports :provisioning supports :smartstate_analysis + has_many :miq_scsi_targets, -> { distinct }, :through => :host_guest_devices + has_many :miq_scsi_luns, -> { distinct }, :through => :miq_scsi_targets + has_many :host_guest_devices, :through => :host_hardwares, :source => :guest_devices + has_many :host_system_services, :through => :hosts, :source => :system_services + def self.ems_type @ems_type ||= "vmwarews".freeze end diff --git a/app/models/manageiq/providers/vmware/infra_manager/inventory/inventory_collections.rb b/app/models/manageiq/providers/vmware/infra_manager/inventory/inventory_collections.rb index 0d3bc65fe..3008c0034 100644 --- a/app/models/manageiq/providers/vmware/infra_manager/inventory/inventory_collections.rb +++ b/app/models/manageiq/providers/vmware/infra_manager/inventory/inventory_collections.rb @@ -40,6 +40,62 @@ def storage_profiles(extra_attributes = {}) attributes.merge!(extra_attributes) end + def miq_scsi_targets(extra_attributes = {}) + attributes = { + :model_class => ::MiqScsiTarget, + :association => :miq_scsi_targets, + :manager_ref => %i(guest_device uid_ems), + :parent_inventory_collections => [:hosts], + } + + attributes.merge!(extra_attributes) + end + + def miq_scsi_luns(extra_attributes = {}) + attributes = { + :model_class => ::MiqScsiLun, + :association => :miq_scsi_luns, + :manager_ref => %i(miq_scsi_target uid_ems), + :parent_inventory_collections => [:hosts], + } + + attributes.merge!(extra_attributes) + end + + def host_guest_devices(extra_attributes = {}) + attributes = { + :model_class => ::GuestDevice, + :manager_ref => %i(hardware uid_ems), + :association => :host_guest_devices, + :parent_inventory_collections => [:hosts], + :inventory_object_attributes => %i( + address + controller_type + device_name + device_type + lan + location + network + present + switch + uid_ems + ), + } + + attributes.merge!(extra_attributes) + end + + def host_system_services(extra_attributes = {}) + attributes = { + :model_class => ::SystemService, + :manager_ref => %i(host name), + :association => :host_system_services, + :parent_inventory_collections => %i(hosts), + } + + attributes.merge!(extra_attributes) + end + def ems_folders(extra_attributes = {}) attributes = {:attributes_blacklist => %i(parent)} super(attributes.merge(extra_attributes)) diff --git a/app/models/manageiq/providers/vmware/infra_manager/inventory/parser.rb b/app/models/manageiq/providers/vmware/infra_manager/inventory/parser.rb index c4b327b15..0d33b4056 100644 --- a/app/models/manageiq/providers/vmware/infra_manager/inventory/parser.rb +++ b/app/models/manageiq/providers/vmware/infra_manager/inventory/parser.rb @@ -140,7 +140,6 @@ def parse_host_system(object, kind, props) parse_host_system_network(host_hash, props) parse_host_system_runtime(host_hash, props) parse_host_system_system_info(host_hash, props) - parse_host_system_children(host_hash, props) host_hash[:type] = if host_hash.include?(:vmm_product) && !%w(esx esxi).include?(host_hash[:vmm_product].to_s.downcase) "ManageIQ::Providers::Vmware::InfraManager::Host" diff --git a/app/models/manageiq/providers/vmware/infra_manager/inventory/parser/host_system.rb b/app/models/manageiq/providers/vmware/infra_manager/inventory/parser/host_system.rb index 94bc0f64b..f512525f9 100644 --- a/app/models/manageiq/providers/vmware/infra_manager/inventory/parser/host_system.rb +++ b/app/models/manageiq/providers/vmware/infra_manager/inventory/parser/host_system.rb @@ -99,10 +99,6 @@ def parse_host_system_system_info(host_hash, props) host_hash[:service_tag] = service_tag end - def parse_host_system_children(host_hash, props) - # TODO - end - def parse_host_system_operating_system(host, props) persister.host_operating_systems.build( :host => host, @@ -115,7 +111,17 @@ def parse_host_system_operating_system(host, props) end def parse_host_system_system_services(host, props) - # TODO + host_service_info = props.fetch_path(:config, :service, :service) + return if host_service_info.nil? + + host_service_info.each do |service| + persister.host_system_services.build( + :host => host, + :name => service[:key], + :display_name => service[:label], + :running => service[:running], + ) + end end def parse_host_system_hardware(host, props) @@ -158,15 +164,16 @@ def parse_host_system_hardware(host, props) hardware = persister.host_hardwares.build(hardware_hash) - parse_host_system_guest_devices(hardware, props) + parse_host_system_network_adapters(hardware, props) + parse_host_system_storage_adapters(hardware, props) end - def parse_host_system_guest_devices(hardware, props) + def parse_host_system_network_adapters(hardware, props) pnics = props.fetch_path(:config, :network, :pnic) pnics.to_a.each do |pnic| name = uid = pnic.device - persister.guest_devices.build( + persister.host_guest_devices.build( :hardware => hardware, :uid_ems => uid, :device_name => name, @@ -175,11 +182,70 @@ def parse_host_system_guest_devices(hardware, props) :present => true, :controller_type => 'ethernet', :address => pnic.mac, - # TODO: :switch => persister.switches.lazy_find(pnic.device) ) end + end + + def parse_host_system_scsi_luns(scsi_luns) + scsi_luns.to_a.each_with_object({}) do |lun, result| + if lun.kind_of?(RbVmomi::VIM::HostScsiDisk) + n_blocks = lun.capacity.block + block_size = lun.capacity.blockSize + capacity = (n_blocks * block_size) / 1024 + end + + lun_hash = { + :uid_ems => lun.uuid, + :canonical_name => lun.lunType, + :device_name => lun.deviceName, + :device_type => lun.deviceType, + :block => n_blocks, + :block_size => block_size, + :capacity => capacity, + } + + result[lun.key] = lun_hash + end + end - hbas = props.fetch_path(:config, :storageDevice, :hostBusAdapter) + def parse_host_system_scsi_targets(scsi_adapters, scsi_lun_uids) + scsi_adapters.to_a.each_with_object({}) do |adapter, result| + result[adapter.adapter] = adapter.target.to_a.map do |target| + uid = target.target.to_s + + transport = target.transport + if transport && transport.kind_of?(RbVmomi::VIM::HostInternetScsiTargetTransport) + iscsi_name = target.transport.iScsiName + iscsi_alias = target.transport.iScsiAlias + address = target.transport.address + end + + scsi_luns = target.lun.to_a.map do |lun| + scsi_lun_uids[lun.scsiLun]&.merge(:lun => lun.lun.to_s) + end + + { + :uid_ems => uid, + :target => uid, + :iscsi_name => iscsi_name, + :iscsi_alias => iscsi_alias, + :address => address, + :miq_scsi_luns => scsi_luns, + } + end + end + end + + def parse_host_system_storage_adapters(hardware, props) + storage_devices = props.dig(:config, :storageDevice) + return if storage_devices.blank? + + scsi_lun_uids = parse_host_system_scsi_luns(storage_devices.dig(:scsiLun)) + + scsi_adapters = storage_devices.dig(:scsiTopology, :adapter) + scsi_targets_by_adapter = parse_host_system_scsi_targets(scsi_adapters, scsi_lun_uids) + + hbas = storage_devices[:hostBusAdapter] hbas.to_a.each do |hba| name = uid = hba.device location = hba.pci @@ -204,7 +270,7 @@ def parse_host_system_guest_devices(hardware, props) "HBA" end - persister.guest_devices.build( + persister_guest_device = persister.host_guest_devices.build( :hardware => hardware, :uid_ems => uid, :device_name => name, @@ -217,6 +283,20 @@ def parse_host_system_guest_devices(hardware, props) :chap_auth_enabled => chap_auth_enabled, :controller_type => controller_type, ) + + scsi_targets_by_adapter[hba.key].to_a.each do |scsi_target| + miq_scsi_luns = Array.wrap(scsi_target.delete(:miq_scsi_luns)) + + persister_scsi_target = persister.miq_scsi_targets.build( + scsi_target.merge(:guest_device => persister_guest_device) + ) + + miq_scsi_luns.each do |miq_scsi_lun| + persister.miq_scsi_luns.build( + miq_scsi_lun.merge(:miq_scsi_target => persister_scsi_target) + ) + end + end end end @@ -237,7 +317,7 @@ def parse_host_system_switches(host, props) mac_changes = security_policy[:macChanges] end - persister.switches.build( + persister_switch = persister.switches.build( :uid_ems => uid, :name => switch[:name], :type => type, @@ -247,6 +327,19 @@ def parse_host_system_switches(host, props) :forged_transmits => forged_transmits, :mac_changes => mac_changes, ) + + switch.pnic.to_a.each do |pnic| + pnic_uid_ems = pnic.split("-").last + next if pnic_uid_ems.nil? + + hardware = persister.host_hardwares.find(host) + persister_guest_device = persister.host_guest_devices.find_or_build_by(:hardware => hardware, :uid_ems => pnic_uid_ems) + persister_guest_device.assign_attributes( + :switch => persister_switch + ) + end + + persister_switch end end diff --git a/app/models/manageiq/providers/vmware/infra_manager/inventory/persister.rb b/app/models/manageiq/providers/vmware/infra_manager/inventory/persister.rb index 97a6bc781..5a6dde997 100644 --- a/app/models/manageiq/providers/vmware/infra_manager/inventory/persister.rb +++ b/app/models/manageiq/providers/vmware/infra_manager/inventory/persister.rb @@ -52,12 +52,16 @@ def inventory_collection_names guest_devices hardwares hosts + host_guest_devices host_hardwares host_networks host_storages host_switches + host_system_services host_operating_systems lans + miq_scsi_luns + miq_scsi_targets networks operating_systems resource_pools diff --git a/manageiq-providers-vmware.gemspec b/manageiq-providers-vmware.gemspec index 4ae79822e..5db98116f 100644 --- a/manageiq-providers-vmware.gemspec +++ b/manageiq-providers-vmware.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |s| s.add_dependency("fog-vcloud-director", ["~> 0.2.2"]) s.add_dependency "fog-core", "~>1.40" s.add_dependency "vmware_web_service", "~>0.2.10" - s.add_dependency "rbvmomi", "~>1.12.0" + s.add_dependency "rbvmomi", "~>1.13.0" s.add_development_dependency "codeclimate-test-reporter", "~> 1.0.0" s.add_development_dependency "simplecov" diff --git a/spec/models/manageiq/providers/vmware/infra_manager/inventory/collector_spec.rb b/spec/models/manageiq/providers/vmware/infra_manager/inventory/collector_spec.rb index cac5674b4..c0d40345d 100644 --- a/spec/models/manageiq/providers/vmware/infra_manager/inventory/collector_spec.rb +++ b/spec/models/manageiq/providers/vmware/infra_manager/inventory/collector_spec.rb @@ -495,7 +495,55 @@ def assert_specific_host :location => "03:00.0", :controller_type => "ethernet", :uid_ems => "vmnic0", - # TODO: :switch => switch, + :switch => switch, + ) + + hba = host.hardware.guest_devices.find_by(:uid_ems => "vmhba1") + + expect(hba).not_to be_nil + expect(hba).to have_attributes( + :device_name => "vmhba1", + :device_type => "storage", + :location => "0e:00.0", + :controller_type => "Block", + :model => "Smart Array P400", + :present => true, + :start_connected => true, + :uid_ems => "vmhba1", + ) + + expect(hba.miq_scsi_targets.count).to eq(1) + + scsi_target = hba.miq_scsi_targets.first + expect(scsi_target).to have_attributes( + :target => 0, + :uid_ems => "0", + :iscsi_name => nil, + :iscsi_alias => nil, + :address => nil, + ) + + expect(scsi_target.miq_scsi_luns.count).to eq(1) + + scsi_lun = scsi_target.miq_scsi_luns.first + expect(scsi_lun).to have_attributes( + :lun => 0, + :canonical_name => "disk", + :lun_type => nil, + :device_name => "/vmfs/devices/disks/mpx.vmhba1:C0:T0:L0", + :device_type => "disk", + :block => 1_146_734_896, + :block_size => 512, + :capacity => 573_367_448, + :uid_ems => "0000000000766d686261313a303a30", + ) + + system_services = host.system_services + expect(system_services.count).to eq(2) + expect(system_services.find_by(:name => "ntpd")).to have_attributes( + :name => "ntpd", + :display_name => "NTP Daemon", + :running => true, ) end