Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use inventory object writers and readers instead of hash #13923

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,59 +10,61 @@ def parse
def inventory_root_groups
collector.inventories.each do |inventory|
inventory_object = persister.inventory_root_groups.find_or_build(inventory.id.to_s)
inventory_object[:name] = inventory.name
inventory_object.name = inventory.name
end
end

def configured_systems
collector.hosts.each do |host|
inventory_object = persister.configured_systems.find_or_build(host.id)
inventory_object[:hostname] = host.name
inventory_object[:virtual_instance_ref] = host.instance_id
inventory_object[:inventory_root_group] = persister.inventory_root_groups.lazy_find(host.inventory_id.to_s)
inventory_object[:counterpart] = Vm.find_by(:uid_ems => host.instance_id)
inventory_object.hostname = host.name
inventory_object.virtual_instance_ref = host.instance_id
inventory_object.inventory_root_group = persister.inventory_root_groups.lazy_find(host.inventory_id.to_s)
inventory_object.counterpart = Vm.find_by(:uid_ems => host.instance_id)
end
end

def configuration_scripts
collector.job_templates.each do |job_template|
inventory_object = persister.configuration_scripts.find_or_build(job_template.id.to_s)
inventory_object[:description] = job_template.description
inventory_object[:name] = job_template.name
inventory_object[:survey_spec] = job_template.survey_spec_hash
inventory_object[:variables] = job_template.extra_vars_hash
inventory_object[:inventory_root_group] = persister.inventory_root_groups.lazy_find(job_template.inventory_id.to_s)
inventory_object.description = job_template.description
inventory_object.name = job_template.name
inventory_object.survey_spec = job_template.survey_spec_hash
inventory_object.variables = job_template.extra_vars_hash
inventory_object.inventory_root_group = persister.inventory_root_groups.lazy_find(job_template.inventory_id.to_s)

inventory_object[:authentications] = []
authentications = []
%w(credential_id cloud_credential_id network_credential_id).each do |credential_attr|
next unless job_template.respond_to?(credential_attr)
credential_id = job_template.public_send(credential_attr).to_s
next if credential_id.blank?
inventory_object[:authentications] << persister.credentials.lazy_find(credential_id)
authentications << persister.credentials.lazy_find(credential_id)
end

inventory_object.authentications = authentications
end
end

def configuration_script_sources
collector.projects.each do |project|
inventory_object = persister.configuration_script_sources.find_or_build(project.id.to_s)
inventory_object[:description] = project.description
inventory_object[:name] = project.name
inventory_object.description = project.description
inventory_object.name = project.name

project.playbooks.each do |playbook_name|
# FIXME: its not really nice how I have to build a manager_ref / uuid here
inventory_object_playbook = persister.configuration_script_payloads.find_or_build("#{project.id}__#{playbook_name}")
inventory_object_playbook[:configuration_script_source] = inventory_object
inventory_object_playbook[:name] = playbook_name
inventory_object_playbook.configuration_script_source = inventory_object
inventory_object_playbook.name = playbook_name
end
end
end

def credentials
collector.credentials.each do |credential|
inventory_object = persister.credentials.find_or_build(credential.id.to_s)
inventory_object[:name] = credential.name
inventory_object[:userid] = credential.username
inventory_object.name = credential.name
inventory_object.userid = credential.username
# credential.description
# credential.host
# credential.password
Expand All @@ -82,7 +84,7 @@ def credentials
# credential.client
# credential.authorize
# credential.authorize_password
inventory_object[:type] = case credential.kind
inventory_object.type = case credential.kind
when 'net' then 'ManageIQ::Providers::AnsibleTower::AutomationManager::NetworkCredential'
when 'ssh' then 'ManageIQ::Providers::AnsibleTower::AutomationManager::MachineCredential'
when 'vmware' then 'ManageIQ::Providers::AnsibleTower::AutomationManager::VmwareCredential'
Expand Down
6 changes: 5 additions & 1 deletion app/models/manager_refresh/inventory_collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,12 @@ def lazy_find(manager_uuid, key: nil, default: nil)
::ManagerRefresh::InventoryObjectLazy.new(self, manager_uuid, :key => key, :default => default)
end

def inventory_object_class
@inventory_object_class ||= Class.new(::ManagerRefresh::InventoryObject)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this need the Class.new part?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, so it's only way I found, where we will end up with the right readers/writers on a InventoryObject class, according to model. Otherwise, they were all adding readers/writers into the one InventoryObject class, so it ended up with methods of all models.

Is there some concern wit Class.new? It should be garbage collected as any other object, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just wish I could give it a nice Class name using this construct

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats what I mean with the proper inheritance in my main comment. This is a somewhat hacky and magical way of defining new classes on the fly

end

def new_inventory_object(hash)
::ManagerRefresh::InventoryObject.new(self, hash)
inventory_object_class.new(self, hash)
end

def build(hash)
Expand Down
44 changes: 43 additions & 1 deletion app/models/manager_refresh/inventory_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class InventoryObject
attr_accessor :object, :id
attr_reader :inventory_collection, :data

delegate :manager_ref, :base_class_name, :to => :inventory_collection
delegate :manager_ref, :base_class_name, :model_class, :to => :inventory_collection
delegate :[], :to => :data

def initialize(inventory_collection, data)
Expand Down Expand Up @@ -91,6 +91,48 @@ def []=(key, value)
value
end

def allowed_writers
return [] unless model_class

# Get all writers of a model
@allowed_writers ||= (model_class.new.methods - Object.methods).grep(/^[\w]+?\=$/)
end

def allowed_readers
return [] unless model_class

# Get all readers inferred from writers of a model
@allowed_readers ||= allowed_writers.map { |x| x.to_s.delete("=").to_sym }
end

def method_missing(method_name, *arguments, &block)
if allowed_writers.include?(method_name)
self.class.define_data_writer(method_name)
send(method_name, arguments[0])
elsif allowed_readers.include?(method_name)
self.class.define_data_reader(method_name)
send(method_name)
else
super
end
end

def respond_to_missing?(method_name, _include_private = false)
allowed_writers.include?(method_name) || allowed_readers.include?(method_name) || super
end

def self.define_data_writer(data_key)
define_method(data_key) do |value|
send(:[]=, data_key.to_s.delete("=").to_sym, value)
end
end

def self.define_data_reader(data_key)
define_method(data_key) do
send(:[], data_key)
end
end

private

def association?(inventory_collection_scope, key)
Expand Down