diff --git a/app/models/ems_refresh/refreshers/ems_refresher_mixin.rb b/app/models/ems_refresh/refreshers/ems_refresher_mixin.rb index addc9214e82..a6fb04e5e4d 100644 --- a/app/models/ems_refresh/refreshers/ems_refresher_mixin.rb +++ b/app/models/ems_refresh/refreshers/ems_refresher_mixin.rb @@ -135,13 +135,13 @@ def parse_targeted_inventory(ems, target, collector) _log.debug "#{log_header} Parsing inventory..." inventory_collections, = Benchmark.realtime_block(:parse_inventory) do provider_module = ManageIQ::Providers::Inflector.provider_module(ems.class).name - inventory_target_class = "#{provider_module}::Inventory::Target::#{target.class.name.demodulize}".safe_constantize - inventory_target = inventory_target_class.new(target) + persister_class = "#{provider_module}::Inventory::Persister::#{target.class.name.demodulize}".safe_constantize + persister = persister_class.new(ems, target) parser_class = "#{provider_module}::Inventory::Parser::#{target.class.name.demodulize}".safe_constantize parser = parser_class.new - i = ManagerRefresh::Inventory.new(inventory_target, collector, parser) + i = ManagerRefresh::Inventory.new(persister, collector, parser) i.inventory_collections end _log.debug "#{log_header} Parsing inventory...Complete" diff --git a/app/models/manageiq/providers/ansible_tower/inventory/parser/automation_manager.rb b/app/models/manageiq/providers/ansible_tower/inventory/parser/automation_manager.rb index 90cf8d2264b..839573da84f 100644 --- a/app/models/manageiq/providers/ansible_tower/inventory/parser/automation_manager.rb +++ b/app/models/manageiq/providers/ansible_tower/inventory/parser/automation_manager.rb @@ -1,57 +1,57 @@ class ManageIQ::Providers::AnsibleTower::Inventory::Parser::AutomationManager < ManagerRefresh::Inventory::Parser def parse - inventory_groups + inventory_root_groups configured_systems configuration_scripts configuration_script_sources credentials end - def inventory_groups + def inventory_root_groups collector.inventories.each do |inventory| - inventory_object = target.inventory_groups.find_or_build(inventory.id.to_s) + inventory_object = persister.inventory_root_groups.find_or_build(inventory.id.to_s) inventory_object[:name] = inventory.name end end def configured_systems collector.hosts.each do |host| - inventory_object = target.configured_systems.find_or_build(host.id) + inventory_object = persister.configured_systems.find_or_build(host.id) inventory_object[:hostname] = host.name inventory_object[:virtual_instance_ref] = host.instance_id - inventory_object[:inventory_root_group] = target.inventory_groups.lazy_find(host.inventory_id.to_s) + inventory_object[:inventory_root_group] = persister.inventory_root_groups.lazy_find(host.inventory_id.to_s) inventory_object[:counterpart] = Vm.find_by(:uid_ems => host.instance_id) end end def configuration_scripts collector.job_templates.each do |job_template| - inventory_object = target.configuration_scripts.find_or_build(job_template.id.to_s) + inventory_object = persister.configuration_scripts.find_or_build(job_template.id.to_s) inventory_object[:description] = job_template.description inventory_object[:name] = job_template.name inventory_object[:survey_spec] = job_template.survey_spec_hash inventory_object[:variables] = job_template.extra_vars_hash - inventory_object[:inventory_root_group] = target.inventory_groups.lazy_find(job_template.inventory_id.to_s) + inventory_object[:inventory_root_group] = persister.inventory_root_groups.lazy_find(job_template.inventory_id.to_s) inventory_object[:authentications] = [] %w(credential_id cloud_credential_id network_credential_id).each do |credential_attr| next unless job_template.respond_to?(credential_attr) credential_id = job_template.public_send(credential_attr).to_s next if credential_id.blank? - inventory_object[:authentications] << target.credentials.lazy_find(credential_id) + inventory_object[:authentications] << persister.credentials.lazy_find(credential_id) end end end def configuration_script_sources collector.projects.each do |project| - inventory_object = target.configuration_script_sources.find_or_build(project.id.to_s) + inventory_object = persister.configuration_script_sources.find_or_build(project.id.to_s) inventory_object[:description] = project.description inventory_object[:name] = project.name project.playbooks.each do |playbook_name| # FIXME: its not really nice how I have to build a manager_ref / uuid here - inventory_object_playbook = target.playbooks.find_or_build("#{project.id}__#{playbook_name}") + inventory_object_playbook = persister.configuration_script_payloads.find_or_build("#{project.id}__#{playbook_name}") inventory_object_playbook[:configuration_script_source] = inventory_object inventory_object_playbook[:name] = playbook_name end @@ -60,7 +60,7 @@ def configuration_script_sources def credentials collector.credentials.each do |credential| - inventory_object = target.credentials.find_or_build(credential.id.to_s) + inventory_object = persister.credentials.find_or_build(credential.id.to_s) inventory_object[:name] = credential.name inventory_object[:userid] = credential.username # credential.description diff --git a/app/models/manageiq/providers/ansible_tower/inventory/persister/automation_manager.rb b/app/models/manageiq/providers/ansible_tower/inventory/persister/automation_manager.rb new file mode 100644 index 00000000000..e187ae7b968 --- /dev/null +++ b/app/models/manageiq/providers/ansible_tower/inventory/persister/automation_manager.rb @@ -0,0 +1,19 @@ +class ManageIQ::Providers::AnsibleTower::Inventory::Persister::AutomationManager < ManagerRefresh::Inventory::Persister + def automation + ManageIQ::Providers::AnsibleTower::InventoryCollectionDefault::AutomationManager + end + + def initialize_inventory_collections + add_inventory_collections( + automation, + %i(inventory_root_groups configured_systems configuration_scripts configuration_script_sources configuration_script_payloads), + :builder_params => {:manager => manager} + ) + + add_inventory_collections( + automation, + %i(credentials), + :builder_params => {:resource => manager} + ) + end +end diff --git a/app/models/manageiq/providers/ansible_tower/inventory/target/automation_manager.rb b/app/models/manageiq/providers/ansible_tower/inventory/target/automation_manager.rb deleted file mode 100644 index 0b1c0d05b5c..00000000000 --- a/app/models/manageiq/providers/ansible_tower/inventory/target/automation_manager.rb +++ /dev/null @@ -1,60 +0,0 @@ -class ManageIQ::Providers::AnsibleTower::Inventory::Target::AutomationManager < ManagerRefresh::Inventory::Target - def inventory_groups - collections[:inventory_groups] ||= ManagerRefresh::InventoryCollection.new( - :model_class => ManageIQ::Providers::AutomationManager::InventoryRootGroup, - :association => :inventory_root_groups, - :parent => @root, - :builder_params => {:manager => @root} - ) - end - - def configured_systems - collections[:configured_systems] ||= ManagerRefresh::InventoryCollection.new( - :model_class => ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem, - :association => :configured_systems, - :parent => @root, - :manager_ref => [:manager_ref], - :builder_params => {:manager => @root} - ) - end - - def configuration_scripts - collections[:configuration_scripts] ||= ManagerRefresh::InventoryCollection.new( - :model_class => ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript, - :association => :configuration_scripts, - :parent => @root, - :manager_ref => [:manager_ref], - :builder_params => {:manager => @root} - ) - end - - def configuration_script_sources - collections[:configuration_script_sources] ||= ManagerRefresh::InventoryCollection.new( - :model_class => ConfigurationScriptSource, - :association => :configuration_script_sources, - :manager_ref => [:manager_ref], - :parent => @root, - :builder_params => {:manager => @root} - ) - end - - def playbooks - collections[:playbooks] ||= ManagerRefresh::InventoryCollection.new( - :model_class => ManageIQ::Providers::AnsibleTower::AutomationManager::Playbook, - :association => :configuration_script_payloads, - :manager_ref => [:manager_ref], - :parent => @root, - :builder_params => {:manager => @root} - ) - end - - def credentials - collections[:credentials] ||= ManagerRefresh::InventoryCollection.new( - :model_class => ManageIQ::Providers::AutomationManager::Authentication, - :association => :credentials, - :manager_ref => [:manager_ref], - :parent => @root, - :builder_params => {:resource => @root} - ) - end -end diff --git a/app/models/manageiq/providers/ansible_tower/inventory_collection_default/automation_manager.rb b/app/models/manageiq/providers/ansible_tower/inventory_collection_default/automation_manager.rb new file mode 100644 index 00000000000..2b72e5a9618 --- /dev/null +++ b/app/models/manageiq/providers/ansible_tower/inventory_collection_default/automation_manager.rb @@ -0,0 +1,56 @@ +class ManageIQ::Providers::AnsibleTower::InventoryCollectionDefault::AutomationManager < ManagerRefresh::InventoryCollectionDefault + class << self + def inventory_root_groups(extra_attributes = {}) + attributes = { + :model_class => ManageIQ::Providers::AutomationManager::InventoryRootGroup, + :association => :inventory_root_groups, + } + attributes.merge!(extra_attributes) + end + + def configured_systems(extra_attributes = {}) + attributes = { + :model_class => ManageIQ::Providers::AnsibleTower::AutomationManager::ConfiguredSystem, + :association => :configured_systems, + :manager_ref => [:manager_ref], + } + attributes.merge!(extra_attributes) + end + + def configuration_scripts(extra_attributes = {}) + attributes = { + :model_class => ManageIQ::Providers::AnsibleTower::AutomationManager::ConfigurationScript, + :association => :configuration_scripts, + :manager_ref => [:manager_ref], + } + attributes.merge!(extra_attributes) + end + + def configuration_script_sources(extra_attributes = {}) + attributes = { + :model_class => ConfigurationScriptSource, + :association => :configuration_script_sources, + :manager_ref => [:manager_ref], + } + attributes.merge!(extra_attributes) + end + + def configuration_script_payloads(extra_attributes = {}) + attributes = { + :model_class => ManageIQ::Providers::AnsibleTower::AutomationManager::Playbook, + :association => :configuration_script_payloads, + :manager_ref => [:manager_ref], + } + attributes.merge!(extra_attributes) + end + + def credentials(extra_attributes = {}) + attributes = { + :model_class => ManageIQ::Providers::AutomationManager::Authentication, + :association => :credentials, + :manager_ref => [:manager_ref], + } + attributes.merge!(extra_attributes) + end + end +end diff --git a/app/models/manageiq/providers/cloud_manager/refresh_parser_inventory_object.rb b/app/models/manageiq/providers/cloud_manager/refresh_parser_inventory_object.rb deleted file mode 100644 index ffa70fa1058..00000000000 --- a/app/models/manageiq/providers/cloud_manager/refresh_parser_inventory_object.rb +++ /dev/null @@ -1,55 +0,0 @@ -class ManageIQ::Providers::CloudManager::RefreshParserInventoryObject < ::ManagerRefresh::RefreshParserInventoryObject - private - - def parse_key_pair(kp) - name = uid = kp.name - - new_result = { - :type => self.class.key_pair_type, - :name => name, - :fingerprint => kp.fingerprint - } - - return uid, new_result - end - - def parse_security_group(sg) - uid = sg.id - - new_result = { - :type => self.class.security_group_type, - :ems_ref => uid, - :name => sg.name, - :description => sg.description.try(:truncate, 255) - } - - return uid, new_result - end - - # - # Helper methods - # - - def filter_unused_disabled_flavors - to_delete = @data[:flavors].reject { |f| f[:enabled] || @known_flavors.include?(f[:ems_ref]) } - to_delete.each do |f| - @data_index[:flavors].delete(f[:ems_ref]) - @data[:flavors].delete(f) - end - end - - def add_instance_disk(disks, size, location, name, controller_type) - if size >= 0 - disk = { - :device_name => name, - :device_type => "disk", - :controller_type => controller_type, - :location => location, - :size => size - } - disks << disk - return disk - end - nil - end -end diff --git a/app/models/manager_refresh/inventory.rb b/app/models/manager_refresh/inventory.rb index 20047750b30..692c1f446e8 100644 --- a/app/models/manager_refresh/inventory.rb +++ b/app/models/manager_refresh/inventory.rb @@ -2,23 +2,28 @@ module ManagerRefresh class Inventory require_nested :Collector require_nested :Parser - require_nested :Target + require_nested :Persister - attr_accessor :collector - attr_accessor :target - attr_accessor :parser + attr_accessor :collector, :parsers, :persister - def initialize(target, collector, parser) + # @param persister [ManagerRefresh::Inventory::Persister] A Persister object + # @param collector [ManagerRefresh::Inventory::Collector] A Collector object + # @param parsers [ManagerRefresh::Inventory::Parser|Array] A Parser object or an array of + # ManagerRefresh::Inventory::Parser objects + def initialize(persister, collector, parsers) @collector = collector - @target = target - @parser = parser + @persister = persister + @parsers = parsers.kind_of?(Array) ? parsers : [parsers] end def inventory_collections - parser.collector = collector - parser.target = target - parser.parse - target.inventory_collections + parsers.each do |parser| + parser.collector = collector + parser.persister = persister + parser.parse + end + + persister.inventory_collections end end end diff --git a/app/models/manager_refresh/inventory/collector.rb b/app/models/manager_refresh/inventory/collector.rb index 560077ef392..2ef62911fee 100644 --- a/app/models/manager_refresh/inventory/collector.rb +++ b/app/models/manager_refresh/inventory/collector.rb @@ -1,9 +1,14 @@ class ManagerRefresh::Inventory::Collector - attr_accessor :manager - attr_accessor :target + attr_reader :manager, :target - def initialize(manager, target) + # @param manager [ManageIQ::Providers::BaseManager] A manager object + # @param target [Object] A refresh Target object + def initialize(manager, refresh_target) @manager = manager - @target = target + @target = refresh_target + end + + def options + @options ||= Settings.ems_refresh[manager.class.ems_type] end end diff --git a/app/models/manager_refresh/inventory/parser.rb b/app/models/manager_refresh/inventory/parser.rb index 5264c13636a..686146d85a6 100644 --- a/app/models/manager_refresh/inventory/parser.rb +++ b/app/models/manager_refresh/inventory/parser.rb @@ -1,6 +1,6 @@ class ManagerRefresh::Inventory::Parser attr_accessor :collector - attr_accessor :target + attr_accessor :persister def parse raise NotImplementedError, _("must be implemented in a subclass") diff --git a/app/models/manager_refresh/inventory/persister.rb b/app/models/manager_refresh/inventory/persister.rb new file mode 100644 index 00000000000..75bd1f1e4c9 --- /dev/null +++ b/app/models/manager_refresh/inventory/persister.rb @@ -0,0 +1,89 @@ +class ManagerRefresh::Inventory::Persister + attr_reader :manager, :target, :collections + + # @param manager [ManageIQ::Providers::BaseManager] A manager object + # @param target [Object] A refresh Target object + def initialize(manager, target) + @manager = manager + @target = target + + @collections = {} + + initialize_inventory_collections + end + + def options + @options ||= Settings.ems_refresh[manager.class.ems_type] + end + + def inventory_collections + collections.values + end + + def inventory_collections_names + collections.keys + end + + def method_missing(method_name, *arguments, &block) + if inventory_collections_names.include?(method_name) + self.class.define_collections_reader(method_name) + send(method_name) + else + super + end + end + + def respond_to_missing?(method_name, _include_private = false) + inventory_collections_names.include?(method_name) || super + end + + def self.define_collections_reader(collection_key) + define_method(collection_key) do + collections[collection_key] + end + end + + protected + + def initialize_inventory_collections + raise NotImplementedError, _("must be implemented in a subclass") + end + + # Adds 1 ManagerRefresh::InventoryCollection under a target.collections using :association key as index + # + # @param options [Hash] Hash used for ManagerRefresh::InventoryCollection initialize + def add_inventory_collection(options) + options[:parent] ||= manager + + collections[options[:association]] = ::ManagerRefresh::InventoryCollection.new(options) + end + + # Adds multiple inventory collections with the same data + # + # @param default [ManagerRefresh::InventoryCollectionDefault] Default + # @param inventory_collections [Array] Array of method names for passed default parameter + # @param options [Hash] Hash used for ManagerRefresh::InventoryCollection initialize + def add_inventory_collections(default, inventory_collections, options = {}) + inventory_collections.each do |inventory_collection| + add_inventory_collection(default.send(inventory_collection, options)) + end + end + + # Adds remaining inventory collections with the same data + # + # @param defaults [Array] Array of ManagerRefresh::InventoryCollectionDefault + # @param options [Hash] Hash used for ManagerRefresh::InventoryCollection initialize + def add_remaining_inventory_collections(defaults, options = {}) + defaults.each do |default| + # Get names of all inventory collections defined in passed classes with Defaults + all_inventory_collections = default.methods - ::ManagerRefresh::InventoryCollectionDefault.methods + # Get names of all defined inventory_collections + defined_inventory_collections = inventory_collections_names + + # Add all missing inventory_collections with defined init_data + add_inventory_collections(default, + all_inventory_collections - defined_inventory_collections, + options) + end + end +end diff --git a/app/models/manager_refresh/inventory/target.rb b/app/models/manager_refresh/inventory/target.rb deleted file mode 100644 index 8583aa10ffe..00000000000 --- a/app/models/manager_refresh/inventory/target.rb +++ /dev/null @@ -1,14 +0,0 @@ -class ManagerRefresh::Inventory::Target - # @param [ApplicationRecord] root - def initialize(root) - @root = root - end - - def collections - @collections ||= {} - end - - def inventory_collections - @collections.values - end -end diff --git a/app/models/manager_refresh/inventory_collection_default/cloud_manager.rb b/app/models/manager_refresh/inventory_collection_default/cloud_manager.rb index f6363bbd2d7..f5810788299 100644 --- a/app/models/manager_refresh/inventory_collection_default/cloud_manager.rb +++ b/app/models/manager_refresh/inventory_collection_default/cloud_manager.rb @@ -4,6 +4,7 @@ def vms(extra_attributes = {}) attributes = { :model_class => ::ManageIQ::Providers::CloudManager::Vm, :association => :vms, + :delete_method => :disconnect_inv, :attributes_blacklist => [:genealogy_parent] } @@ -12,8 +13,9 @@ def vms(extra_attributes = {}) def miq_templates(extra_attributes = {}) attributes = { - :model_class => ::ManageIQ::Providers::CloudManager::Template, - :association => :miq_templates, + :model_class => ::ManageIQ::Providers::CloudManager::Template, + :association => :miq_templates, + :delete_method => :disconnect_inv, } attributes.merge!(extra_attributes) diff --git a/app/models/manager_refresh/refresh_parser_inventory_object.rb b/app/models/manager_refresh/refresh_parser_inventory_object.rb deleted file mode 100644 index 944aadb225c..00000000000 --- a/app/models/manager_refresh/refresh_parser_inventory_object.rb +++ /dev/null @@ -1,27 +0,0 @@ -module ManagerRefresh - class RefreshParserInventoryObject - attr_reader :inventory, :inventory_collections - - def initialize(inventory) - @inventory = inventory - @inventory_collections = inventory.inventory_collections - end - - def process_inventory_collection(collection, key) - (collection || []).each do |item| - new_result = yield(item) - next if new_result.blank? - - raise "InventoryCollection #{key} must be defined" unless inventory_collections[key] - - inventory_collections[key] << inventory_collections[key].new_inventory_object(new_result) - end - end - - class << self - def ems_inv_to_hashes(inventory) - new(inventory).ems_inv_to_hashes - end - end - end -end