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

Add automate methods for VM import between providers #36

Merged
merged 1 commit into from
May 24, 2017

Conversation

matobet
Copy link
Contributor

@matobet matobet commented Feb 7, 2017

Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1404920

Added automate methods required to back the transform vm service dialog (ManageIQ/manageiq#13794 ManageIQ/manageiq-ui-classic#383) facilitating v2v conversion of VMs between two infra providers.

The dialog consists of 3 select boxes (target infra provider, cluster, storage domain) and a single checkbox that controls whether thin provisioning is enabled. To supply those select boxes we provided the list_infra_providers, list_clusters and list_storages methods respectively.

@matobet
Copy link
Contributor Author

matobet commented Feb 14, 2017

Depends on ManageIQ/manageiq#13916

@mkanoor
Copy link
Contributor

mkanoor commented Feb 14, 2017

@matobet
Could you also add a spec for the automate methods in this PR

For the newer methods we are following a module approach so that we can test them outside of the Automate Engine. A good example to follow would be a method and spec like

Method

https://github.com/ManageIQ/manageiq-content/blob/master/content/automate/ManageIQ/Service/Generic/StateMachines/GenericLifecycle.class/__methods__/check_completed.rb

Spec

https://github.com/ManageIQ/manageiq-content/blob/master/spec/content/automate/ManageIQ/Service/Generic/StateMachines/GenericLifecycle.class/__methods__/check_completed_spec.rb

@matobet
Copy link
Contributor Author

matobet commented Feb 15, 2017

@mkanoor Posted new (modularized) version of the scripts, can you please tell me if I'm on the right track?

:storage_id => storage_id,
:sparse => sparse
)
exit MIQ_OK
Copy link
Contributor

Choose a reason for hiding this comment

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

@matobet
We don't need the exit you can use @handle.root['ae_result'] = 'ok'

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done


provider.import_vm(
vm.id,
:name => name,
Copy link
Contributor

Choose a reason for hiding this comment

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

@matobet
Could we not use the local variables and directly use the attribute values from root

provider.import_vm(
@handle.root['vm'].id,
:name =>  @handle.root['dialog_name'],
:cluster_id => @handle.root['dialog_cluster'],
:storage_id => @handle.root['dialog_storage'],
:sparse => @handle.root['dialog_sparse'])

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

values_hash = {}
values_hash[''] = '-- select target infrastructure provider from list --'

managers = @handle.vmdb('ManageIQ_Providers_Redhat_InfraManager').all.select(&:validate_import_vm)
Copy link
Contributor Author

@matobet matobet Feb 16, 2017

Choose a reason for hiding this comment

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

@mkanoor When writing the specs for this script, how should I approach to mocking this call to vmdb(ManageIQ_Providers_Redhat_InfraManager)? I tried looking in other specs and found no example of this..

From what I understand the basic idea is to create the backing AR model, e.g.

let(:provider) { FactoryGirl.create(:ems_redhat) }

and then create the "wrapping"

let(:svc_model_provider) { MiqAeMethodService::MiqAeServiceManageIQ_Providers_Redhat_InfraManager.find(provider.id) }

but I'm not sure how to proceed in this case... (tests are currently failing with "Service Model not found".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok solved

end
end
list_values = {
'sort_by' => :value,
Copy link
Contributor

Choose a reason for hiding this comment

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

@matobet
Do you want the Dialogs to show items sorted by ID or by description/name?
If you want it to displayed sorted by name description the sort_by => 'description'

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

values_hash['!'] = '-- No clusters found --'
else
provider.ems_clusters.each do |cluster|
values_hash[cluster.id.to_s] = cluster.name
Copy link
Contributor

Choose a reason for hiding this comment

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

@matobet
could the key here be just id and not id string

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

if !provider_id.nil? && !provider_id.empty? && provider_id != '!'
provider = @handle.vmdb(:ext_management_system, provider_id)
if provider.nil?
values_hash['!'] = '-- No clusters found --'
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

values_hash = {}
values_hash[''] = '-- select cluster from list --'

provider_id = @handle.root['dialog_provider']
Copy link
Contributor

Choose a reason for hiding this comment

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

@matobet
Are you expecting the @handle.root['dialog_provider'] to be ! at some point as a default value

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mkanoor The '!' value of provider_id is being handled at line 17, if that is your question.


def main
values_hash = {}
values_hash[''] = '-- select storage from list --'
Copy link
Contributor

Choose a reason for hiding this comment

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

@matobet
I think the key here should be nil
value_hash[nil] = '-- select storage from list --'
On line 21 you are setting nil to None if no providers are found.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -0,0 +1,45 @@
module ManageIQ
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

@mkanoor mkanoor left a comment

Choose a reason for hiding this comment

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

we are requesting that every automate method have an associated spec. Please add the missing specs for the list methods

@matobet
Copy link
Contributor Author

matobet commented Feb 22, 2017

@mkanoor done, but now this patch also depends on the core patch adding required factories for the specs ManageIQ/manageiq#14017

@matobet matobet force-pushed the v2v-automate branch 2 times, most recently from 8dce9b5 to 1cacf6e Compare May 16, 2017 16:27
@matobet
Copy link
Contributor Author

matobet commented May 16, 2017

@tinaafitz pushed new version, added missing tests and hopefully addressed your comments :)

@@ -0,0 +1,53 @@
---
Copy link
Member

Choose a reason for hiding this comment

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

@matobet We're working on documenting guidelines for adding State Machines to the ManageIQ domain.

Can you modify your ImportVM State Machine as follows:

Minimum Requirements for ManageIQ domain State Machines:
(In addition to the specific processing states required by the new state machine)

  1. Minimum of 3 Pre states(pre1, pre2, pre3)

  2. Minimum of 3 Post states(post1, post2, post3)

  3. update_*_status method required for every states on_entry, on_exit, on_error
    a. * update request with enhanced message including
    updated_message = "[#{$evm.root['miq_server'].name}] "
    updated_message += "Step [#{$evm.root['ae_state']}] "
    updated_message += "Status [#{status}] "
    updated_message += "Message [#{prov.message}] "
    updated_message += "Current Retry Number [#{$evm.root['ae_state_retries']}]" if
    $evm.root['ae_result'] == 'retry'
    b. * set user_message in request:
    prov.miq_request.user_message = updated_message

c. * create notification and error log message on error
if $evm.root['ae_result'] == "error"
$evm.create_notification(:level => "error"
:message => "VM Provision Error: #{updated_message}")
$evm.log(:error, "VM Provision Error: #{updated_message}")
end

  1. Finished state
    Can use CommonMethods finished method:
    /System/CommonMethods/StateMachineMethods/your_instance_name_here
    (Add an instance to the /System/CommonMethods/StateMachineMethods class with your instance name. Can optionally modify task_finished method in that class for special processing)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tinaafitz ok, 1) and 2) seems pretty straightforward (I assume the states to be of type string)
but regarding 3) what is exactly necessary? add 3 methods for each state of the state machine (with the new pre and post that would total to 8*3=24 new methods)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tinaafitz and regarding 4) the state will be part of the ImportVm state machine (after the last "post" state)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tinaafitz Done, please review at your nearest convenience :)

@matobet matobet force-pushed the v2v-automate branch 3 times, most recently from a9202e8 to 1a9520f Compare May 19, 2017 16:27
Copy link
Member

@tinaafitz tinaafitz left a comment

Choose a reason for hiding this comment

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

@matobet - Great job on all of your changes!
I ran all of the spec tests and they look good.
I made just a few comments and I'm finished with the review. The next step is I'll ask @mkanoor for a final review.
Could you provide a brief explanation of setup/prerequisites/use cases for documentation purposes?

let(:miq_server) { EvmSpecHelper.local_miq_server }
let(:ems) { FactoryGirl.create(:ems_redhat) }
let(:vm) { FactoryGirl.create(:vm_redhat) }
let(:miq_event) { FactoryGirl.create(:miq_event, :event_type => event_type) }
Copy link
Member

Choose a reason for hiding this comment

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

@matobet miq_event is not needed 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.

done

end

def main
options = {
Copy link
Member

Choose a reason for hiding this comment

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

@matobet - Could you add basic validation that the required arguments exist before calling execute to create the automation request?

Here's a sample basic validation method:
def validate_root_args(arg_names)
arg_names.each do |name|
unless $evm.root[name].present?
msg = "Error, required root attribute: #{name} not found"
$evm.log(:error, msg)
raise msg
end
end
end

and you can call it prior to calling execute....

validate_root_args(%w(vm dialog_name dialog_provider dialog_cluster dialog_sparse))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done


def main
provider = @handle.vmdb(:ext_management_system, @handle.root['provider_id'])
@handle.log(:info, 'Submitting Import')
Copy link
Member

Choose a reason for hiding this comment

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

@matobet - Could you add basic validation that the required arguments exist before calling submit_import_vm?

Here's a sample basic validation method:
def validate_root_args(arg_names)
arg_names.each do |name|
unless $evm.root[name].present?
msg = "Error, required root attribute: #{name} not found"
$evm.log(:error, msg)
raise msg
end
end
end

and you can call it prior to calling execute....

validate_root_args(%w(vm name cluster_id storage_id sparse))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@matobet
Copy link
Contributor Author

matobet commented May 23, 2017

Hi @tinaafitz thank you for the review, I addressed all your comments but I'm not sure what exactly do you mean by setup/prerequisites/use cases for documentation purposes?

@tinaafitz
Copy link
Member

@matobet Thanks for making the changes. I'll ask @mkanoor to review.
You probably already have all of the necessary documentation information in your PRs.
The purpose is to answer the question of how do I use this feature? Although I've reviewed your PR, I wouldn't know how best to guide someone who wanted to use this new feature.

I think the information is all here, maybe if you could provide a brief explanation to a new user wanting to use v2.
https://docs.google.com/document/d/1TnAjYJd041vCWu71ks4oxT_jjSrlDE2nZWLBXK4ZKkg/edit
https://trello.com/c/uh3V62OZ/11-v2v-in-miq

@tinaafitz
Copy link
Member

@mkanoor @matobet has made all of the requested changes. Please review.

@mkanoor
Copy link
Contributor

mkanoor commented May 23, 2017

@matobet Can you fix the rubocop warning, we can use a next if the variable is present else raise an error

@mkanoor
Copy link
Contributor

mkanoor commented May 23, 2017

@matobet

              def validate_root_args(arg_names)
                arg_names.each do |name|
                  next if @handle.root[name].present?
                  raise "Error, required root attribute: #{name} not found"
                 end
              end

@matobet
Copy link
Contributor Author

matobet commented May 23, 2017

@mkanoor done

@miq-bot
Copy link
Member

miq-bot commented May 23, 2017

Checked commit matobet@62030d8 with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0
15 files checked, 0 offenses detected
Everything looks fine. 🍰

@matobet
Copy link
Contributor Author

matobet commented May 23, 2017

@tinaafitz as per our discussion, posting here short feature description:

Feature Overview

  • Allow migration of user workloads (VMs) from VMware infra provider to RHV provider
  • So far bulk operations not supported, need to individual VMs one-by-one
  • User chooses target (RHV) provider, cluster and storage domain
  • So far only the Vmware -> RHV is direction is supported (no other permutations of source & destination)

REST

Added a new action to the providers REST resource that allows for importing vms.
POST /api/providers/:id

{
  "action" : "import_vm", 
  "resource" : {
      "source": { "href": "http://localhost:3000/api/vms/:source_vm_id" },
      "target": {
          "name": "<name of newly created VM in RHEV>",
          "data_store": { "href": "http://localhost:3000/api/:target_data_store_id" },
          "cluster": { "href": "http://localhost:3000/api/:target_cluster_id" },
          "sparse": "[true|false]"
      }
  }
}

For now only the combination of a Vmware source VM and a RHEV as the target provider is supported.

UI

  • New button in the “vm detail” (“Transform this VM to RHV”)
    transform-vm-to-rhv-button

  • It should be visible only for VMware VMs

  • It should be enabled (not greyed out) only when there exists a suitable target provider in the system (in this case RHV infra provider of version 4.0+)

  • Spawns dialog with the following options
    transform-vm-dialog_

    • Name
    • Cluster
    • Storage domain
    • Thin provisioning (yes/no checkbox)
      For the created VM.
  • After submission the status and progress of the operation should be tracked along with other automate requests.

@mkanoor
Copy link
Contributor

mkanoor commented May 23, 2017

@matobet Looks good.
👍

@gmcculloug gmcculloug merged commit bd5bb97 into ManageIQ:master May 24, 2017
@gmcculloug gmcculloug added this to the Sprint 62 Ending Jun 5, 2017 milestone May 24, 2017
simaishi pushed a commit that referenced this pull request Jun 9, 2017
Add automate methods for VM import between providers
(cherry picked from commit bd5bb97)

https://bugzilla.redhat.com/show_bug.cgi?id=1459996
@simaishi
Copy link
Contributor

simaishi commented Jun 9, 2017

Fine backport details:

$ git log -1
commit 868138f7b46eb73d639d8c8bed337cea78da34c7
Author: Greg McCullough <gmccullo@redhat.com>
Date:   Wed May 24 08:28:35 2017 -0400

    Merge pull request #36 from matobet/v2v-automate
    
    Add automate methods for VM import between providers
    (cherry picked from commit bd5bb97383ea203cc2bde9d740a09624a08e01f2)
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1459996

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.

7 participants