-
Notifications
You must be signed in to change notification settings - Fork 897
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
Enhanced inventory collector target and parser classes #13907
Enhanced inventory collector target and parser classes #13907
Conversation
ManagerRefresh::Inventory::Parser is the new base class for refresh.
Modify Base target class to align with Amazon usecase
Modify Collector base class to align with Amazon usecase
Modify Inventory base class to align with Amazon usecase
Target initialize is taking a collector object as a parameter
Modify Ansible Target to use the new target and manager methods
|
||
# @param manager [ManageIQ::Providers::BaseManager] A manager object | ||
# @param target [ActiveRecord|Hash] A refresh Target object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why could this be a Hash?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Object
def collections | ||
@collections ||= {} | ||
# @param collector [ManagerRefresh::Inventory::Collector] A collector object | ||
def initialize(collector) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if I like the collector being tied to this class.
This increases the coupling
Ansible tower enhance target IC definitions
Unify Target and Collector interface
Allow to overwrite aninsible IC defaults
@Ladas Will this require any changes to the external provider repos? |
Rename Target to Persister under Inventory
@djberg96 yes, but currently only AWS should be affected. @Fryguy we are going with Inventory::Persister instead of Inventory::Target @durandom so now we can do persister.configured_systems instead of persister.collections[:configured_systems]. It uses a method missing that defines a getter using collections, so it should be quick enough. |
Dynamic access of collections with Rails like method cache, first pass goes through methods missing and looks into collections hash by creating a getter metho. So second+ pass is much faster.
12ba718
to
c333f2d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really ❤️ that we move from Inventory::Target
to Inventory::Persister
- though this name is still a bit strange, but 🤷♂️ <- thanks github
Besides internal naming of some attributes and some comments about future refactorings, thats good stuff
|
||
def self.define_collections_reader(collection_key) | ||
define_method(collection_key) do | ||
collections.try(:[], collection_key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why try here? collections will always respond to []
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, it's initialized to {}, so it should be safe
attr_reader :manager, :target, :collections | ||
|
||
# @param manager [ManageIQ::Providers::BaseManager] A manager object | ||
# @param target [Object] A refresh Target object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, do we already have something else than an ActiveRecord::Base
as a target?
If not, I'd put this in here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I have the TargetCollection, which is not AR based class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you put an OR (|
) in there? knowing it is an ActiveRecord::Base
(or similar) seems to be helpful
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I need to finish the targeted refresh to know what will come through here, so I was thinking Object for now, which is always true :-D
|
||
# @param manager [ManageIQ::Providers::BaseManager] A manager object | ||
# @param target [Object] A refresh Target object | ||
def initialize(manager, refresh_target) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be target
# | ||
# @param inventory_collection_data [Hash] Hash used for ManagerRefresh::InventoryCollection initialize | ||
def add_inventory_collection(inventory_collection_data) | ||
data = inventory_collection_data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this assignment?
I find neither data
nor inventory_collection_data
really revealing.
How about init_params
or just params
, or just options
- at least options is what we are used to read as init_options
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I just wanted to fit to 120 cols :-) not sure why I did this. :-)
'options' sounds good
data = inventory_collection_data | ||
data[:parent] ||= manager | ||
|
||
if !data.key?(:delete_method) && data[:model_class] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if there is no :delete_method
and not :model_class
?
If thats a problem, I think that should be guarded in the initializer of InventoryCollection
Maybe not now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the default delete method is always rails :destroy, this helper just sets it to disconnect_inv if there is any defined
The alternative might be to have this defined in the MIQ core definitions
|
||
if !data.key?(:delete_method) && data[:model_class] | ||
# Automatically infer what the delete method should be, unless the delete methods was given | ||
data[:delete_method] = data[:model_class].new.respond_to?(:disconnect_inv) ? :disconnect_inv : nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like the coupling and magic.
I rather have this explicit in the Default
classes.
You know, the less magic the better. People have to directly see they need a :delete_method
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, make sense, I was leaning towards this too
# @param default [ManagerRefresh::InventoryCollectionDefault] Default | ||
# @param inventory_collections [Array] Array of method names for passed default parameter | ||
# @param inventory_collections_data [Hash] Hash used for ManagerRefresh::InventoryCollection initialize | ||
def add_inventory_collections(default, inventory_collections, inventory_collections_data = {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment about _data
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont really like the default
and how it just emmits hashes...
But ok for now and do some refactoring later
# | ||
# @param defaults [Array] Array of ManagerRefresh::InventoryCollectionDefault | ||
# @param inventory_collections_data [Hash] Hash used for ManagerRefresh::InventoryCollection initialize | ||
def add_remaining_inventory_collections(defaults, inventory_collections_data = {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an indicator, that the InventoryCollectionDefault
concept is somehow not fitting.
So leave it for now, but I have the feeling this will and should go away
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, so this helper is mainly for the Targeted refresh, where I define few ICs and want to be able to easily say "Rest of the ICs should come from a DB"
Renames in Persister according to review
Explicitly define a delete method instead of auto-magic, the default IC definitions have delete_method defined, if it differs from a default :destroy.
Checked commits Ladas/manageiq@28a74aa~...85ad5bf with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 from me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks really nice.
just a few nits - all of them can be ignored
@@ -135,13 +135,13 @@ def parse_targeted_inventory(ems, target, collector) | |||
_log.debug "#{log_header} Parsing inventory..." | |||
inventory_collections, = Benchmark.realtime_block(:parse_inventory) do | |||
provider_module = ManageIQ::Providers::Inflector.provider_module(ems.class).name | |||
inventory_target_class = "#{provider_module}::Inventory::Target::#{target.class.name.demodulize}".safe_constantize | |||
inventory_target = inventory_target_class.new(target) | |||
persister_class = "#{provider_module}::Inventory::Persister::#{target.class.name.demodulize}".safe_constantize |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you using strings/safe_constantize
to avoid class not found?
(basically asking will this work if you don't .name
, but just reference the class)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, and I'm chiming in, because the original code was mine, so I'm to blame 😉
So, if the class is not found, it would return nil
and nil.new
will blow up.
So we should assume the class is there, check if its not and raise an exception like you should really implement this
- so the dev knows what he's missing
attr_reader :manager, :target, :collections | ||
|
||
# @param manager [ManageIQ::Providers::BaseManager] A manager object | ||
# @param target [Object] A refresh Target object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you put an OR (|
) in there? knowing it is an ActiveRecord::Base
(or similar) seems to be helpful
collections[:inventory_groups] ||= ManagerRefresh::InventoryCollection.new( | ||
:model_class => ManageIQ::Providers::AutomationManager::InventoryRootGroup, | ||
:association => :inventory_root_groups, | ||
:parent => @root, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
really like how @root
(single refresh specific variable) was removed from the collection definition.
Would be nice if Persister
definition was reusable. (future thought)
Agree |
@@ -4,6 +4,7 @@ def vms(extra_attributes = {}) | |||
attributes = { | |||
:model_class => ::ManageIQ::Providers::CloudManager::Vm, | |||
:association => :vms, | |||
:delete_method => :disconnect_inv, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the explicit delete method 👍
This LGTM 👍 |
Enhanced inventory collector target and parser classes to align with the Amazon usecase.