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

Enhanced inventory collector target and parser classes #13907

Conversation

Ladas
Copy link
Contributor

@Ladas Ladas commented Feb 14, 2017

Enhanced inventory collector target and parser classes to align with the Amazon usecase.

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
Copy link
Member

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?

Copy link
Contributor Author

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)
Copy link
Member

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
@djberg96
Copy link
Contributor

@Ladas Will this require any changes to the external provider repos?

Rename Target to Persister under Inventory
@Ladas
Copy link
Contributor Author

Ladas commented Feb 14, 2017

@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.
Copy link
Member

@durandom durandom left a 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)
Copy link
Member

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 []

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, 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
Copy link
Member

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.

Copy link
Contributor Author

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

Copy link
Member

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

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, 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)
Copy link
Member

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
Copy link
Member

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

Copy link
Contributor Author

@Ladas Ladas Feb 15, 2017

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]
Copy link
Member

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.

Copy link
Contributor Author

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
Copy link
Member

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.

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, 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 = {})
Copy link
Member

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

Copy link
Member

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 = {})
Copy link
Member

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

Copy link
Contributor Author

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.
@Ladas
Copy link
Contributor Author

Ladas commented Feb 15, 2017

@miq-bot assign @agrare

@miq-bot miq-bot assigned agrare and unassigned blomquisg Feb 15, 2017
@miq-bot
Copy link
Member

miq-bot commented Feb 15, 2017

Checked commits Ladas/manageiq@28a74aa~...85ad5bf with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0
9 files checked, 0 offenses detected
Everything looks good. 🍰

Copy link
Member

@durandom durandom left a comment

Choose a reason for hiding this comment

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

👍 from me

Copy link
Member

@kbrock kbrock left a 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
Copy link
Member

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)?

Copy link
Member

@durandom durandom Feb 16, 2017

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
Copy link
Member

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,
Copy link
Member

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)

@agrare
Copy link
Member

agrare commented Feb 16, 2017

though this name is still a bit strange, but 🤷‍♂️

Agree Inventory::Persister is strange but its better than Target, we can revisit this if we can think of a better name :)

@@ -4,6 +4,7 @@ def vms(extra_attributes = {})
attributes = {
:model_class => ::ManageIQ::Providers::CloudManager::Vm,
:association => :vms,
:delete_method => :disconnect_inv,
Copy link
Member

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 👍

@agrare
Copy link
Member

agrare commented Feb 16, 2017

This LGTM 👍

@agrare agrare merged commit 063b42d into ManageIQ:master Feb 16, 2017
@agrare agrare added the euwe/no label Feb 16, 2017
@agrare agrare added this to the Sprint 55 Ending Feb 27, 2017 milestone Feb 16, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants