-
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
Add TransformationMapping#validate_vms method #17177
Conversation
@miq-bot add_label enhancement, transformation |
Thanks @bzwei -- that's the information I was looking for! |
This is an initial PR that can support API development work. |
3333461
to
3436c6f
Compare
58d0036
to
dd2894f
Compare
|
Agreed... why CSV? if this is coming from an API, I would expect a proper JSON array of array. Even if we did use CSV, the model should only be coded against an array of arrays, IMO, and something else above the model should be translating a csv to an array of arrays. |
app/models/transformation_mapping.rb
Outdated
|
||
def select_vms | ||
# TBD | ||
end |
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 add a method if you aren't going to use it...just add it later when you need it.
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.
It is an sample for our team developer. It will be filled with logic very soon. It is urgently needed.
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 @Fryguy is saying anyone can add the ternary above when there is a usage for it.
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.
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.
@gmcculloug The follow up PR is coming today. Working on the test cases.
app/models/transformation_mapping.rb
Outdated
conditions = {:name => vm_name} | ||
|
||
# construct conditions or selections based on MIQ exported csv columns | ||
conditions[:uid_ems] = row['UID'] if row['UID'].present? |
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 feels bad to have the API use arbitrary case for keys. Just use lower case for everything, and, I would go farther to say that it should just use uid_ems as the key name to avoid confusion, but that could be discussed.
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.
All the keys are the headers from the csv, which can be an exported from manageiq, or directly created by user through an external system. All the headers exported from manageiq are capitalized. Examples are Name
, Provider
, Cluster
, IP Addresses
, Allocated Size
etc. All columns are optional. We will do our best to identify the VMs according to provided columns.
Is uid_ems
a good name for users who do not use manageiq exports?
My original thoughts is for the UI to read the csv file and simply convert to JSON without any modification, and pass to backend. Backend will select the columns of interest.
Do you think the UI should select columns of interest and convert the headers to low case? In the future if there is new column added, then both UI and backend need to make changes.
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 are "MIQ exported csv columns"? Do we generate this in reporting or something? If it's based on our data, why wouldn't we just use our id's?
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 existing miq csv export functionality. When you browse an inventory of VMs you have an option to download the VMs in a CSV file. It does not contain our Id's.
But this is only one way to provide the csv file for v2v migration use. User can choose to create their own csv file using whatever method they want.
app/models/transformation_mapping.rb
Outdated
# construct conditions or selections based on MIQ exported csv columns | ||
conditions[:uid_ems] = row['UID'] if row['UID'].present? | ||
vms = Vm.where(conditions) | ||
vms = vms.select { |vm| vm.host.name == row['Host'] } if row['Host'].present? |
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 could be just part of the query itself...
Vm.where(conditions).where(:host => {:name => row['Host']})
app/models/transformation_mapping.rb
Outdated
|
||
# construct conditions or selections based on MIQ exported csv columns | ||
conditions[:uid_ems] = row['UID'] if row['UID'].present? | ||
vms = Vm.where(conditions) |
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.
Instead of building up a conditions Hash, prefer building up queries.
query = Vm.where(:name => vm_name)
query = query.where(:uid_ems => row['UID']) if row['UID'].present?
query = query.where(:host => {:name => row['Host']}) if row['Host'].present?
vms = query.to_a
app/models/transformation_mapping.rb
Outdated
def describe_non_vm(vm_name) | ||
{ | ||
N_("Name") => vm_name, | ||
N_("Reason") => "VM does not exist" |
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 understand why we are translating keys of a Hash. Is this for presentation purposes? If so, then this doesn't belong here at all, as presentation logic does not belong in a model. Instead, the model should return a "normal" Hash, and something else can translate that for presentation purposes.
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.
@Fryguy This looks OK to me.
The N_
notation means that strings would be marked for translation, but the actual translation would happen on the client side.
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.
@bzwei Can you change the Reason line to this -
N_("Reason") => N_("VM does not exist")
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 would also expect the hash to look something like {:name => vm_name, :reason => "Some reason", ...}
and have the presenter handle translations.
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.
"Name" and "Reason" are presentation strings visible in the UI, yes.
But they are NOT translated in the model.
By specifying N_
we simply make sure that the i18n rake task will pick up those strings and put them in the gettext catalog, which will be then sent to the translators.
@Fryguy @bdunne This is a pioneer PR for other developers to take over. I here laid out the overall structure to handle both cases. spec tests to be added by following up PR soon with other enhancement. I have the variable name |
dd2894f
to
ea9e13d
Compare
@AparnaKarve Presentation details do not belong in the model at all is my point. Things like "Name" is a presentation details (regardless of the i18n aspects) |
app/models/transformation_mapping.rb
Outdated
query = Vm.where(:name => vm_name) | ||
query = query.where(:uid_ems => row['UID']) if row['UID'].present? | ||
query = query.where(:host => {:name => row['Host']}) if row['Host'].present? | ||
query = query.where(:ext_management_system => {:name => row['Provider']}) if row['Provider'].present? |
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 like that the incoming vm_list array of hashes has "human readable" strings (aka presentation strings). These should ideally be lower-cased strings or symbols and probably should align tightly to the column names. In fact, if the incoming vms_list was a hash where the column names were keys, that could be passed directly to the query. In other words, the 4 lines above are really a conversion from "csv -formatted" to "database-formatted", which IMO doesn't belong here...the csv -> hash conversion belongs with something like a class that deals with the CSV details itself.
app/models/transformation_mapping.rb
Outdated
"Allocated Size" => vm.allocated_disk_storage, | ||
"ID" => vm.id, | ||
"Reason" => reason | ||
} |
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.
My point was lost here in that these two methods are all presentation logic and belong outside of this model in something that deals with "csv" data. I still don't agree that CSV is needed at all as that is a terrible transfer medium, particular at the REST API level, where an API user expects JSON.
@Fryguy I thought this through, and for this particular case, we can keep the model free of all i18n aspects. EDIT: It's the context of where we are applying i18n matters. |
ea9e13d
to
a9b7b8a
Compare
a9b7b8a
to
d454361
Compare
@AparnaKarve It would be best if we setup some time next week to review. I beliee there are still concerns around the presentation details in the model as well as possible performance concerns. I think it would be best to try to address these when people are back in the office next week. |
@gmcculloug Sounds good. Thanks. |
app/models/transformation_mapping.rb
Outdated
end | ||
|
||
def describe_vm(vm, reason) | ||
# formate to be finalized |
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.
Typo "format"
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 line can be removed now.
app/models/transformation_mapping.rb
Outdated
vm_list.each do |row| | ||
vm_name = row['name'] | ||
|
||
if row['name'].blank? |
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.
Should this use the variable assigned above?
app/models/transformation_mapping.rb
Outdated
query = query.joins(:ext_management_system).where(:ext_management_systems => {:name => row['provider']}) if row['provider'].present? | ||
|
||
vms = query.to_a | ||
invalid_list << describe_non_vm(vm_name) if vms.empty? |
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.
Shouldn't this be part of the if
conditional below to avoid going into the else condition on line 64?
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.
vms
is empty. So line 64 will not loop.
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.
But why even enter the else
which is intended for the "array of vms" case?
964f4c0
to
f9993d3
Compare
978b97f
to
41b1e8f
Compare
@Fryguy @bzwei Had a meeting to discuss and determine how to move this forward. We agreed that both the query logic and the return structures need to be updated. The current changes, while not optimal, do allow the feature to work and be demonstrated which the refactoring work progresses. @Fryguy Can you confirm here that we are good to merge this now and will create followup PRs to address the issues we identified. |
59fd6a4
to
964f4c0
Compare
964f4c0
to
43563ba
Compare
Checked commits bzwei/manageiq@04887ae~...43563ba with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0 |
@gmcculloug This is fine, as long as we prioritize the follows for after the demo. |
Add TransformationMapping#validate_vms method (cherry picked from commit eede7da)
Gaprindashvili backport details:
|
Add
#validate_vms
method to support API/api/transformation_mappings/id
actionsearch_vms_and_validate
.If the action provides no csv content, the method should select all VMs that are qualified for migration based on the mapping.
If csv is provided in the POST body, the method should filter all selections and group them into
valid_vms
,invalid_vms
, andconflict_vms
.Selected attributes of each VM are included for displaying purpose.
id
is critical to be used by following up API call to create a transformation plan.