From 41060e103703fd703cd18c91738d3e0f3df61838 Mon Sep 17 00:00:00 2001
From: Ladislav Smola <lsmola@redhat.com>
Date: Wed, 8 Feb 2017 14:02:08 +0100
Subject: [PATCH 1/5] InventoryCollectionDefault base class

InventoryCollectionDefault base class
---
 app/models/manager_refresh/inventory_collection_default.rb | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 app/models/manager_refresh/inventory_collection_default.rb

diff --git a/app/models/manager_refresh/inventory_collection_default.rb b/app/models/manager_refresh/inventory_collection_default.rb
new file mode 100644
index 00000000000..1dcbe7dfd26
--- /dev/null
+++ b/app/models/manager_refresh/inventory_collection_default.rb
@@ -0,0 +1,2 @@
+class ManagerRefresh::InventoryCollectionDefault
+end

From 1ffdad9f715116818ea4bef80147037dc054507d Mon Sep 17 00:00:00 2001
From: Ladislav Smola <lsmola@redhat.com>
Date: Wed, 8 Feb 2017 14:02:46 +0100
Subject: [PATCH 2/5] Shared configurations of InventoryCollections for
 CloudManager

Shared configurations of InventoryCollections for CloudManager
---
 .../cloud_manager.rb                          | 226 ++++++++++++++++++
 1 file changed, 226 insertions(+)
 create mode 100644 app/models/manager_refresh/inventory_collection_default/cloud_manager.rb

diff --git a/app/models/manager_refresh/inventory_collection_default/cloud_manager.rb b/app/models/manager_refresh/inventory_collection_default/cloud_manager.rb
new file mode 100644
index 00000000000..586ef2f8764
--- /dev/null
+++ b/app/models/manager_refresh/inventory_collection_default/cloud_manager.rb
@@ -0,0 +1,226 @@
+class ManagerRefresh::InventoryCollectionDefault::CloudManager < ManagerRefresh::InventoryCollectionDefault
+  class << self
+    def vms(extra_attributes = {})
+      attributes = {
+        :model_class          => ::ManageIQ::Providers::CloudManager::Vm,
+        :association          => :vms,
+        :attributes_blacklist => [:genealogy_parent]
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def miq_templates(extra_attributes = {})
+      attributes = {
+        :model_class => ::ManageIQ::Providers::CloudManager::Template,
+        :association => :miq_templates,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def availability_zones(extra_attributes = {})
+      attributes = {
+        :model_class => ::AvailabilityZone,
+        :association => :availability_zones,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def flavors(extra_attributes = {})
+      attributes = {
+        :model_class => ::Flavor,
+        :association => :flavors,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def key_pairs(extra_attributes = {})
+      attributes = {
+        :model_class => ::ManageIQ::Providers::CloudManager::AuthKeyPair,
+        :manager_ref => [:name],
+        :association => :key_pairs
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def hardwares(extra_attributes = {})
+      attributes = {
+        :model_class => ::Hardware,
+        :manager_ref => [:vm_or_template],
+        :association => :hardwares
+      }
+
+      case extra_attributes[:strategy]
+      when :local_db_cache_all
+        attributes[:custom_manager_uuid] = lambda do |hardware|
+          [hardware.vm_or_template.ems_ref]
+        end
+      when :find_missing_in_local_db
+        attributes[:custom_db_finder] = lambda do |inventory_collection, hash_uuid_by_ref|
+          inventory_collection.parent.send(inventory_collection.association).references(:vm_or_template).where(
+            :vms => {:ems_ref => hash_uuid_by_ref[:vm_or_template]}
+          ).first
+        end
+      end
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def disks(extra_attributes = {})
+      attributes = {
+        :model_class => ::Disk,
+        :manager_ref => [:hardware, :device_name],
+        :association => :disks
+      }
+
+      if extra_attributes[:strategy] == :local_db_cache_all
+        attributes[:custom_manager_uuid] = lambda do |disk|
+          [disk.hardware.vm_or_template.ems_ref, disk.device_name]
+        end
+      end
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def networks(extra_attributes = {})
+      attributes = {
+        :model_class => ::Network,
+        :manager_ref => [:hardware, :description],
+        :association => :networks
+      }
+
+      if extra_attributes[:strategy] == :local_db_cache_all
+        attributes[:custom_manager_uuid] = lambda do |network|
+          [network.hardware.vm_or_template.ems_ref, network.description]
+        end
+      end
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def orchestration_stacks(extra_attributes = {})
+      attributes = {
+        :model_class          => ::ManageIQ::Providers::CloudManager::OrchestrationStack,
+        :association          => :orchestration_stacks,
+        :attributes_blacklist => [:parent]
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def orchestration_stacks_resources(extra_attributes = {})
+      attributes = {
+        :model_class => ::OrchestrationStackResource,
+        :association => :orchestration_stacks_resources,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def orchestration_stacks_outputs(extra_attributes = {})
+      attributes = {
+        :model_class => ::OrchestrationStackOutput,
+        :association => :orchestration_stacks_outputs,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def orchestration_stacks_parameters(extra_attributes = {})
+      attributes = {
+        :model_class => ::OrchestrationStackParameter,
+        :association => :orchestration_stacks_parameters,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def orchestration_templates(extra_attributes = {})
+      # TODO(lsmola) do refactoring, we shouldn't need this custom saving block
+      orchestration_template_save_block = lambda do |_ems, inventory_collection|
+        hashes = inventory_collection.data.map(&:attributes)
+
+        templates = ::OrchestrationTemplate.find_or_create_by_contents(hashes)
+        inventory_collection.data.zip(templates).each do |inventory_object, template|
+          inventory_object.id = template.id
+        end
+      end
+
+      attributes = {
+        :model_class       => ::OrchestrationTemplateCfn,
+        :association       => :orchestration_templates,
+        :custom_save_block => orchestration_template_save_block
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def orchestration_stack_ancestry(extra_attributes = {})
+      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].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([:id, :ancestry])
+                                   .where(:id => stacks_parents.values).find_each.index_by(&:id)
+
+        model_class
+          .select([: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
+
+      attributes = {
+        :association       => :orchestration_stack_ancestry,
+        :custom_save_block => orchestration_stack_ancestry_save_block
+      }
+      attributes.merge!(extra_attributes)
+    end
+
+    def vm_and_miq_template_ancestry(extra_attributes = {})
+      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 = inventory_collection.dependency_attributes[:vms].first.data.each_with_object({}) do |x, obj|
+          genealogy_parent_id = x.data[:genealogy_parent].load.try(:id)
+          obj[x.id]           = genealogy_parent_id if genealogy_parent_id
+        end
+
+        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 = miq_templates[vms_genealogy_parents[vm.id]]
+          parent.with_relationship_type('genealogy') { parent.set_child(vm) }
+        end
+      end
+
+      attributes = {
+        :association       => :vm_and_miq_template_ancestry,
+        :custom_save_block => vm_and_miq_template_ancestry_save_block,
+      }
+      attributes.merge!(extra_attributes)
+    end
+  end
+end

From 31d3369a10fcdf6f394e850c74f4125206d116f5 Mon Sep 17 00:00:00 2001
From: Ladislav Smola <lsmola@redhat.com>
Date: Wed, 8 Feb 2017 14:04:00 +0100
Subject: [PATCH 3/5] Shared configurations of InventoryCollections for
 NetworkManager

Shared configurations of InventoryCollections for NetworkManager
---
 .../network_manager.rb                        | 143 ++++++++++++++++++
 1 file changed, 143 insertions(+)
 create mode 100644 app/models/manager_refresh/inventory_collection_default/network_manager.rb

diff --git a/app/models/manager_refresh/inventory_collection_default/network_manager.rb b/app/models/manager_refresh/inventory_collection_default/network_manager.rb
new file mode 100644
index 00000000000..26e143a6ece
--- /dev/null
+++ b/app/models/manager_refresh/inventory_collection_default/network_manager.rb
@@ -0,0 +1,143 @@
+class ManagerRefresh::InventoryCollectionDefault::NetworkManager < ManagerRefresh::InventoryCollectionDefault
+  class << self
+    def cloud_subnet_network_ports(extra_attributes = {})
+      attributes = {
+        :model_class => ::CloudSubnetNetworkPort,
+        :manager_ref => [:address, :cloud_subnet, :network_port],
+        :association => :cloud_subnet_network_ports,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def network_ports(extra_attributes = {})
+      attributes = {
+        :model_class => ::NetworkPort,
+        :association => :network_ports,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def floating_ips(extra_attributes = {})
+      attributes = {
+        :model_class => ::FloatingIp,
+        :association => :floating_ips,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def cloud_subnets(extra_attributes = {})
+      attributes = {
+        :model_class => ::CloudSubnet,
+        :association => :cloud_subnets,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def cloud_networks(extra_attributes = {})
+      attributes = {
+        :model_class => ::CloudNetwork,
+        :association => :cloud_networks,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def security_groups(extra_attributes = {})
+      attributes = {
+        :model_class => ::SecurityGroup,
+        :association => :security_groups,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def firewall_rules(extra_attributes = {})
+      attributes = {
+        :model_class => ::FirewallRule,
+        :manager_ref => [:resource, :source_security_group, :direction, :host_protocol, :port, :end_port, :source_ip_range],
+        :association => :firewall_rules,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def load_balancers(extra_attributes = {})
+      attributes = {
+        :model_class => ::LoadBalancer,
+        :association => :load_balancers,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def load_balancer_pools(extra_attributes = {})
+      attributes = {
+        :model_class => ::LoadBalancerPool,
+        :association => :load_balancer_pools,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def load_balancer_pool_members(extra_attributes = {})
+      attributes = {
+        :model_class => ::LoadBalancerPoolMember,
+        :association => :load_balancer_pool_members,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def load_balancer_pool_member_pools(extra_attributes = {})
+      attributes = {
+        :model_class => ::LoadBalancerPoolMemberPool,
+        :manager_ref => [:load_balancer_pool, :load_balancer_pool_member],
+        :association => :load_balancer_pool_member_pools,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def load_balancer_listeners(extra_attributes = {})
+      attributes = {
+        :model_class => ::LoadBalancerListener,
+        :association => :load_balancer_listeners,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def load_balancer_listener_pools(extra_attributes = {})
+      attributes = {
+        :model_class => ::LoadBalancerListenerPool,
+        :manager_ref => [:load_balancer_listener, :load_balancer_pool],
+        :association => :load_balancer_listener_pools,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def load_balancer_health_checks(extra_attributes = {})
+      attributes = {
+        :model_class => ::LoadBalancerHealthCheck,
+        :association => :load_balancer_health_checks,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def load_balancer_health_check_members(extra_attributes = {})
+      attributes = {
+        :model_class => ::LoadBalancerHealthCheckMember,
+        :manager_ref => [:load_balancer_health_check, :load_balancer_pool_member],
+        :association => :load_balancer_health_check_members,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+  end
+end

From dd66d23c6948d09b72498377d368d0d2fe6a8eac Mon Sep 17 00:00:00 2001
From: Ladislav Smola <lsmola@redhat.com>
Date: Wed, 8 Feb 2017 14:04:44 +0100
Subject: [PATCH 4/5] Shared configurations of InventoryCollections for
 StorageManager

Shared configurations of InventoryCollections for StorageManager
---
 .../storage_manager.rb                        | 39 +++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 app/models/manager_refresh/inventory_collection_default/storage_manager.rb

diff --git a/app/models/manager_refresh/inventory_collection_default/storage_manager.rb b/app/models/manager_refresh/inventory_collection_default/storage_manager.rb
new file mode 100644
index 00000000000..f069caa3440
--- /dev/null
+++ b/app/models/manager_refresh/inventory_collection_default/storage_manager.rb
@@ -0,0 +1,39 @@
+class ManagerRefresh::InventoryCollectionDefault::NetworkManager < ManagerRefresh::InventoryCollectionDefault
+  class << self
+    def cloud_volumes(extra_attributes = {})
+      attributes = {
+        :model_class => ::CloudVolume,
+        :association => :cloud_volumes,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def cloud_volume_snapshots(extra_attributes = {})
+      attributes = {
+        :model_class => ::CloudVolumeSnapshot,
+        :association => :cloud_volume_snapshots,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def cloud_object_store_containers(extra_attributes = {})
+      attributes = {
+        :model_class => ::CloudObjectStoreContainer,
+        :association => :cloud_object_store_containers,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+
+    def cloud_object_store_objects(extra_attributes = {})
+      attributes = {
+        :model_class => ::CloudObjectStoreObject,
+        :association => :cloud_object_store_objects,
+      }
+
+      attributes.merge!(extra_attributes)
+    end
+  end
+end

From 9bcc88d522e9bcdef2d73973ad0ae3cc9449263f Mon Sep 17 00:00:00 2001
From: Ladislav Smola <lsmola@redhat.com>
Date: Wed, 8 Feb 2017 14:46:27 +0100
Subject: [PATCH 5/5] Fix rubocop issues

Fix rubocop issues
---
 .../inventory_collection_default/cloud_manager.rb    | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

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 586ef2f8764..f6363bbd2d7 100644
--- a/app/models/manager_refresh/inventory_collection_default/cloud_manager.rb
+++ b/app/models/manager_refresh/inventory_collection_default/cloud_manager.rb
@@ -173,8 +173,8 @@ def orchestration_stack_ancestry(extra_attributes = {})
         model_class = stacks_inventory_collection.model_class
 
         stacks_parents_indexed = model_class
-                                   .select([:id, :ancestry])
-                                   .where(:id => stacks_parents.values).find_each.index_by(&:id)
+                                 .select([:id, :ancestry])
+                                 .where(:id => stacks_parents.values).find_each.index_by(&:id)
 
         model_class
           .select([:id, :ancestry])
@@ -205,12 +205,12 @@ def vm_and_miq_template_ancestry(extra_attributes = {})
         end
 
         miq_templates = miq_templates_inventory_collection.model_class
-                          .select([:id])
-                          .where(:id => vms_genealogy_parents.values).find_each.index_by(&:id)
+                                                          .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|
+                                .select([:id])
+                                .where(:id => vms_genealogy_parents.keys).find_each do |vm|
           parent = miq_templates[vms_genealogy_parents[vm.id]]
           parent.with_relationship_type('genealogy') { parent.set_child(vm) }
         end