diff --git a/app/models/manager_refresh/inventory/persister.rb b/app/models/manager_refresh/inventory/persister.rb index 613f2f8ac9af..175234b7b292 100644 --- a/app/models/manager_refresh/inventory/persister.rb +++ b/app/models/manager_refresh/inventory/persister.rb @@ -1,10 +1,11 @@ class ManagerRefresh::Inventory::Persister require 'json' require 'yaml' + require_nested :Builder attr_reader :manager, :target, :collections - include ::ManagerRefresh::InventoryCollection::Builder::PersisterHelper + include ::ManagerRefresh::Inventory::Persister::Builder::PersisterHelper # @param manager [ManageIQ::Providers::BaseManager] A manager object # @param target [Object] A refresh Target object diff --git a/app/models/manager_refresh/inventory/persister/builder.rb b/app/models/manager_refresh/inventory/persister/builder.rb new file mode 100644 index 000000000000..34a1de2079f8 --- /dev/null +++ b/app/models/manager_refresh/inventory/persister/builder.rb @@ -0,0 +1,267 @@ +class ManagerRefresh::Inventory::Persister::Builder + class MissingModelClassError < StandardError; end + + require_nested :AutomationManager + require_nested :CloudManager + require_nested :InfraManager + require_nested :NetworkManager + require_nested :PhysicalInfraManager + require_nested :StorageManager + require_nested :PersisterHelper + + include ::ManagerRefresh::Inventory::Persister::Builder::Shared + + # Default options for builder + # :adv_settings + # - values from Advanced settings (doesn't overwrite values specified in code) + # - @see method ManagerRefresh::Inventory::Persister.make_builder_settings() + # :shared_properties + # - any properties applied if missing (not explicitly specified) + def self.default_options + { + :adv_settings => {}, + :shared_properties => {}, + } + end + + # Entry point + # Creates builder and builds data for inventory collection + # @param name [Symbol, Array] InventoryCollection.association value. method not called when Array + # (optional) method with this name also used for concrete inventory collection specific properties + # @param persister_class [Class] used for "guessing" model_class + # @param options [Hash] + def self.prepare_data(name, persister_class, options = {}) + options = default_options.merge(options) + builder = new(name, persister_class, options) + builder.construct_data + + yield(builder) if block_given? + + builder + end + + # @see prepare_data() + def initialize(name, persister_class, options = self.class.default_options) + @name = name + @persister_class = persister_class + + @properties = {} + @inventory_object_attributes = [] + @default_values = {} + @dependency_attributes = {} + + @options = options + @options[:auto_inventory_attributes] = true if @options[:auto_inventory_attributes].nil? + @options[:without_model_class] = false if @options[:without_model_class].nil? + + @adv_settings = options[:adv_settings] # Configuration/Advanced settings in GUI + @shared_properties = options[:shared_properties] # From persister + end + + # Builds data for InventoryCollection + # Calls method @name (if exists) with specific properties + # Yields for overwriting provider-specific properties + def construct_data + add_properties(:association => @name) + + add_properties(@adv_settings, :if_missing) + add_properties(@shared_properties, :if_missing) + + send(@name.to_sym) if @name.respond_to?(:to_sym) && respond_to?(@name.to_sym) + + if @properties[:model_class].nil? + add_properties(:model_class => auto_model_class) unless @options[:without_model_class] + end + end + + # Creates InventoryCollection + def to_inventory_collection + if @properties[:model_class].nil? && !@options[:without_model_class] + raise MissingModelClassError + end + + ::ManagerRefresh::InventoryCollection.new(to_hash) + end + + # + # Missing method + # - add_some_property(value) + # converted to: + # - add_properties(:some_property => value) + # + def method_missing(method_name, *arguments, &block) + if method_name.to_s.starts_with?('add_') + add_properties( + method_name.to_s.gsub('add_', '').to_sym => arguments[0] + ) + else + super + end + end + + def respond_to_missing?(method_name, _include_private = false) + method_name.to_s.starts_with?('add_') + end + + # Merges @properties + # @see ManagerRefresh::InventoryCollection.initialize for list of properties + # + # @param props [Hash] + # @param mode [Symbol] :overwrite | :if_missing + def add_properties(props = {}, mode = :overwrite) + @properties = merge_hashes(@properties, props, mode) + end + + # Adds inventory object attributes (part of @properties) + def add_inventory_attributes(array) + @inventory_object_attributes += (array || []) + end + + # Removes specified inventory object attributes + def remove_inventory_attributes(array) + @inventory_object_attributes -= (array || []) + end + + # Clears all inventory object attributes + def clear_inventory_attributes! + @options[:auto_inventory_attributes] = false + @inventory_object_attributes = [] + end + + # Adds key/values to default values (InventoryCollection.default_values) (part of @properties) + def add_default_values(params = {}, mode = :overwrite) + @default_values = merge_hashes(@default_values, params, mode) + end + + # Evaluates lambda blocks + def evaluate_lambdas!(persister) + @default_values = evaluate_lambdas_on(@default_values, persister) + @dependency_attributes = evaluate_lambdas_on(@dependency_attributes, persister) + end + + # Adds key/values to dependency_attributes (part of @properties) + def add_dependency_attributes(attrs = {}, mode = :overwrite) + @dependency_attributes = merge_hashes(@dependency_attributes, attrs, mode) + end + + # Deletes key from dependency_attributes + def remove_dependency_attributes(key) + @dependency_attributes.delete(key) + end + + # Returns whole InventoryCollection properties + def to_hash + add_inventory_attributes(auto_inventory_attributes) if @options[:auto_inventory_attributes] + + @properties[:inventory_object_attributes] ||= @inventory_object_attributes + + @properties[:default_values] ||= {} + @properties[:default_values].merge!(@default_values) + + @properties[:dependency_attributes] ||= {} + @properties[:dependency_attributes].merge!(@dependency_attributes) + + @properties + end + + protected + + # Extends source hash with + # - a) all keys from dest (overwrite mode) + # - b) missing keys (missing mode) + # + # @param mode [Symbol] :overwrite | :if_missing + def merge_hashes(source, dest, mode) + return source if source.nil? || dest.nil? + + if mode == :overwrite + source.merge(dest) + else + dest.merge(source) + end + end + + # Derives model_class from persister class and @name + # 1) searches for class in provider + # 2) if not found, searches class in core + # Can be disabled by options :auto_model_class => false + # + # @example derives model_class from amazon + # + # @persister_class = ManageIQ::Providers::Amazon::Inventory::Persister::CloudManager + # @name = :vms + # + # returns - ::::<@name.classify> + # returns - ::ManageIQ::Providers::Amazon::CloudManager::Vm + # + # @example derives model_class from @name only + # + # @persister_class = ManagerRefresh::Inventory::Persister + # @name = :vms + # + # returns ::Vm + # + # @return [Class | nil] when class doesn't exist, returns nil + def auto_model_class + model_class = begin + # a) Provider specific class + provider_module = ManageIQ::Providers::Inflector.provider_module(@persister_class).name + manager_module = self.class.name.split('::').last + + class_name = "#{provider_module}::#{manager_module}::#{@name.to_s.classify}" + + inferred_class = class_name.safe_constantize + + # safe_constantize can return different similar class ( some Rails auto-magic :/ ) + if inferred_class.to_s == class_name + inferred_class + end + rescue ::ManageIQ::Providers::Inflector::ObjectNotNamespacedError + nil + end + + if model_class + model_class + else + # b) general class + "::#{@name.to_s.classify}".safe_constantize + end + end + + # Enables/disables auto_model_class and exception check + # @param skip [Boolean] + def skip_model_class(skip = true) + @options[:without_model_class] = skip + end + + # Inventory object attributes are derived from setters + # + # Can be disabled by options :auto_inventory_attributes => false + # - attributes can be manually set via method add_inventory_attributes() + def auto_inventory_attributes + return if @properties[:model_class].nil? + + (@properties[:model_class].new.methods - ApplicationRecord.methods).grep(/^[\w]+?\=$/).collect do |setter| + setter.to_s[0..setter.length - 2].to_sym + end + end + + # Enables/disables auto_inventory_attributes + # @param skip [Boolean] + def skip_auto_inventory_attributes(skip = true) + @options[:auto_inventory_attributes] = !skip + end + + # Evaluates lambda blocks in @default_values and @dependency_attributes + # @param values [Hash] + # @param persister [ManagerRefresh::Inventory::Persister] + def evaluate_lambdas_on(values, persister) + values&.transform_values do |value| + if value.respond_to?(:call) + value.call(persister) + else + value + end + end + end +end diff --git a/app/models/manager_refresh/inventory/persister/builder/automation_manager.rb b/app/models/manager_refresh/inventory/persister/builder/automation_manager.rb new file mode 100644 index 000000000000..199a24e70e70 --- /dev/null +++ b/app/models/manager_refresh/inventory/persister/builder/automation_manager.rb @@ -0,0 +1,50 @@ +class ManagerRefresh::Inventory::Persister::Builder::AutomationManager < ManagerRefresh::Inventory::Persister::Builder + def configuration_scripts + default_manager_ref + add_common_default_values + end + + def configuration_script_payloads + add_properties( + :manager_ref => %i(configuration_script_source manager_ref) + ) + add_common_default_values + end + + def configuration_script_sources + default_manager_ref + add_common_default_values + end + + def configured_systems + default_manager_ref + add_common_default_values + end + + def credentials + default_manager_ref + add_default_values( + :resource => ->(persister) { persister.manager } + ) + end + + def inventory_root_groups + add_common_default_values + end + + def vms + add_properties(:manager_ref => %i(uid_ems)) + end + + protected + + def default_manager_ref + add_properties(:manager_ref => %i(manager_ref)) + end + + def add_common_default_values + add_default_values( + :manager => ->(persister) { persister.manager } + ) + end +end diff --git a/app/models/manager_refresh/inventory/persister/builder/cloud_manager.rb b/app/models/manager_refresh/inventory/persister/builder/cloud_manager.rb new file mode 100644 index 000000000000..6c66c70b3fd7 --- /dev/null +++ b/app/models/manager_refresh/inventory/persister/builder/cloud_manager.rb @@ -0,0 +1,207 @@ +class ManagerRefresh::Inventory::Persister::Builder::CloudManager < ManagerRefresh::Inventory::Persister::Builder + def availability_zones + add_common_default_values + end + + def flavors + add_common_default_values + end + + def key_pairs + add_properties( + :model_class => ::ManageIQ::Providers::CloudManager::AuthKeyPair, + :manager_ref => %i(name) + ) + add_default_values( + :resource_id => ->(persister) { persister.manager.id }, + :resource_type => ->(persister) { persister.manager.class.base_class } + ) + end + + def vm_and_template_labels + # TODO(lsmola) make a generic CustomAttribute IC and move it to base class + add_properties( + :model_class => ::CustomAttribute, + :manager_ref => %i(resource name), + :parent_inventory_collections => %i(vms miq_templates) + ) + + add_targeted_arel( + lambda do |inventory_collection| + manager_uuids = inventory_collection.parent_inventory_collections.collect(&:manager_uuids).map(&:to_a).flatten + inventory_collection.parent.vm_and_template_labels.where( + 'vms' => {:ems_ref => manager_uuids} + ) + end + ) + end + + def vm_and_template_taggings + add_properties( + :model_class => Tagging, + :manager_ref => %i(taggable tag), + :parent_inventory_collections => %i(vms miq_templates) + ) + + add_targeted_arel( + lambda do |inventory_collection| + manager_uuids = inventory_collection.parent_inventory_collections.collect(&:manager_uuids).map(&:to_a).flatten + ems = inventory_collection.parent + ems.vm_and_template_taggings.where( + 'taggable_id' => ems.vms_and_templates.where(:ems_ref => manager_uuids) + ) + end + ) + end + + def orchestration_stacks + add_properties( + :attributes_blacklist => %i(parent), + ) + + add_common_default_values + end + + def orchestration_stacks_resources + add_properties( + :model_class => ::OrchestrationStackResource, + :parent_inventory_collections => %i(orchestration_stacks) + ) + end + + def orchestration_stacks_outputs + add_properties( + :model_class => ::OrchestrationStackOutput, + :parent_inventory_collections => %i(orchestration_stacks) + ) + end + + def orchestration_stacks_parameters + add_properties( + :model_class => ::OrchestrationStackParameter, + :parent_inventory_collections => %i(orchestration_stacks) + ) + end + + def orchestration_templates + # TODO(lsmola) do refactoring, we shouldn't need this custom saving block\ + orchestration_templates_save_block = lambda do |_ems, inventory_collection| + hashes = inventory_collection.data.map(&:attributes) + + templates = inventory_collection.model_class.find_or_create_by_contents(hashes) + inventory_collection.data.zip(templates).each do |inventory_object, template| + inventory_object.id = template.id + end + end + + add_properties( + :custom_save_block => orchestration_templates_save_block + ) + end + + def orchestration_stack_ancestry + skip_auto_inventory_attributes + skip_model_class + + add_properties( + :custom_save_block => orchestration_stack_ancestry_save_block + ) + + add_dependency_attributes( + :orchestration_stacks => ->(persister) { [persister.collections[:orchestration_stacks]] }, + :orchestration_stacks_resources => ->(persister) { [persister.collections[:orchestration_stacks_resources]] } + ) + end + + def vm_and_miq_template_ancestry + skip_auto_inventory_attributes + skip_model_class + + add_properties( + :custom_save_block => vm_and_miq_template_ancestry_save_block + ) + + add_dependency_attributes( + :vms => ->(persister) { [persister.collections[:vms]] }, + :miq_templates => ->(persister) { [persister.collections[:miq_templates]] } + ) + end +end + +private + +def orchestration_stack_ancestry_save_block + lambda do |_ems, inventory_collection| + stacks_inventory_collection = inventory_collection.dependency_attributes[:orchestration_stacks].try(:first) + + return if stacks_inventory_collection.blank? + + stacks_parents = stacks_inventory_collection.data.each_with_object({}) do |x, obj| + parent_id = x.data[:parent].try(:load).try(:id) + obj[x.id] = parent_id if parent_id + end + + model_class = stacks_inventory_collection.model_class + + stacks_parents_indexed = model_class.select(%i(id ancestry)) + .where(:id => stacks_parents.values).find_each.index_by(&:id) + + ActiveRecord::Base.transaction do + model_class.select(%i(id ancestry)) + .where(:id => stacks_parents.keys).find_each do |stack| + parent = stacks_parents_indexed[stacks_parents[stack.id]] + stack.update_attribute(:parent, parent) + end + end + end +end + +def vm_and_miq_template_ancestry_save_block + lambda do |_ems, inventory_collection| + vms_inventory_collection = inventory_collection.dependency_attributes[:vms].try(:first) + miq_templates_inventory_collection = inventory_collection.dependency_attributes[:miq_templates].try(:first) + + return if vms_inventory_collection.blank? || miq_templates_inventory_collection.blank? + + # Fetch IDs of all vms and genealogy_parents, only if genealogy_parent is present + vms_genealogy_parents = vms_inventory_collection.data.each_with_object({}) do |x, obj| + unless x.data[:genealogy_parent].nil? + genealogy_parent_id = x.data[:genealogy_parent].load.try(:id) + obj[x.id] = genealogy_parent_id if genealogy_parent_id + end + end + + miq_template_genealogy_parents = miq_templates_inventory_collection.data.each_with_object({}) do |x, obj| + unless x.data[:genealogy_parent].nil? + genealogy_parent_id = x.data[:genealogy_parent].load.try(:id) + obj[x.id] = genealogy_parent_id if genealogy_parent_id + end + end + + ActiveRecord::Base.transaction do + # associate parent templates to child instances + parent_miq_templates = miq_templates_inventory_collection.model_class + .select([:id]) + .where(:id => vms_genealogy_parents.values).find_each.index_by(&:id) + vms_inventory_collection.model_class + .select([:id]) + .where(:id => vms_genealogy_parents.keys).find_each do |vm| + parent = parent_miq_templates[vms_genealogy_parents[vm.id]] + vm.with_relationship_type('genealogy') { vm.parent = parent } + end + end + + ActiveRecord::Base.transaction do + # associate parent instances to child templates + parent_vms = vms_inventory_collection.model_class + .select([:id]) + .where(:id => miq_template_genealogy_parents.values).find_each.index_by(&:id) + miq_templates_inventory_collection.model_class + .select([:id]) + .where(:id => miq_template_genealogy_parents.keys).find_each do |miq_template| + parent = parent_vms[miq_template_genealogy_parents[miq_template.id]] + miq_template.with_relationship_type('genealogy') { miq_template.parent = parent } + end + end + end +end diff --git a/app/models/manager_refresh/inventory/persister/builder/container_manager.rb b/app/models/manager_refresh/inventory/persister/builder/container_manager.rb new file mode 100644 index 000000000000..3ea28c909ff9 --- /dev/null +++ b/app/models/manager_refresh/inventory/persister/builder/container_manager.rb @@ -0,0 +1,262 @@ +class ManagerRefresh::Inventory::Persister::Builder::ContainerManager < ManagerRefresh::Inventory::Persister::Builder + # TODO: (agrare) Targeted refreshes will require adjusting the associations / arels. (duh) + def container_projects + add_properties( + :secondary_refs => {:by_name => %i(name)}, + :delete_method => :disconnect_inv + ) + add_common_default_values + end + + def container_quotas + add_properties( + :attributes_blacklist => %i(namespace), + :delete_method => :disconnect_inv + ) + add_common_default_values + end + + def container_quota_scopes + add_properties( + :manager_ref => %i(container_quota scope), + :parent_inventory_collections => %i(container_quotas) + ) + end + + def container_quota_items + add_properties( + :manager_ref => %i(container_quota resource quota_desired quota_enforced quota_observed), + :delete_method => :disconnect_inv, + :parent_inventory_collections => %i(container_quotas) + ) + end + + def container_limits + add_properties( + :attributes_blacklist => %i(namespace) + ) + add_common_default_values + end + + def container_limit_items + add_properties( + :manager_ref => %i(container_limit resource item_type), + :parent_inventory_collections => %i(container_limits) + ) + end + + def container_nodes + add_properties( + :model_class => ::ContainerNode, + :secondary_refs => {:by_name => %i(name)}, + :delete_method => :disconnect_inv + ) + add_common_default_values + end + + def computer_systems + add_properties( + :manager_ref => %i(managed_entity), + # TODO(lsmola) can we introspect this from the relation? Basically, the + # :parent_inventory_collections are needed only if :association goes :through other association. Then the + # parent is actually the root association (if we chain several :through associations). We should be able to + # create a tree of :through associations of ems and infer the parent_inventory_collections from that? + :parent_inventory_collections => %i(container_nodes), + ) + end + + def computer_system_hardwares + add_properties( + :model_class => ::Hardware, + :manager_ref => %i(computer_system), + :parent_inventory_collections => %i(container_nodes), + ) + end + + def computer_system_operating_systems + add_properties( + :model_class => ::OperatingSystem, + :manager_ref => %i(computer_system), + :parent_inventory_collections => %i(container_nodes), + ) + end + + # images have custom_attributes but that's done conditionally in openshift parser + def container_images + add_properties( + # TODO: (bpaskinc) old save matches on [:image_ref, :container_image_registry_id] + # TODO: (bpaskinc) should match on digest when available + # TODO: (mslemr) provider-specific class exists (openshift), but specs fail with them (?) + :model_class => ::ContainerImage, + :manager_ref => %i(image_ref), + :delete_method => :disconnect_inv, + :custom_reconnect_block => custom_reconnect_block + ) + add_common_default_values + end + + def container_image_registries + add_properties(:manager_ref => %i(host port)) + add_common_default_values + end + + def container_groups + add_properties( + :model_class => ContainerGroup, + :secondary_refs => {:by_container_project_and_name => %i(container_project name)}, + :attributes_blacklist => %i(namespace), + :delete_method => :disconnect_inv, + :custom_reconnect_block => custom_reconnect_block + ) + add_common_default_values + end + + def container_volumes + add_properties( + :manager_ref => %i(parent name), + :parent_inventory_collections => %i(container_groups), + ) + end + + def containers + add_properties( + :model_class => Container, + # parser sets :ems_ref => "#{pod_id}_#{container.name}_#{container.image}" + :delete_method => :disconnect_inv, + :custom_reconnect_block => custom_reconnect_block + ) + add_common_default_values + end + + def container_port_configs + # parser sets :ems_ref => "#{pod_id}_#{container_name}_#{port_config.containerPort}_#{port_config.hostPort}_#{port_config.protocol}" + add_properties( + :parent_inventory_collections => %i(containers) + ) + end + + def container_env_vars + add_properties( + # TODO: (agrare) old save matches on all :name, :value, :field_path - does this matter? + :manager_ref => %i(container name), + :parent_inventory_collections => %i(containers) + ) + end + + def security_contexts + add_properties( + :manager_ref => %i(resource), + :parent_inventory_collections => %i(containers) + ) + end + + def container_replicators + add_properties( + :secondary_refs => {:by_container_project_and_name => %i(container_project name)}, + :attributes_blacklist => %i(namespace) + ) + add_common_default_values + end + + def container_services + add_properties( + :secondary_refs => {:by_container_project_and_name => %i(container_project name)}, + :attributes_blacklist => %i(namespace), + :saver_strategy => "default" # TODO: (fryguy) (perf) Can't use batch strategy because of usage of M:N container_groups relation + ) + add_common_default_values + end + + def container_service_port_configs + add_properties( + :manager_ref => %i(ems_ref protocol), # TODO: (lsmola) make protocol part of the ems_ref?) + :parent_inventory_collections => %i(container_services) + ) + end + + def container_routes + add_properties( + :attributes_blacklist => %i(namespace), + :parent_inventory_collections => %i(container_services) + ) + add_common_default_values + end + + def container_templates + add_properties( + :model_class => ::ContainerTemplate, + :attributes_blacklist => %i(namespace) + ) + add_common_default_values + end + + def container_template_parameters + add_properties( + :manager_ref => %i(container_template name), + :parent_inventory_collections => %i(container_templates) + ) + end + + def container_builds + add_properties( + :secondary_refs => {:by_namespace_and_name => %i(namespace name)} + ) + add_common_default_values + end + + def container_build_pods + add_properties( + # TODO: (bpaskinc) convert namespace column -> container_project_id? + :manager_ref => %i(namespace name), + :secondary_refs => {:by_namespace_and_name => %i(namespace name)}, + ) + add_common_default_values + end + + def persistent_volumes + add_default_values(:parent => ->(persister) { persister.manager }) + end + + def persistent_volume_claims + add_properties( + :secondary_refs => {:by_container_project_and_name => %i(container_project name)}, + :attributes_blacklist => %i(namespace) + ) + add_common_default_values + end + + protected + + def custom_reconnect_block + # TODO(lsmola) once we have DB unique indexes, we can stop using manual reconnect, since it adds processing time + lambda do |inventory_collection, inventory_objects_index, attributes_index| + relation = inventory_collection.model_class.where(:ems_id => inventory_collection.parent.id).archived + + # Skip reconnect if there are no archived entities + return if relation.archived.count <= 0 + raise "Allowed only manager_ref size of 1, got #{inventory_collection.manager_ref}" if inventory_collection.manager_ref.count > 1 + + inventory_objects_index.each_slice(1000) do |batch| + relation.where(inventory_collection.manager_ref.first => batch.map(&:first)).each do |record| + index = inventory_collection.object_index_with_keys(inventory_collection.manager_ref_to_cols, record) + + # We need to delete the record from the inventory_objects_index and attributes_index, otherwise it + # would be sent for create. + inventory_object = inventory_objects_index.delete(index) + hash = attributes_index.delete(index) + + # Make the entity active again, otherwise we would be duplicating nested entities + hash[:deleted_on] = nil + + record.assign_attributes(hash.except(:id, :type)) + if !inventory_collection.check_changed? || record.changed? + record.save! + inventory_collection.store_updated_records(record) + end + + inventory_object.id = record.id + end + end + end + end +end diff --git a/app/models/manager_refresh/inventory/persister/builder/infra_manager.rb b/app/models/manager_refresh/inventory/persister/builder/infra_manager.rb new file mode 100644 index 000000000000..63d0db0a1211 --- /dev/null +++ b/app/models/manager_refresh/inventory/persister/builder/infra_manager.rb @@ -0,0 +1,260 @@ +class ManagerRefresh::Inventory::Persister::Builder::InfraManager < ManagerRefresh::Inventory::Persister::Builder + def networks + add_properties( + :manager_ref => %i(hardware ipaddress ipv6address), + :parent_inventory_collections => %i(vms miq_templates), + ) + end + + def host_networks + add_properties( + :model_class => ::Network, + :manager_ref => %i(hardware ipaddress), + :parent_inventory_collections => %i(hosts) + ) + end + + def guest_devices + add_properties( + :manager_ref => %i(hardware uid_ems), + :parent_inventory_collections => %i(vms miq_templates), + ) + end + + def host_guest_devices + add_properties( + :model_class => ::GuestDevice, + :manager_ref => %i(hardware uid_ems), + :parent_inventory_collections => %i(hosts), + ) + end + + def host_hardwares + add_properties( + :model_class => ::Hardware, + :manager_ref => %i(host), + :parent_inventory_collections => %i(hosts) + ) + end + + def host_system_services + add_properties( + :model_class => ::SystemService, + :manager_ref => %i(host name), + :parent_inventory_collections => %i(hosts) + ) + end + + def snapshots + add_properties( + :manager_ref => %i(uid), + :parent_inventory_collections => %i(vms miq_templates), + ) + end + + def operating_systems + add_properties( + :manager_ref => %i(vm_or_template), + :parent_inventory_collections => %i(vms miq_templates), + ) + end + + def host_operating_systems + add_properties( + :model_class => ::OperatingSystem, + :manager_ref => %i(host), + :parent_inventory_collections => %i(hosts), + ) + end + + def ems_custom_attributes + add_properties( + :model_class => ::CustomAttribute, + :manager_ref => %i(name), + :parent_inventory_collections => %i(vms miq_templates), + ) + end + + def vm_and_template_ems_custom_fields + skip_auto_inventory_attributes + + add_properties( + :model_class => ::CustomAttribute, + :manager_ref => %i(name), + :parent_inventory_collections => %i(vms) + ) + + add_inventory_attributes(%i(section name value source resource)) + end + + def ems_folders + add_properties( + :manager_ref => %i(uid_ems), + :attributes_blacklist => %i(ems_children), + ) + add_common_default_values + end + + def datacenters + add_common_default_values + end + + def resource_pools + add_properties( + :manager_ref => %i(uid_ems), + :attributes_blacklist => %i(ems_children), + ) + add_common_default_values + end + + def ems_clusters + add_properties( + :attributes_blacklist => %i(ems_children datacenter_id), + ) + + add_inventory_attributes(%i(datacenter_id)) + add_common_default_values + end + + def storages + add_properties( + :manager_ref => %i(location), + :complete => false, + :arel => Storage, + ) + end + + def hosts + add_common_default_values + + add_custom_reconnect_block( + lambda do |inventory_collection, inventory_objects_index, attributes_index| + relation = inventory_collection.model_class.where(:ems_id => nil) + + return if relation.count <= 0 + + inventory_objects_index.each_slice(100) do |batch| + relation.where(inventory_collection.manager_ref.first => batch.map(&:first)).each do |record| + index = inventory_collection.object_index_with_keys(inventory_collection.manager_ref_to_cols, record) + + # We need to delete the record from the inventory_objects_index and attributes_index, otherwise it + # would be sent for create. + inventory_object = inventory_objects_index.delete(index) + hash = attributes_index.delete(index) + + record.assign_attributes(hash.except(:id, :type)) + if !inventory_collection.check_changed? || record.changed? + record.save! + inventory_collection.store_updated_records(record) + end + + inventory_object.id = record.id + end + end + end + ) + end + + def vms + super + + custom_reconnect_block = lambda do |inventory_collection, inventory_objects_index, attributes_index| + relation = inventory_collection.model_class.where(:ems_id => nil) + + return if relation.count <= 0 + + inventory_objects_index.each_slice(100) do |batch| + relation.where(inventory_collection.manager_ref.first => batch.map(&:first)).each do |record| + index = inventory_collection.object_index_with_keys(inventory_collection.manager_ref_to_cols, record) + + # We need to delete the record from the inventory_objects_index and attributes_index, otherwise it + # would be sent for create. + inventory_object = inventory_objects_index.delete(index) + hash = attributes_index.delete(index) + + record.assign_attributes(hash.except(:id, :type)) + if !inventory_collection.check_changed? || record.changed? + record.save! + inventory_collection.store_updated_records(record) + end + + inventory_object.id = record.id + end + end + end + + add_properties( + :custom_reconnect_block => custom_reconnect_block + ) + end + + def host_storages + add_properties( + :manager_ref => %i(host storage), + :parent_inventory_collections => %i(hosts) + ) + end + + def host_switches + add_properties( + :manager_ref => %i(host switch), + :parent_inventory_collections => %i(hosts) + ) + end + + def switches + add_properties( + :manager_ref => %i(uid_ems), # TODO looks like switches are using a bad association, this one is defined as through hosts + ) + add_common_default_values + end + + def lans + add_properties( + :manager_ref => %i(uid_ems), + :parent_inventory_collections => %i(hosts), + ) + end + + def snapshot_parent + snapshot_parent_save_block = lambda do |_ems, inventory_collection| + snapshot_collection = inventory_collection.dependency_attributes[:snapshots].try(:first) + + snapshot_collection.each do |snapshot| + ActiveRecord::Base.transaction do + child = Snapshot.find(snapshot.id) + parent = Snapshot.find_by(:uid_ems => snapshot.parent_uid) + child.update_attribute(:parent_id, parent.try(:id)) + end + end + end + + add_properties( + :custom_save_block => snapshot_parent_save_block + ) + end + + def customization_specs + add_properties(:manager_ref => %i(name)) + + add_common_default_values + end + + def miq_scsi_luns + add_properties( + :manager_ref => %i(miq_scsi_target uid_ems), + :parent_inventory_collections => %i(hosts) + ) + end + + def miq_scsi_targets + add_properties( + :manager_ref => %i(guest_device uid_ems), + :parent_inventory_collections => %i(hosts) + ) + end + + def storage_profiles + add_common_default_values + end +end diff --git a/app/models/manager_refresh/inventory/persister/builder/network_manager.rb b/app/models/manager_refresh/inventory/persister/builder/network_manager.rb new file mode 100644 index 000000000000..908b15cb8914 --- /dev/null +++ b/app/models/manager_refresh/inventory/persister/builder/network_manager.rb @@ -0,0 +1,206 @@ +class ManagerRefresh::Inventory::Persister::Builder::NetworkManager < ManagerRefresh::Inventory::Persister::Builder + def cloud_subnet_network_ports + add_properties( + # :model_class => ::CloudSubnetNetworkPort, + :manager_ref => %i(address cloud_subnet network_port), + :parent_inventory_collections => %i(vms network_ports load_balancers) + ) + + add_targeted_arel( + lambda do |inventory_collection| + manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } + inventory_collection.parent.cloud_subnet_network_ports.references(:network_ports).where( + :network_ports => {:ems_ref => manager_uuids} + ) + end + ) + end + + def network_ports + add_properties( + :use_ar_object => true, + # TODO(lsmola) can't do batch strategy for network_ports because of security_groups relation + :saver_strategy => :default + ) + + add_common_default_values + end + + def network_groups + add_common_default_values + end + + def network_routers + add_common_default_values + end + + def floating_ips + add_common_default_values + end + + def cloud_tenants + add_common_default_values + end + + def cloud_subnets + add_common_default_values + end + + def cloud_networks + add_common_default_values + end + + def security_groups + add_common_default_values + end + + def firewall_rules + add_properties( + :manager_ref => %i(resource source_security_group direction host_protocol port end_port source_ip_range), + :parent_inventory_collections => %i(security_groups) + ) + end + + def load_balancers + add_common_default_values + end + + def load_balancer_pools + add_properties( + :parent_inventory_collections => %i(load_balancers) + ) + + add_targeted_arel( + lambda do |inventory_collection| + manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } + inventory_collection.parent.load_balancer_pools + .joins(:load_balancers) + .where(:load_balancers => {:ems_ref => manager_uuids}) + .distinct + end + ) + + add_common_default_values + end + + def load_balancer_pool_members + add_properties( + :parent_inventory_collections => %i(load_balancers) + ) + + add_targeted_arel( + lambda do |inventory_collection| + manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } + inventory_collection.parent.load_balancer_pool_members + .joins(:load_balancer_pool_member_pools => [:load_balancer_pool => :load_balancers]) + .where(:load_balancer_pool_member_pools => { + 'load_balancer_pools' => { + 'load_balancers' => { + :ems_ref => manager_uuids + } + } + }).distinct + end + ) + + add_common_default_values + end + + def load_balancer_pool_member_pools + add_properties( + :manager_ref => %i(load_balancer_pool load_balancer_pool_member), + :parent_inventory_collections => %i(load_balancers) + ) + + add_targeted_arel( + lambda do |inventory_collection| + manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } + inventory_collection.parent.load_balancer_pool_member_pools + .joins(:load_balancer_pool => :load_balancers) + .where(:load_balancer_pools => { 'load_balancers' => { :ems_ref => manager_uuids } }) + .distinct + end + ) + end + + def load_balancer_listeners + add_properties( + :use_ar_object => true, + :parent_inventory_collections => %i(load_balancers), + ) + + add_targeted_arel( + lambda do |inventory_collection| + manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } + inventory_collection.parent.load_balancer_listeners + .joins(:load_balancer) + .where(:load_balancers => {:ems_ref => manager_uuids}) + .distinct + end + ) + + add_common_default_values + end + + def load_balancer_listener_pools + add_properties( + :manager_ref => %i(load_balancer_listener load_balancer_pool), + :parent_inventory_collections => %i(load_balancers) + ) + + add_targeted_arel( + lambda do |inventory_collection| + manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } + inventory_collection.parent.load_balancer_listener_pools + .joins(:load_balancer_pool => :load_balancers) + .where(:load_balancer_pools => {'load_balancers' => {:ems_ref => manager_uuids}}) + .distinct + end + ) + end + + def load_balancer_health_checks + add_properties( + :parent_inventory_collections => %i(load_balancers) + ) + + add_targeted_arel( + lambda do |inventory_collection| + manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } + inventory_collection.parent.load_balancer_health_checks + .joins(:load_balancer) + .where(:load_balancers => {:ems_ref => manager_uuids}) + .distinct + end + ) + + add_common_default_values + end + + def load_balancer_health_check_members + add_properties( + :manager_ref => %i(load_balancer_health_check load_balancer_pool_member), + :parent_inventory_collections => %i(load_balancers) + ) + + add_targeted_arel( + lambda do |inventory_collection| + manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } + inventory_collection.parent.load_balancer_health_check_members + .joins(:load_balancer_health_check => :load_balancer) + .where(:load_balancer_health_checks => {'load_balancers' => {:ems_ref => manager_uuids}}) + .distinct + end + ) + end + + protected + + def add_common_default_values + add_default_values(:ems_id => default_ems_id) + end + + def default_ems_id + ->(persister) { persister.manager.try(:network_manager).try(:id) || persister.manager.id } + end +end diff --git a/app/models/manager_refresh/inventory_collection/builder/persister_helper.rb b/app/models/manager_refresh/inventory/persister/builder/persister_helper.rb similarity index 75% rename from app/models/manager_refresh/inventory_collection/builder/persister_helper.rb rename to app/models/manager_refresh/inventory/persister/builder/persister_helper.rb index 23034f9b931d..2349f24b21bf 100644 --- a/app/models/manager_refresh/inventory_collection/builder/persister_helper.rb +++ b/app/models/manager_refresh/inventory/persister/builder/persister_helper.rb @@ -1,19 +1,19 @@ -module ManagerRefresh::InventoryCollection::Builder::PersisterHelper +module ManagerRefresh::Inventory::Persister::Builder::PersisterHelper extend ActiveSupport::Concern # Interface for creating InventoryCollection under @collections # - # @param builder_class [ManagerRefresh::InventoryCollection::Builder] or subclasses + # @param builder_class [ManagerRefresh::Inventory::Persister::Builder] or subclasses # @param collection_name [Symbol || Array] used as InventoryCollection:association # @param extra_properties [Hash] props from InventoryCollection.initialize list # - adds/overwrites properties added by builder # # @param settings [Hash] builder settings - # - @see ManagerRefresh::InventoryCollection::Builder.default_options + # - @see ManagerRefresh::Inventory::Persister::Builder.default_options # - @see make_builder_settings() # # @example - # add_collection(ManagerRefresh::InventoryCollection::Builder::CloudManager, :vms) do |builder| + # add_collection(ManagerRefresh::Inventory::Persister::Builder::CloudManager, :vms) do |builder| # builder.add_properties( # :strategy => :local_db_cache_all, # ) @@ -38,36 +38,36 @@ def add_collection(builder_class, collection_name, extra_properties = {}, settin # builder_class for add_collection() def cloud - ::ManagerRefresh::InventoryCollection::Builder::CloudManager + ::ManagerRefresh::Inventory::Persister::Builder::CloudManager end # builder_class for add_collection() def network - ::ManagerRefresh::InventoryCollection::Builder::NetworkManager + ::ManagerRefresh::Inventory::Persister::Builder::NetworkManager end # builder_class for add_collection() def infra - ::ManagerRefresh::InventoryCollection::Builder::InfraManager + ::ManagerRefresh::Inventory::Persister::Builder::InfraManager end # builder_class for add_collection() def storage - ::ManagerRefresh::InventoryCollection::Builder::StorageManager + ::ManagerRefresh::Inventory::Persister::Builder::StorageManager end # builder_class for add_collection() def automation - ::ManagerRefresh::InventoryCollection::Builder::AutomationManager + ::ManagerRefresh::Inventory::Persister::Builder::AutomationManager end # builder class for add_collection() def physical_infra - ::ManagerRefresh::InventoryCollection::Builder::PhysicalInfraManager + ::ManagerRefresh::Inventory::Persister::Builder::PhysicalInfraManager end def container - ::ManagerRefresh::InventoryCollection::Builder::ContainerManager + ::ManagerRefresh::Inventory::Persister::Builder::ContainerManager end # @param extra_settings [Hash] @@ -77,9 +77,9 @@ def container # :without_model_class # - if false and no model_class derived or specified, throws exception # - doesn't try to derive model class automatically - # - @see method ManagerRefresh::InventoryCollection::Builder.auto_model_class + # - @see method ManagerRefresh::Inventory::Persister::Builder.auto_model_class def make_builder_settings(extra_settings = {}) - opts = ::ManagerRefresh::InventoryCollection::Builder.default_options + opts = ::ManagerRefresh::Inventory::Persister::Builder.default_options opts[:adv_settings] = options.try(:[], :inventory_collections).try(:to_hash) || {} opts[:shared_properties] = shared_options diff --git a/app/models/manager_refresh/inventory/persister/builder/physical_infra_manager.rb b/app/models/manager_refresh/inventory/persister/builder/physical_infra_manager.rb new file mode 100644 index 000000000000..67f3c5755352 --- /dev/null +++ b/app/models/manager_refresh/inventory/persister/builder/physical_infra_manager.rb @@ -0,0 +1,35 @@ +class ManagerRefresh::Inventory::Persister::Builder::PhysicalInfraManager < ManagerRefresh::Inventory::Persister::Builder + def physical_servers + add_common_default_values + end + + def physical_server_details + add_properties( + :model_class => ::AssetDetail, + :manager_ref => %i(resource), + :parent_inventory_collections => %i(physical_servers) + ) + end + + def computer_systems + add_properties( + :manager_ref => %i(managed_entity), + :parent_inventory_collections => %i(physical_servers) + ) + end + + def hardwares + add_properties( + :manager_ref => %i(computer_system), + :parent_inventory_collections => %i(physical_servers) + ) + end + + def physical_racks + add_common_default_values + end + + def physical_chassis + add_common_default_values + end +end diff --git a/app/models/manager_refresh/inventory_collection/builder/shared.rb b/app/models/manager_refresh/inventory/persister/builder/shared.rb similarity index 98% rename from app/models/manager_refresh/inventory_collection/builder/shared.rb rename to app/models/manager_refresh/inventory/persister/builder/shared.rb index 59ce2f26719e..572bdf4a651b 100644 --- a/app/models/manager_refresh/inventory_collection/builder/shared.rb +++ b/app/models/manager_refresh/inventory/persister/builder/shared.rb @@ -1,4 +1,4 @@ -module ManagerRefresh::InventoryCollection::Builder::Shared +module ManagerRefresh::Inventory::Persister::Builder::Shared extend ActiveSupport::Concern included do diff --git a/app/models/manager_refresh/inventory/persister/builder/storage_manager.rb b/app/models/manager_refresh/inventory/persister/builder/storage_manager.rb new file mode 100644 index 000000000000..10d802d2b78c --- /dev/null +++ b/app/models/manager_refresh/inventory/persister/builder/storage_manager.rb @@ -0,0 +1,3 @@ +class ManagerRefresh::Inventory::Persister::Builder::StorageManager < ManagerRefresh::Inventory::Persister::Builder + # Nothing there +end diff --git a/app/models/manager_refresh/inventory_collection.rb b/app/models/manager_refresh/inventory_collection.rb index 5f64b7a4d907..5e1620dc6010 100644 --- a/app/models/manager_refresh/inventory_collection.rb +++ b/app/models/manager_refresh/inventory_collection.rb @@ -44,8 +44,6 @@ module ManagerRefresh # puts @ems.vms.collect(&:ems_ref) # => ["vm2", "vm3"] # class InventoryCollection - require_nested :Builder - # @return [Boolean] A true value marks that we collected all the data of the InventoryCollection, # meaning we also collected all the references. attr_accessor :data_collection_finalized diff --git a/app/models/manager_refresh/inventory_collection/builder.rb b/app/models/manager_refresh/inventory_collection/builder.rb deleted file mode 100644 index 8200842a2292..000000000000 --- a/app/models/manager_refresh/inventory_collection/builder.rb +++ /dev/null @@ -1,272 +0,0 @@ -module ManagerRefresh - class InventoryCollection - # @see test in /spec/models/manager_refresh/inventory_collection/builder_spec.rb - class Builder - class MissingModelClassError < StandardError; end - - require_nested :AutomationManager - require_nested :CloudManager - require_nested :InfraManager - require_nested :NetworkManager - require_nested :PhysicalInfraManager - require_nested :StorageManager - require_nested :PersisterHelper - - include ::ManagerRefresh::InventoryCollection::Builder::Shared - - # Default options for builder - # :adv_settings - # - values from Advanced settings (doesn't overwrite values specified in code) - # - @see method ManagerRefresh::Inventory::Persister.make_builder_settings() - # :shared_properties - # - any properties applied if missing (not explicitly specified) - def self.default_options - { - :adv_settings => {}, - :shared_properties => {}, - } - end - - # Entry point - # Creates builder and builds data for inventory collection - # @param name [Symbol, Array] InventoryCollection.association value. method not called when Array - # (optional) method with this name also used for concrete inventory collection specific properties - # @param persister_class [Class] used for "guessing" model_class - # @param options [Hash] - def self.prepare_data(name, persister_class, options = {}) - options = default_options.merge(options) - builder = new(name, persister_class, options) - builder.construct_data - - yield(builder) if block_given? - - builder - end - - # @see prepare_data() - def initialize(name, persister_class, options = self.class.default_options) - @name = name - @persister_class = persister_class - - @properties = {} - @inventory_object_attributes = [] - @default_values = {} - @dependency_attributes = {} - - @options = options - @options[:auto_inventory_attributes] = true if @options[:auto_inventory_attributes].nil? - @options[:without_model_class] = false if @options[:without_model_class].nil? - - @adv_settings = options[:adv_settings] # Configuration/Advanced settings in GUI - @shared_properties = options[:shared_properties] # From persister - end - - # Builds data for InventoryCollection - # Calls method @name (if exists) with specific properties - # Yields for overwriting provider-specific properties - def construct_data - add_properties(:association => @name) - - add_properties(@adv_settings, :if_missing) - add_properties(@shared_properties, :if_missing) - - send(@name.to_sym) if @name.respond_to?(:to_sym) && respond_to?(@name.to_sym) - - if @properties[:model_class].nil? - add_properties(:model_class => auto_model_class) unless @options[:without_model_class] - end - end - - # Creates InventoryCollection - def to_inventory_collection - if @properties[:model_class].nil? && !@options[:without_model_class] - raise MissingModelClassError - end - - ::ManagerRefresh::InventoryCollection.new(to_hash) - end - - # - # Missing method - # - add_some_property(value) - # converted to: - # - add_properties(:some_property => value) - # - def method_missing(method_name, *arguments, &block) - if method_name.to_s.starts_with?('add_') - add_properties( - method_name.to_s.gsub('add_', '').to_sym => arguments[0] - ) - else - super - end - end - - def respond_to_missing?(method_name, _include_private = false) - method_name.to_s.starts_with?('add_') - end - - # Merges @properties - # @see ManagerRefresh::InventoryCollection.initialize for list of properties - # - # @param props [Hash] - # @param mode [Symbol] :overwrite | :if_missing - def add_properties(props = {}, mode = :overwrite) - @properties = merge_hashes(@properties, props, mode) - end - - # Adds inventory object attributes (part of @properties) - def add_inventory_attributes(array) - @inventory_object_attributes += (array || []) - end - - # Removes specified inventory object attributes - def remove_inventory_attributes(array) - @inventory_object_attributes -= (array || []) - end - - # Clears all inventory object attributes - def clear_inventory_attributes! - @options[:auto_inventory_attributes] = false - @inventory_object_attributes = [] - end - - # Adds key/values to default values (InventoryCollection.default_values) (part of @properties) - def add_default_values(params = {}, mode = :overwrite) - @default_values = merge_hashes(@default_values, params, mode) - end - - # Evaluates lambda blocks - def evaluate_lambdas!(persister) - @default_values = evaluate_lambdas_on(@default_values, persister) - @dependency_attributes = evaluate_lambdas_on(@dependency_attributes, persister) - end - - # Adds key/values to dependency_attributes (part of @properties) - def add_dependency_attributes(attrs = {}, mode = :overwrite) - @dependency_attributes = merge_hashes(@dependency_attributes, attrs, mode) - end - - # Deletes key from dependency_attributes - def remove_dependency_attributes(key) - @dependency_attributes.delete(key) - end - - # Returns whole InventoryCollection properties - def to_hash - add_inventory_attributes(auto_inventory_attributes) if @options[:auto_inventory_attributes] - - @properties[:inventory_object_attributes] ||= @inventory_object_attributes - - @properties[:default_values] ||= {} - @properties[:default_values].merge!(@default_values) - - @properties[:dependency_attributes] ||= {} - @properties[:dependency_attributes].merge!(@dependency_attributes) - - @properties - end - - protected - - # Extends source hash with - # - a) all keys from dest (overwrite mode) - # - b) missing keys (missing mode) - # - # @param mode [Symbol] :overwrite | :if_missing - def merge_hashes(source, dest, mode) - return source if source.nil? || dest.nil? - - if mode == :overwrite - source.merge(dest) - else - dest.merge(source) - end - end - - # Derives model_class from persister class and @name - # 1) searches for class in provider - # 2) if not found, searches class in core - # Can be disabled by options :auto_model_class => false - # - # @example derives model_class from amazon - # - # @persister_class = ManageIQ::Providers::Amazon::Inventory::Persister::CloudManager - # @name = :vms - # - # returns - ::::<@name.classify> - # returns - ::ManageIQ::Providers::Amazon::CloudManager::Vm - # - # @example derives model_class from @name only - # - # @persister_class = ManagerRefresh::Inventory::Persister - # @name = :vms - # - # returns ::Vm - # - # @return [Class | nil] when class doesn't exist, returns nil - def auto_model_class - model_class = begin - # a) Provider specific class - provider_module = ManageIQ::Providers::Inflector.provider_module(@persister_class).name - manager_module = self.class.name.split('::').last - - class_name = "#{provider_module}::#{manager_module}::#{@name.to_s.classify}" - - inferred_class = class_name.safe_constantize - - # safe_constantize can return different similar class ( some Rails auto-magic :/ ) - if inferred_class.to_s == class_name - inferred_class - end - rescue ::ManageIQ::Providers::Inflector::ObjectNotNamespacedError - nil - end - - if model_class - model_class - else - # b) general class - "::#{@name.to_s.classify}".safe_constantize - end - end - - # Enables/disables auto_model_class and exception check - # @param skip [Boolean] - def skip_model_class(skip = true) - @options[:without_model_class] = skip - end - - # Inventory object attributes are derived from setters - # - # Can be disabled by options :auto_inventory_attributes => false - # - attributes can be manually set via method add_inventory_attributes() - def auto_inventory_attributes - return if @properties[:model_class].nil? - - (@properties[:model_class].new.methods - ApplicationRecord.methods).grep(/^[\w]+?\=$/).collect do |setter| - setter.to_s[0..setter.length - 2].to_sym - end - end - - # Enables/disables auto_inventory_attributes - # @param skip [Boolean] - def skip_auto_inventory_attributes(skip = true) - @options[:auto_inventory_attributes] = !skip - end - - # Evaluates lambda blocks in @default_values and @dependency_attributes - # @param values [Hash] - # @param persister [ManagerRefresh::Inventory::Persister] - def evaluate_lambdas_on(values, persister) - values&.transform_values do |value| - if value.respond_to?(:call) - value.call(persister) - else - value - end - end - end - end - end -end diff --git a/app/models/manager_refresh/inventory_collection/builder/automation_manager.rb b/app/models/manager_refresh/inventory_collection/builder/automation_manager.rb deleted file mode 100644 index 2de9a401530f..000000000000 --- a/app/models/manager_refresh/inventory_collection/builder/automation_manager.rb +++ /dev/null @@ -1,56 +0,0 @@ -module ManagerRefresh - class InventoryCollection - class Builder - class AutomationManager < ::ManagerRefresh::InventoryCollection::Builder - def configuration_scripts - default_manager_ref - add_common_default_values - end - - def configuration_script_payloads - add_properties( - :manager_ref => %i(configuration_script_source manager_ref) - ) - add_common_default_values - end - - def configuration_script_sources - default_manager_ref - add_common_default_values - end - - def configured_systems - default_manager_ref - add_common_default_values - end - - def credentials - default_manager_ref - add_default_values( - :resource => ->(persister) { persister.manager } - ) - end - - def inventory_root_groups - add_common_default_values - end - - def vms - add_properties(:manager_ref => %i(uid_ems)) - end - - protected - - def default_manager_ref - add_properties(:manager_ref => %i(manager_ref)) - end - - def add_common_default_values - add_default_values( - :manager => ->(persister) { persister.manager } - ) - end - end - end - end -end diff --git a/app/models/manager_refresh/inventory_collection/builder/cloud_manager.rb b/app/models/manager_refresh/inventory_collection/builder/cloud_manager.rb deleted file mode 100644 index d18ed77147e8..000000000000 --- a/app/models/manager_refresh/inventory_collection/builder/cloud_manager.rb +++ /dev/null @@ -1,213 +0,0 @@ -module ManagerRefresh - class InventoryCollection - class Builder - class CloudManager < ::ManagerRefresh::InventoryCollection::Builder - def availability_zones - add_common_default_values - end - - def flavors - add_common_default_values - end - - def key_pairs - add_properties( - :model_class => ::ManageIQ::Providers::CloudManager::AuthKeyPair, - :manager_ref => %i(name) - ) - add_default_values( - :resource_id => ->(persister) { persister.manager.id }, - :resource_type => ->(persister) { persister.manager.class.base_class } - ) - end - - def vm_and_template_labels - # TODO(lsmola) make a generic CustomAttribute IC and move it to base class - add_properties( - :model_class => ::CustomAttribute, - :manager_ref => %i(resource name), - :parent_inventory_collections => %i(vms miq_templates) - ) - - add_targeted_arel( - lambda do |inventory_collection| - manager_uuids = inventory_collection.parent_inventory_collections.collect(&:manager_uuids).map(&:to_a).flatten - inventory_collection.parent.vm_and_template_labels.where( - 'vms' => {:ems_ref => manager_uuids} - ) - end - ) - end - - def vm_and_template_taggings - add_properties( - :model_class => Tagging, - :manager_ref => %i(taggable tag), - :parent_inventory_collections => %i(vms miq_templates) - ) - - add_targeted_arel( - lambda do |inventory_collection| - manager_uuids = inventory_collection.parent_inventory_collections.collect(&:manager_uuids).map(&:to_a).flatten - ems = inventory_collection.parent - ems.vm_and_template_taggings.where( - 'taggable_id' => ems.vms_and_templates.where(:ems_ref => manager_uuids) - ) - end - ) - end - - def orchestration_stacks - add_properties( - :attributes_blacklist => %i(parent), - ) - - add_common_default_values - end - - def orchestration_stacks_resources - add_properties( - :model_class => ::OrchestrationStackResource, - :parent_inventory_collections => %i(orchestration_stacks) - ) - end - - def orchestration_stacks_outputs - add_properties( - :model_class => ::OrchestrationStackOutput, - :parent_inventory_collections => %i(orchestration_stacks) - ) - end - - def orchestration_stacks_parameters - add_properties( - :model_class => ::OrchestrationStackParameter, - :parent_inventory_collections => %i(orchestration_stacks) - ) - end - - def orchestration_templates - # TODO(lsmola) do refactoring, we shouldn't need this custom saving block\ - orchestration_templates_save_block = lambda do |_ems, inventory_collection| - hashes = inventory_collection.data.map(&:attributes) - - templates = inventory_collection.model_class.find_or_create_by_contents(hashes) - inventory_collection.data.zip(templates).each do |inventory_object, template| - inventory_object.id = template.id - end - end - - add_properties( - :custom_save_block => orchestration_templates_save_block - ) - end - - def orchestration_stack_ancestry - skip_auto_inventory_attributes - skip_model_class - - add_properties( - :custom_save_block => orchestration_stack_ancestry_save_block - ) - - add_dependency_attributes( - :orchestration_stacks => ->(persister) { [persister.collections[:orchestration_stacks]] }, - :orchestration_stacks_resources => ->(persister) { [persister.collections[:orchestration_stacks_resources]] } - ) - end - - def vm_and_miq_template_ancestry - skip_auto_inventory_attributes - skip_model_class - - add_properties( - :custom_save_block => vm_and_miq_template_ancestry_save_block - ) - - add_dependency_attributes( - :vms => ->(persister) { [persister.collections[:vms]] }, - :miq_templates => ->(persister) { [persister.collections[:miq_templates]] } - ) - end - end - - private - - def orchestration_stack_ancestry_save_block - lambda do |_ems, inventory_collection| - stacks_inventory_collection = inventory_collection.dependency_attributes[:orchestration_stacks].try(:first) - - return if stacks_inventory_collection.blank? - - stacks_parents = stacks_inventory_collection.data.each_with_object({}) do |x, obj| - parent_id = x.data[:parent].try(:load).try(:id) - obj[x.id] = parent_id if parent_id - end - - model_class = stacks_inventory_collection.model_class - - stacks_parents_indexed = model_class.select(%i(id ancestry)) - .where(:id => stacks_parents.values).find_each.index_by(&:id) - - ActiveRecord::Base.transaction do - model_class.select(%i(id ancestry)) - .where(:id => stacks_parents.keys).find_each do |stack| - parent = stacks_parents_indexed[stacks_parents[stack.id]] - stack.update_attribute(:parent, parent) - end - end - end - end - - def vm_and_miq_template_ancestry_save_block - lambda do |_ems, inventory_collection| - vms_inventory_collection = inventory_collection.dependency_attributes[:vms].try(:first) - miq_templates_inventory_collection = inventory_collection.dependency_attributes[:miq_templates].try(:first) - - return if vms_inventory_collection.blank? || miq_templates_inventory_collection.blank? - - # Fetch IDs of all vms and genealogy_parents, only if genealogy_parent is present - vms_genealogy_parents = vms_inventory_collection.data.each_with_object({}) do |x, obj| - unless x.data[:genealogy_parent].nil? - genealogy_parent_id = x.data[:genealogy_parent].load.try(:id) - obj[x.id] = genealogy_parent_id if genealogy_parent_id - end - end - - miq_template_genealogy_parents = miq_templates_inventory_collection.data.each_with_object({}) do |x, obj| - unless x.data[:genealogy_parent].nil? - genealogy_parent_id = x.data[:genealogy_parent].load.try(:id) - obj[x.id] = genealogy_parent_id if genealogy_parent_id - end - end - - ActiveRecord::Base.transaction do - # associate parent templates to child instances - parent_miq_templates = miq_templates_inventory_collection.model_class - .select([:id]) - .where(:id => vms_genealogy_parents.values).find_each.index_by(&:id) - vms_inventory_collection.model_class - .select([:id]) - .where(:id => vms_genealogy_parents.keys).find_each do |vm| - parent = parent_miq_templates[vms_genealogy_parents[vm.id]] - vm.with_relationship_type('genealogy') { vm.parent = parent } - end - end - - ActiveRecord::Base.transaction do - # associate parent instances to child templates - parent_vms = vms_inventory_collection.model_class - .select([:id]) - .where(:id => miq_template_genealogy_parents.values).find_each.index_by(&:id) - miq_templates_inventory_collection.model_class - .select([:id]) - .where(:id => miq_template_genealogy_parents.keys).find_each do |miq_template| - parent = parent_vms[miq_template_genealogy_parents[miq_template.id]] - miq_template.with_relationship_type('genealogy') { miq_template.parent = parent } - end - end - end - end - end - end -end diff --git a/app/models/manager_refresh/inventory_collection/builder/container_manager.rb b/app/models/manager_refresh/inventory_collection/builder/container_manager.rb deleted file mode 100644 index f0e51fb0c355..000000000000 --- a/app/models/manager_refresh/inventory_collection/builder/container_manager.rb +++ /dev/null @@ -1,268 +0,0 @@ -module ManagerRefresh - class InventoryCollection - class Builder - class ContainerManager < ::ManagerRefresh::InventoryCollection::Builder - # TODO: (agrare) Targeted refreshes will require adjusting the associations / arels. (duh) - def container_projects - add_properties( - :secondary_refs => {:by_name => %i(name)}, - :delete_method => :disconnect_inv - ) - add_common_default_values - end - - def container_quotas - add_properties( - :attributes_blacklist => %i(namespace), - :delete_method => :disconnect_inv - ) - add_common_default_values - end - - def container_quota_scopes - add_properties( - :manager_ref => %i(container_quota scope), - :parent_inventory_collections => %i(container_quotas) - ) - end - - def container_quota_items - add_properties( - :manager_ref => %i(container_quota resource quota_desired quota_enforced quota_observed), - :delete_method => :disconnect_inv, - :parent_inventory_collections => %i(container_quotas) - ) - end - - def container_limits - add_properties( - :attributes_blacklist => %i(namespace) - ) - add_common_default_values - end - - def container_limit_items - add_properties( - :manager_ref => %i(container_limit resource item_type), - :parent_inventory_collections => %i(container_limits) - ) - end - - def container_nodes - add_properties( - :model_class => ::ContainerNode, - :secondary_refs => {:by_name => %i(name)}, - :delete_method => :disconnect_inv - ) - add_common_default_values - end - - def computer_systems - add_properties( - :manager_ref => %i(managed_entity), - # TODO(lsmola) can we introspect this from the relation? Basically, the - # :parent_inventory_collections are needed only if :association goes :through other association. Then the - # parent is actually the root association (if we chain several :through associations). We should be able to - # create a tree of :through associations of ems and infer the parent_inventory_collections from that? - :parent_inventory_collections => %i(container_nodes), - ) - end - - def computer_system_hardwares - add_properties( - :model_class => ::Hardware, - :manager_ref => %i(computer_system), - :parent_inventory_collections => %i(container_nodes), - ) - end - - def computer_system_operating_systems - add_properties( - :model_class => ::OperatingSystem, - :manager_ref => %i(computer_system), - :parent_inventory_collections => %i(container_nodes), - ) - end - - # images have custom_attributes but that's done conditionally in openshift parser - def container_images - add_properties( - # TODO: (bpaskinc) old save matches on [:image_ref, :container_image_registry_id] - # TODO: (bpaskinc) should match on digest when available - # TODO: (mslemr) provider-specific class exists (openshift), but specs fail with them (?) - :model_class => ::ContainerImage, - :manager_ref => %i(image_ref), - :delete_method => :disconnect_inv, - :custom_reconnect_block => custom_reconnect_block - ) - add_common_default_values - end - - def container_image_registries - add_properties(:manager_ref => %i(host port)) - add_common_default_values - end - - def container_groups - add_properties( - :model_class => ContainerGroup, - :secondary_refs => {:by_container_project_and_name => %i(container_project name)}, - :attributes_blacklist => %i(namespace), - :delete_method => :disconnect_inv, - :custom_reconnect_block => custom_reconnect_block - ) - add_common_default_values - end - - def container_volumes - add_properties( - :manager_ref => %i(parent name), - :parent_inventory_collections => %i(container_groups), - ) - end - - def containers - add_properties( - :model_class => Container, - # parser sets :ems_ref => "#{pod_id}_#{container.name}_#{container.image}" - :delete_method => :disconnect_inv, - :custom_reconnect_block => custom_reconnect_block - ) - add_common_default_values - end - - def container_port_configs - # parser sets :ems_ref => "#{pod_id}_#{container_name}_#{port_config.containerPort}_#{port_config.hostPort}_#{port_config.protocol}" - add_properties( - :parent_inventory_collections => %i(containers) - ) - end - - def container_env_vars - add_properties( - # TODO: (agrare) old save matches on all :name, :value, :field_path - does this matter? - :manager_ref => %i(container name), - :parent_inventory_collections => %i(containers) - ) - end - - def security_contexts - add_properties( - :manager_ref => %i(resource), - :parent_inventory_collections => %i(containers) - ) - end - - def container_replicators - add_properties( - :secondary_refs => {:by_container_project_and_name => %i(container_project name)}, - :attributes_blacklist => %i(namespace) - ) - add_common_default_values - end - - def container_services - add_properties( - :secondary_refs => {:by_container_project_and_name => %i(container_project name)}, - :attributes_blacklist => %i(namespace), - :saver_strategy => "default" # TODO: (fryguy) (perf) Can't use batch strategy because of usage of M:N container_groups relation - ) - add_common_default_values - end - - def container_service_port_configs - add_properties( - :manager_ref => %i(ems_ref protocol), # TODO: (lsmola) make protocol part of the ems_ref?) - :parent_inventory_collections => %i(container_services) - ) - end - - def container_routes - add_properties( - :attributes_blacklist => %i(namespace), - :parent_inventory_collections => %i(container_services) - ) - add_common_default_values - end - - def container_templates - add_properties( - :model_class => ::ContainerTemplate, - :attributes_blacklist => %i(namespace) - ) - add_common_default_values - end - - def container_template_parameters - add_properties( - :manager_ref => %i(container_template name), - :parent_inventory_collections => %i(container_templates) - ) - end - - def container_builds - add_properties( - :secondary_refs => {:by_namespace_and_name => %i(namespace name)} - ) - add_common_default_values - end - - def container_build_pods - add_properties( - # TODO: (bpaskinc) convert namespace column -> container_project_id? - :manager_ref => %i(namespace name), - :secondary_refs => {:by_namespace_and_name => %i(namespace name)}, - ) - add_common_default_values - end - - def persistent_volumes - add_default_values(:parent => ->(persister) { persister.manager }) - end - - def persistent_volume_claims - add_properties( - :secondary_refs => {:by_container_project_and_name => %i(container_project name)}, - :attributes_blacklist => %i(namespace) - ) - add_common_default_values - end - - protected - - def custom_reconnect_block - # TODO(lsmola) once we have DB unique indexes, we can stop using manual reconnect, since it adds processing time - lambda do |inventory_collection, inventory_objects_index, attributes_index| - relation = inventory_collection.model_class.where(:ems_id => inventory_collection.parent.id).archived - - # Skip reconnect if there are no archived entities - return if relation.archived.count <= 0 - raise "Allowed only manager_ref size of 1, got #{inventory_collection.manager_ref}" if inventory_collection.manager_ref.count > 1 - - inventory_objects_index.each_slice(1000) do |batch| - relation.where(inventory_collection.manager_ref.first => batch.map(&:first)).each do |record| - index = inventory_collection.object_index_with_keys(inventory_collection.manager_ref_to_cols, record) - - # We need to delete the record from the inventory_objects_index and attributes_index, otherwise it - # would be sent for create. - inventory_object = inventory_objects_index.delete(index) - hash = attributes_index.delete(index) - - # Make the entity active again, otherwise we would be duplicating nested entities - hash[:deleted_on] = nil - - record.assign_attributes(hash.except(:id, :type)) - if !inventory_collection.check_changed? || record.changed? - record.save! - inventory_collection.store_updated_records(record) - end - - inventory_object.id = record.id - end - end - end - end - end - end - end -end diff --git a/app/models/manager_refresh/inventory_collection/builder/infra_manager.rb b/app/models/manager_refresh/inventory_collection/builder/infra_manager.rb deleted file mode 100644 index 086157f6622a..000000000000 --- a/app/models/manager_refresh/inventory_collection/builder/infra_manager.rb +++ /dev/null @@ -1,266 +0,0 @@ -module ManagerRefresh - class InventoryCollection - class Builder - class InfraManager < ::ManagerRefresh::InventoryCollection::Builder - def networks - add_properties( - :manager_ref => %i(hardware ipaddress ipv6address), - :parent_inventory_collections => %i(vms miq_templates), - ) - end - - def host_networks - add_properties( - :model_class => ::Network, - :manager_ref => %i(hardware ipaddress), - :parent_inventory_collections => %i(hosts) - ) - end - - def guest_devices - add_properties( - :manager_ref => %i(hardware uid_ems), - :parent_inventory_collections => %i(vms miq_templates), - ) - end - - def host_guest_devices - add_properties( - :model_class => ::GuestDevice, - :manager_ref => %i(hardware uid_ems), - :parent_inventory_collections => %i(hosts), - ) - end - - def host_hardwares - add_properties( - :model_class => ::Hardware, - :manager_ref => %i(host), - :parent_inventory_collections => %i(hosts) - ) - end - - def host_system_services - add_properties( - :model_class => ::SystemService, - :manager_ref => %i(host name), - :parent_inventory_collections => %i(hosts) - ) - end - - def snapshots - add_properties( - :manager_ref => %i(uid), - :parent_inventory_collections => %i(vms miq_templates), - ) - end - - def operating_systems - add_properties( - :manager_ref => %i(vm_or_template), - :parent_inventory_collections => %i(vms miq_templates), - ) - end - - def host_operating_systems - add_properties( - :model_class => ::OperatingSystem, - :manager_ref => %i(host), - :parent_inventory_collections => %i(hosts), - ) - end - - def ems_custom_attributes - add_properties( - :model_class => ::CustomAttribute, - :manager_ref => %i(name), - :parent_inventory_collections => %i(vms miq_templates), - ) - end - - def vm_and_template_ems_custom_fields - skip_auto_inventory_attributes - - add_properties( - :model_class => ::CustomAttribute, - :manager_ref => %i(name), - :parent_inventory_collections => %i(vms) - ) - - add_inventory_attributes(%i(section name value source resource)) - end - - def ems_folders - add_properties( - :manager_ref => %i(uid_ems), - :attributes_blacklist => %i(ems_children), - ) - add_common_default_values - end - - def datacenters - add_common_default_values - end - - def resource_pools - add_properties( - :manager_ref => %i(uid_ems), - :attributes_blacklist => %i(ems_children), - ) - add_common_default_values - end - - def ems_clusters - add_properties( - :attributes_blacklist => %i(ems_children datacenter_id), - ) - - add_inventory_attributes(%i(datacenter_id)) - add_common_default_values - end - - def storages - add_properties( - :manager_ref => %i(location), - :complete => false, - :arel => Storage, - ) - end - - def hosts - add_common_default_values - - add_custom_reconnect_block( - lambda do |inventory_collection, inventory_objects_index, attributes_index| - relation = inventory_collection.model_class.where(:ems_id => nil) - - return if relation.count <= 0 - - inventory_objects_index.each_slice(100) do |batch| - relation.where(inventory_collection.manager_ref.first => batch.map(&:first)).each do |record| - index = inventory_collection.object_index_with_keys(inventory_collection.manager_ref_to_cols, record) - - # We need to delete the record from the inventory_objects_index and attributes_index, otherwise it - # would be sent for create. - inventory_object = inventory_objects_index.delete(index) - hash = attributes_index.delete(index) - - record.assign_attributes(hash.except(:id, :type)) - if !inventory_collection.check_changed? || record.changed? - record.save! - inventory_collection.store_updated_records(record) - end - - inventory_object.id = record.id - end - end - end - ) - end - - def vms - super - - custom_reconnect_block = lambda do |inventory_collection, inventory_objects_index, attributes_index| - relation = inventory_collection.model_class.where(:ems_id => nil) - - return if relation.count <= 0 - - inventory_objects_index.each_slice(100) do |batch| - relation.where(inventory_collection.manager_ref.first => batch.map(&:first)).each do |record| - index = inventory_collection.object_index_with_keys(inventory_collection.manager_ref_to_cols, record) - - # We need to delete the record from the inventory_objects_index and attributes_index, otherwise it - # would be sent for create. - inventory_object = inventory_objects_index.delete(index) - hash = attributes_index.delete(index) - - record.assign_attributes(hash.except(:id, :type)) - if !inventory_collection.check_changed? || record.changed? - record.save! - inventory_collection.store_updated_records(record) - end - - inventory_object.id = record.id - end - end - end - - add_properties( - :custom_reconnect_block => custom_reconnect_block - ) - end - - def host_storages - add_properties( - :manager_ref => %i(host storage), - :parent_inventory_collections => %i(hosts) - ) - end - - def host_switches - add_properties( - :manager_ref => %i(host switch), - :parent_inventory_collections => %i(hosts) - ) - end - - def switches - add_properties( - :manager_ref => %i(uid_ems), # TODO looks like switches are using a bad association, this one is defined as through hosts - ) - add_common_default_values - end - - def lans - add_properties( - :manager_ref => %i(uid_ems), - :parent_inventory_collections => %i(hosts), - ) - end - - def snapshot_parent - snapshot_parent_save_block = lambda do |_ems, inventory_collection| - snapshot_collection = inventory_collection.dependency_attributes[:snapshots].try(:first) - - snapshot_collection.each do |snapshot| - ActiveRecord::Base.transaction do - child = Snapshot.find(snapshot.id) - parent = Snapshot.find_by(:uid_ems => snapshot.parent_uid) - child.update_attribute(:parent_id, parent.try(:id)) - end - end - end - - add_properties( - :custom_save_block => snapshot_parent_save_block - ) - end - - def customization_specs - add_properties(:manager_ref => %i(name)) - - add_common_default_values - end - - def miq_scsi_luns - add_properties( - :manager_ref => %i(miq_scsi_target uid_ems), - :parent_inventory_collections => %i(hosts) - ) - end - - def miq_scsi_targets - add_properties( - :manager_ref => %i(guest_device uid_ems), - :parent_inventory_collections => %i(hosts) - ) - end - - def storage_profiles - add_common_default_values - end - end - end - end -end diff --git a/app/models/manager_refresh/inventory_collection/builder/network_manager.rb b/app/models/manager_refresh/inventory_collection/builder/network_manager.rb deleted file mode 100644 index 084b0917385f..000000000000 --- a/app/models/manager_refresh/inventory_collection/builder/network_manager.rb +++ /dev/null @@ -1,212 +0,0 @@ -module ManagerRefresh - class InventoryCollection - class Builder - class NetworkManager < ::ManagerRefresh::InventoryCollection::Builder - def cloud_subnet_network_ports - add_properties( - # :model_class => ::CloudSubnetNetworkPort, - :manager_ref => %i(address cloud_subnet network_port), - :parent_inventory_collections => %i(vms network_ports load_balancers) - ) - - add_targeted_arel( - lambda do |inventory_collection| - manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } - inventory_collection.parent.cloud_subnet_network_ports.references(:network_ports).where( - :network_ports => {:ems_ref => manager_uuids} - ) - end - ) - end - - def network_ports - add_properties( - :use_ar_object => true, - # TODO(lsmola) can't do batch strategy for network_ports because of security_groups relation - :saver_strategy => :default - ) - - add_common_default_values - end - - def network_groups - add_common_default_values - end - - def network_routers - add_common_default_values - end - - def floating_ips - add_common_default_values - end - - def cloud_tenants - add_common_default_values - end - - def cloud_subnets - add_common_default_values - end - - def cloud_networks - add_common_default_values - end - - def security_groups - add_common_default_values - end - - def firewall_rules - add_properties( - :manager_ref => %i(resource source_security_group direction host_protocol port end_port source_ip_range), - :parent_inventory_collections => %i(security_groups) - ) - end - - def load_balancers - add_common_default_values - end - - def load_balancer_pools - add_properties( - :parent_inventory_collections => %i(load_balancers) - ) - - add_targeted_arel( - lambda do |inventory_collection| - manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } - inventory_collection.parent.load_balancer_pools - .joins(:load_balancers) - .where(:load_balancers => {:ems_ref => manager_uuids}) - .distinct - end - ) - - add_common_default_values - end - - def load_balancer_pool_members - add_properties( - :parent_inventory_collections => %i(load_balancers) - ) - - add_targeted_arel( - lambda do |inventory_collection| - manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } - inventory_collection.parent.load_balancer_pool_members - .joins(:load_balancer_pool_member_pools => [:load_balancer_pool => :load_balancers]) - .where(:load_balancer_pool_member_pools => { - 'load_balancer_pools' => { - 'load_balancers' => { - :ems_ref => manager_uuids - } - } - }).distinct - end - ) - - add_common_default_values - end - - def load_balancer_pool_member_pools - add_properties( - :manager_ref => %i(load_balancer_pool load_balancer_pool_member), - :parent_inventory_collections => %i(load_balancers) - ) - - add_targeted_arel( - lambda do |inventory_collection| - manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } - inventory_collection.parent.load_balancer_pool_member_pools - .joins(:load_balancer_pool => :load_balancers) - .where(:load_balancer_pools => { 'load_balancers' => { :ems_ref => manager_uuids } }) - .distinct - end - ) - end - - def load_balancer_listeners - add_properties( - :use_ar_object => true, - :parent_inventory_collections => %i(load_balancers), - ) - - add_targeted_arel( - lambda do |inventory_collection| - manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } - inventory_collection.parent.load_balancer_listeners - .joins(:load_balancer) - .where(:load_balancers => {:ems_ref => manager_uuids}) - .distinct - end - ) - - add_common_default_values - end - - def load_balancer_listener_pools - add_properties( - :manager_ref => %i(load_balancer_listener load_balancer_pool), - :parent_inventory_collections => %i(load_balancers) - ) - - add_targeted_arel( - lambda do |inventory_collection| - manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } - inventory_collection.parent.load_balancer_listener_pools - .joins(:load_balancer_pool => :load_balancers) - .where(:load_balancer_pools => {'load_balancers' => {:ems_ref => manager_uuids}}) - .distinct - end - ) - end - - def load_balancer_health_checks - add_properties( - :parent_inventory_collections => %i(load_balancers) - ) - - add_targeted_arel( - lambda do |inventory_collection| - manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } - inventory_collection.parent.load_balancer_health_checks - .joins(:load_balancer) - .where(:load_balancers => {:ems_ref => manager_uuids}) - .distinct - end - ) - - add_common_default_values - end - - def load_balancer_health_check_members - add_properties( - :manager_ref => %i(load_balancer_health_check load_balancer_pool_member), - :parent_inventory_collections => %i(load_balancers) - ) - - add_targeted_arel( - lambda do |inventory_collection| - manager_uuids = inventory_collection.parent_inventory_collections.flat_map { |c| c.manager_uuids.to_a } - inventory_collection.parent.load_balancer_health_check_members - .joins(:load_balancer_health_check => :load_balancer) - .where(:load_balancer_health_checks => {'load_balancers' => {:ems_ref => manager_uuids}}) - .distinct - end - ) - end - - protected - - def add_common_default_values - add_default_values(:ems_id => default_ems_id) - end - - def default_ems_id - ->(persister) { persister.manager.try(:network_manager).try(:id) || persister.manager.id } - end - end - end - end -end diff --git a/app/models/manager_refresh/inventory_collection/builder/physical_infra_manager.rb b/app/models/manager_refresh/inventory_collection/builder/physical_infra_manager.rb deleted file mode 100644 index a7d655c828b9..000000000000 --- a/app/models/manager_refresh/inventory_collection/builder/physical_infra_manager.rb +++ /dev/null @@ -1,41 +0,0 @@ -module ManagerRefresh - class InventoryCollection - class Builder - class PhysicalInfraManager < ::ManagerRefresh::InventoryCollection::Builder - def physical_servers - add_common_default_values - end - - def physical_server_details - add_properties( - :model_class => ::AssetDetail, - :manager_ref => %i(resource), - :parent_inventory_collections => %i(physical_servers) - ) - end - - def computer_systems - add_properties( - :manager_ref => %i(managed_entity), - :parent_inventory_collections => %i(physical_servers) - ) - end - - def hardwares - add_properties( - :manager_ref => %i(computer_system), - :parent_inventory_collections => %i(physical_servers) - ) - end - - def physical_racks - add_common_default_values - end - - def physical_chassis - add_common_default_values - end - end - end - end -end diff --git a/app/models/manager_refresh/inventory_collection/builder/storage_manager.rb b/app/models/manager_refresh/inventory_collection/builder/storage_manager.rb deleted file mode 100644 index 1cb0cf808b1e..000000000000 --- a/app/models/manager_refresh/inventory_collection/builder/storage_manager.rb +++ /dev/null @@ -1,9 +0,0 @@ -module ManagerRefresh - class InventoryCollection - class Builder - class StorageManager < ::ManagerRefresh::InventoryCollection::Builder - # Nothing there - end - end - end -end diff --git a/spec/models/manager_refresh/inventory_collection/builder_spec.rb b/spec/models/manager_refresh/persister/builder_spec.rb similarity index 94% rename from spec/models/manager_refresh/inventory_collection/builder_spec.rb rename to spec/models/manager_refresh/persister/builder_spec.rb index 45a5cc649dd6..b26d894ef52c 100644 --- a/spec/models/manager_refresh/inventory_collection/builder_spec.rb +++ b/spec/models/manager_refresh/persister/builder_spec.rb @@ -1,6 +1,6 @@ -require_relative '../persister/test_persister' +require_relative 'test_persister' -describe ManagerRefresh::InventoryCollection::Builder do +describe ManagerRefresh::Inventory::Persister::Builder do before :each do @zone = FactoryGirl.create(:zone) @ems = FactoryGirl.create(:ems_cloud, @@ -15,9 +15,9 @@ def create_persister let(:adv_settings) { {:strategy => :local_db_find_missing_references, :saver_strategy => :concurrent_safe_batch} } - let(:cloud) { ::ManagerRefresh::InventoryCollection::Builder::CloudManager } + let(:cloud) { ::ManagerRefresh::Inventory::Persister::Builder::CloudManager } - let(:network) { ::ManagerRefresh::InventoryCollection::Builder::NetworkManager } + let(:network) { ::ManagerRefresh::Inventory::Persister::Builder::NetworkManager } let(:persister_class) { ::ManagerRefresh::Inventory::Persister } @@ -58,7 +58,7 @@ def create_persister it 'throws exception if model_class not specified' do builder = cloud.prepare_data(:non_existing_ic, persister_class) - expect { builder.to_inventory_collection }.to raise_error(::ManagerRefresh::InventoryCollection::Builder::MissingModelClassError) + expect { builder.to_inventory_collection }.to raise_error(::ManagerRefresh::Inventory::Persister::Builder::MissingModelClassError) end # --- adv. settings (TODO: link to gui)--- diff --git a/spec/models/manager_refresh/save_inventory/init_data_helper.rb b/spec/models/manager_refresh/save_inventory/init_data_helper.rb index 44fab7964677..4d91b417b6fb 100644 --- a/spec/models/manager_refresh/save_inventory/init_data_helper.rb +++ b/spec/models/manager_refresh/save_inventory/init_data_helper.rb @@ -87,11 +87,11 @@ def container_quota_items_attrs_init_data(extra_attributes = {}) end def cloud - ManagerRefresh::InventoryCollection::Builder::CloudManager + ManagerRefresh::Inventory::Persister::Builder::CloudManager end def network - ManagerRefresh::InventoryCollection::Builder::NetworkManager + ManagerRefresh::Inventory::Persister::Builder::NetworkManager end def persister_class